Raspberry Pi Zewo Wで距離センサーVL53L0Xのi2cアドレスを変更して複数同時に動作させてみた

# 概要
距離センサーVL53L0Xのi2cアドレスを変更して複数動作させる方法です
VL53L0Xは起動時のi2cアドレスは0x29なので複数接続すると全て同じアドレスになってしまい制御できなくなります
制御するにはXSHUTを使用して、一つづつi2cアドレスを変更する手順が必要となります
手順の概要は以下の通りです

1. 全てのVL53L0XのXSHUTをLOWにする
2. 1つ目のVL53L0XのXSHUTをHIGHにする
3. このときi2cアドレスは初期値の0x29ですが、そのまま初期化する
4. 変更したいi2cアドレスに設定する
5. 再度初期化する
6. 2〜5の手順を全てのVL53L0Xに対して実施する（2の１つ目を２つ目、３つ目と読み替えてください）
7. i2cアドレス変更完了






# 動作テスト

## 構成図
今回はVL53L0Xを4つ動作させます
i2cアドレスとGPIO番号は以下の値にしましたが、
i2cアドレスは0x29以外と使用していないアドレスであればOKです
GPIO番号は任意でOKです

|  VL53L0X  |  i2cアドレス  | GPIO |
| ---- | ---- | ---- |
|  1  |  0x2a  | 26|
|  2  |  0x2b  | 19|
|  3  |  0x2c  | 20|
|  4  |  0x2d  | 16|



![20200620.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146154/bf1409ce-8665-1fba-d302-1daaefc4f854.png)


## 実際の物

![20200619_205954.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146154/f87ccc6e-c8dc-93d3-c0e7-63a42bcf9dbf.jpeg)




## 動作結果
1000と表示されている箇所は1000mm以上になります。
VL53L0XはDefault modeで最大測定値は1200mmなので誤値を出力しないために出力制限をしています
![スクリーンショット 2020-06-20 0.05.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146154/75ebb9de-d365-80e0-a7eb-459bb000c9a4.png)


# コード

全体は[github](https://github.com/shigeru-yokochi/drone/tree/VL53L0X_multi_test)にあります。i2cアドレス変更箇所と測定値獲得の箇所は以下になります

```c:vl53l0x.c
//VL53L0X_init()の初期化箇所

    //XSHUTをHIGHにする
    digitalWrite(xshut_gpio,HIGH);
    usleep(100000); //100ms
    //defaultの0x29で初期化
    m_pMyDevice[device_id]->fd = VL53L0X_i2c_init("/dev/i2c-1", 0x29);  
    //変更するi2cアドレス指定
    m_pMyDevice[device_id]->I2cDevAddr      = i2c_address;
    VL53L0X_SetDeviceAddress(m_pMyDevice[device_id],	m_pMyDevice[device_id]->I2cDevAddr<<1);
　　//変更したi2cアドレスで再度初期化
    m_pMyDevice[device_id]->fd = VL53L0X_i2c_init("/dev/i2c-1", m_pMyDevice[device_id]->I2cDevAddr);
```

```c:main.c
//I2c_device_init()内の初期化箇所

	//全てのL53L0Xのxshutをlowにする
   	pinMode(VL53L0X_XSHUT_1_GPIO,OUTPUT);
   	pinMode(VL53L0X_XSHUT_2_GPIO,OUTPUT);
   	pinMode(VL53L0X_XSHUT_3_GPIO,OUTPUT);
   	pinMode(VL53L0X_XSHUT_4_GPIO,OUTPUT);
   	pinMode(VL53L0X_XSHUT_5_GPIO,OUTPUT);
    digitalWrite(VL53L0X_XSHUT_1_GPIO,LOW);
    digitalWrite(VL53L0X_XSHUT_2_GPIO,LOW);
    digitalWrite(VL53L0X_XSHUT_3_GPIO,LOW);
    digitalWrite(VL53L0X_XSHUT_4_GPIO,LOW);
    digitalWrite(VL53L0X_XSHUT_5_GPIO,LOW);
 
	if(VL53L0X_init(VL53L0X_XSHUT_1_GPIO,0x2a,0) != VL53L0X_ERROR_NONE){	//距離センサ 1
		printf("*** VL53L0X_init()err\n");
		return -1;
	}
	if(VL53L0X_init(VL53L0X_XSHUT_2_GPIO,0x2b,1) != VL53L0X_ERROR_NONE){	//距離センサ 2
		printf("*** VL53L0X_init()err\n");
		return -1;
	}
	if(VL53L0X_init(VL53L0X_XSHUT_3_GPIO,0x2c,2) != VL53L0X_ERROR_NONE){	//距離センサ 3
		printf("*** VL53L0X_init()err\n");
		return -1;
	}
	if(VL53L0X_init(VL53L0X_XSHUT_4_GPIO,0x2d,3) != VL53L0X_ERROR_NONE){	//距離センサ 4
		printf("*** VL53L0X_init()err\n");
		return -1;
	}


```

```c:main.c
//VL53L0X測定値獲得と表示箇所

    for(;;){
        if(VL53L0X_GetMeasurements(&VL53L0X_Measurement[0],0) != VL53L0X_ERROR_NONE)break;	//VL53L0X測定値獲得 1つ目	 
        if(VL53L0X_GetMeasurements(&VL53L0X_Measurement[1],1) != VL53L0X_ERROR_NONE)break;	//VL53L0X測定値獲得 2つ目
        if(VL53L0X_GetMeasurements(&VL53L0X_Measurement[2],2) != VL53L0X_ERROR_NONE)break;	//VL53L0X測定値獲得 3つ目
        if(VL53L0X_GetMeasurements(&VL53L0X_Measurement[3],3) != VL53L0X_ERROR_NONE)break;	//VL53L0X測定値獲得 4つ目

        printf("time %0.2lf VL53L0X(1..4):%4d %4d %4d %4d\n", dfFlightTime, 
				VL53L0X_Measurement[0],
				VL53L0X_Measurement[1],
				VL53L0X_Measurement[2],
				VL53L0X_Measurement[3]);
    }
```