EPS-WROOM32で測距センサVL53L0Xを複数接続して使ってみた

2018.10.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、さかじです。前回の投稿で少し触れましたが、横田deGoシーズン2で使用した棚に対して手が入ったかどうかを監視するVL53L0Xは4つ使用しています。どのように接続して問題点、対応をまとめました。

EPS-WROOM32で測距センサVL53L0Xを使ってみた

回路図

CADを使えないので手書きです。

XHコネクタ側のピン説明

1 : VCC
2 : GND
3 : SDA
4 : SCL
5 : XSHUT

問題点

  • 使用するVL53L0Xは4つ
  • 接続I2Cのみ
  • I2Cでは同一バスに同じアドレスのデバイスが存在してはいけない

対応

VL53L0Xを一つづつ起動して、アドレスを変更していきます。XSHUT端子をLOWにすることでVL53L0Xをオフにすることができます。

起動時、各VL53L0XのXSHUTをLOWに変更します

    // センサ0
    pinMode(23, OUTPUT);
    digitalWrite(23, LOW);
    // センサ1
    pinMode(19, OUTPUT);
    digitalWrite(19, LOW);
    // センサ2
    pinMode(18, OUTPUT);
    digitalWrite(18, LOW);
    // センサ3
    pinMode(17, OUTPUT);
    digitalWrite(17, LOW);

XSHUTに接続されている端子をINPUTにしセンサ0のアドレスを任意の値に変更します この時VL53L0Xの初期アドレスと違う値にします。
初期アドレスは0b0101001

#define ADDRESS_DEFAULT 0b0101001 // 0x29
VL53L0X gSensor; // 使用するセンサークラス
void setup() {
    // センサ0 初期化
    pinMode(23, INPUT);
    gSensor.init();
    gSensor.setTimeout(1000);
    gSensor.startContinuous(10);
    gSensor.setAddress(ADDRESS_DEFAULT + 2);
}

同様にセンサ1〜3もアドレスを変更します。処理をまとめて以下のように作成しました。

#define SENSOR_NUM  4 // 使用するセンサーの数
#define ADDRESS_DEFAULT 0b0101001 // 0x29
#define ADDRESS_00 (ADDRESS_DEFAULT + 2)
/**
 * 各センサのXSHUTへ接続されているGPIOの配列
 */
const int GPIO_MASK_ARRAY[SENSOR_NUM] = {23, 19, 18, 17};
VL53L0X gSensor[SENSOR_NUM]; // 使用するセンサークラス配列

void setup() {
  // まず全てのGPIOをLOW
  for (int i = 0; i < SENSOR_NUM; i++)
  {
    pinMode(GPIO_MASK_ARRAY[i], OUTPUT);
    digitalWrite(GPIO_MASK_ARRAY[i], LOW);
  }

  for (int i = 0; i < SENSOR_NUM; i++) {
    // センサを初期化
    pinMode(GPIO_MASK_ARRAY[i], INPUT);
    if (gSensor[i].init() == true)
    {
      gSensor[i].setTimeout(1000);
      gSensor[i].startContinuous(10);
      int address = ADDRESS_00 + (i * 2);
      gSensor[i].setAddress(address);
    }
    else
    {
      Serial.print("Sensor ");
      Serial.print(i);
      Serial.println(" error");
    }
  }

これで4つのVL53L0Xにアクセスできるようになりました。

void loop()
{
  for (int i = 0; i < SENSOR_NUM; i++) {
    Serial.print(gSensor[i].readRangeSingleMillimeters());
    if (gSensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

    Serial.println();
    delay(1000);
  }
}

最後に

I2Cは同一アドレスが存在できないことで、今回のようなアドレスを変更できる機能、ハードウェアで変更する機能など備えているICもあります。特にメモリ関係は複数接続する可能性があるためアドレス変更の機能があるものが多いです。またRTCなど複数接続できないものはアドレスを変更できる機能がない場合もあります。複数使用したくてアドレスが変更できない場合にはI2Cのバスを変更する、SPIなど別の方式を検討するなどが良いでしょう。