Let's play 般若心経

研究日記です。

時間がない

8/27 CPU100度いって落ちるから掃除した

コントローラ完成

これを押し込んで

できました。採寸が大変でした。センサモジュールも一つ一つサイズが違います。

今まで印刷しては調整してきたゴミがこちらです。

プログラムを書こう

センサ4つとボタン2つとスティック2つの値をキャラクタリスティックで送ります。

クリックでコードを表示
#include <ArduinoBLE.h>
#include "DFRobot_VEML7700.h"
#include <BH1745NUC.h>
#include <Adafruit_VL53L0X.h>

// プロトタイプ宣言
String scanI2CAddresses(); 
void readAndSendButtonState();
void sendColorValue();
void readAndSendStickValues();
void sendLuxValue();
void sendDistanceValue();
void sendTempHumValues();


int stick1X = A0;
int stick1Y = A1;
int stick2X = A2;
int stick2Y = A3;

DFRobot_VEML7700 als;
BH1745NUC bh1745nuc(BH1745NUC_DEVICE_ADDRESS_39);
Adafruit_VL53L0X lox = Adafruit_VL53L0X();

BLEService sensorService("1221");
BLEStringCharacteristic luxCharacteristic("2A37", BLERead | BLENotify, 20);
BLEStringCharacteristic colorCharacteristic("2A38", BLERead | BLENotify, 20);
BLEStringCharacteristic buttonCharacteristic("2A39", BLERead | BLENotify, 5);
BLEStringCharacteristic stickCharacteristic("2A40", BLERead | BLENotify, 20);
BLEStringCharacteristic i2cAddressCharacteristic("2A41", BLERead | BLENotify, 10);
BLEStringCharacteristic distanceCharacteristic("2A42", BLERead | BLENotify, 10);
BLEStringCharacteristic tempHumCharacteristic("2A43", BLERead | BLENotify, 20);


void setup() {
  Wire.begin(); 
  Serial.begin(9600);
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }

  als.begin();
  bh1745nuc.init();
  // 距離センサの初期化
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }

  BLE.setLocalName("SensorBLE");
  BLE.setAdvertisedService(sensorService);

  sensorService.addCharacteristic(luxCharacteristic);
  sensorService.addCharacteristic(colorCharacteristic);
  sensorService.addCharacteristic(i2cAddressCharacteristic);
  sensorService.addCharacteristic(buttonCharacteristic);
  sensorService.addCharacteristic(stickCharacteristic);
  sensorService.addCharacteristic(distanceCharacteristic);
  sensorService.addCharacteristic(tempHumCharacteristic);

  BLE.addService(sensorService);

  BLE.advertise();
  Serial.println("Bluetooth device active, waiting for connections...");
}

void loop() {
  BLEDevice central = BLE.central();

  if (central) {
    Serial.print("Connected to central: ");
    Serial.println(central.address());

    // Scan I2C addresses and update the new characteristic
    String i2cAddresses = scanI2CAddresses();
    i2cAddressCharacteristic.writeValue(i2cAddresses.c_str());

    while (central.connected()) {
      if (i2cAddresses.indexOf("16") != -1) { // if VEML7700 is connected
        sendLuxValue();
      }
      if (i2cAddresses.indexOf("57") != -1) { // if BH1745NUC is connected
        sendColorValue();
      }
      if (i2cAddresses.indexOf("45") != -1) { // if SHT35 is connected
        sendTempHumValues();
      }
      if (i2cAddresses.indexOf("29") != -1) { // if VL53L0X is connected
       sendDistanceValue();
      }
      readAndSendButtonState();//ボタン
      readAndSendStickValues();//アナログスティック

      if (i2cAddresses.indexOf("45") != -1) { // 温湿度センサが接続されている場合
       delay((int)((1.0/30)*1000 - 15));  // 短いディレイ
      } else {
       delay((int)(1.0/30*1000));  // 通常のディレイ
      }
    }

    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
  }
}

// 前回のボタンの状態を保存するための変数
bool previousButtonState[4] = {false, false, false, false};

void readAndSendButtonState() {
  String buttonsPressed = ""; // 押されたボタンの番号を格納する文字列

  for (int i = 0; i < 4; i++) {
    int pin = 2 + i;//D2+i
    bool currentState = digitalRead(pin) == HIGH;

    // ボタンが押された瞬間のみを検出
    if (currentState && !previousButtonState[i]) {
      buttonsPressed += String(pin);
    }

    // 現在のボタンの状態を保存
    previousButtonState[i] = currentState;
  }

  if (buttonsPressed != "") { // 1つ以上のボタンが押された場合のみ送信
    buttonCharacteristic.writeValue(buttonsPressed.c_str());
  }
}

void sendColorValue() {
  unsigned short rgbc[4];
  if (bh1745nuc.get_val(rgbc) == 0) {
    float maxVal = max(max(rgbc[0], rgbc[1]), rgbc[2]);
    float scale = 1.0 / maxVal;

    // RGB値を0~1の範囲にスケーリング
    float R = rgbc[0] * scale;
    float G = rgbc[1] * scale;
    float B = rgbc[2] * scale;

    // 小数点以下3桁にフォーマット
    char colorStr[50];
    snprintf(colorStr, sizeof(colorStr), "%.3f,%.3f,%.3f", R, G, B);
    Serial.println(colorStr);

    colorCharacteristic.writeValue(colorStr);
  }
}

void readAndSendStickValues() {
  int stick1X = analogRead(A0);
  int stick1Y = analogRead(A1);
  int stick2X = analogRead(A2);
  int stick2Y = analogRead(A3);
  char stickValues[20];
  snprintf(stickValues, sizeof(stickValues), "%d,%d,%d,%d", stick1X, stick1Y, stick2X, stick2Y);
  stickCharacteristic.writeValue(stickValues);
}

void sendLuxValue() {
  float lux;
  als.getALSLux(lux);
  String luxStr = "VEML7700:" + String(lux) + " lx";
  luxCharacteristic.writeValue(luxStr.c_str());
}

String scanI2CAddresses() {
  String detectedAddresses = "";
  for (int address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    byte error = Wire.endTransmission();
    if (error == 0) {
      detectedAddresses += String(address, HEX) + ",";
    }
  }
  return detectedAddresses;
}

void sendDistanceValue() {
  VL53L0X_RangingMeasurementData_t measure;
  lox.rangingTest(&measure, false);
  if (measure.RangeStatus != 4) {
    distanceCharacteristic.writeValue(String(measure.RangeMilliMeter).c_str());
  } else {
    distanceCharacteristic.writeValue("Out of range");
  }
}

void sendTempHumValues() {
  // Send measure command
  Wire.beginTransmission(0x45);
  Wire.write(0x24);
  Wire.write(0x0B);
  Wire.endTransmission();

  delay(15); // Wait for measurement to complete (max 15ms)

  // Request 6 bytes of data
  Wire.requestFrom(0x45, 6);

  // Read data
  byte data[6];
  for (int i = 0; i < 6; i++) {
    data[i] = Wire.read();
  }

  // Convert to actual temperature and humidity
  unsigned int rawTemp = (data[0] << 8) | data[1];
  unsigned int rawHum = (data[3] << 8) | data[4];

  float temp = -45 + 175 * ((float)rawTemp / 65535);
  float hum = 100 * ((float)rawHum / 65535);

  String tempHumStr = String(temp, 2) + "°C," + String(hum, 2) + "%";
  tempHumCharacteristic.writeValue(tempHumStr.c_str());
}

 

これをUEで取得してキャラクターを動かしてギミック作ってUIとエフェクトとサウンド頑張って動画撮って編集して終わりです。がんばろう