2016年12月18日

距離センサVL53L0X動作テスト

今回は距離センサVL53L0Xを試食してみたので、
ご紹介します。

先日、素子単体が秋月でも発売されたようですが、
電圧が標準2.8Vで素子が小さいため、
変換基板がないと少し厳しいかもしれません。


IMG_3732_.jpg



環境はこれまで同様、
・STM32F303K8
 +SW4STM32(System Workbench for STM32)
 +STM32CubeMX(F3_1.6.0)
です。


距離センサVL53L0XはST製の評価用基板セット(2個入り)を使用しました。

STから提供されているライブラリは
キャリブレーションやジェスチャなどコードが膨大なため、
動作テストに必要なコードのみ引き出したコードを使用してテストしてみました。
正規のキャリブレーションを行っていないため、
動作の保証はできません。
あくまでテスト確認用です。



コード例は下記の通りです。

#include "stm32f3xx_hal.h"

#define VL53L0X_Address    0x52
#define VL53L0X_REG_IDENTIFICATION_MODEL_ID         0xc0
#define VL53L0X_REG_IDENTIFICATION_REVISION_ID      0xc2
#define VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD   0x50
#define VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD 0x70
#define VL53L0X_REG_SYSRANGE_START                  0x00
#define VL53L0X_REG_RESULT_INTERRUPT_STATUS         0x13
#define VL53L0X_REG_RESULT_RANGE_STATUS             0x14



uint8_t buf[16];


uint16_t VL53L0X_decode_vcsel_period(short vcsel_period_reg) {
  uint16_t vcsel_period_pclks = (vcsel_period_reg + 1) << 1;
  return vcsel_period_pclks;
}

uint16_t convuint16(int lsb, int msb) {
    return ((msb & 0xFF) << 8) | (lsb & 0xFF);
}

void write_byte_data_at(uint8_t reg, uint8_t data) {
     uint8_t val[1];
     val[0]=data;
     HAL_I2C_Mem_Write(&hi2c1, VL53L0X_Address, reg, I2C_MEMADD_SIZE_8BIT, val, 1, 1000);
}

uint8_t read_byte_data_at(uint8_t reg) {
    uint8_t value;
    HAL_I2C_Mem_Read(&hi2c1, VL53L0X_Address, reg, I2C_MEMADD_SIZE_8BIT, &value, 1, 1000);
  return value;
}

void read_block_data_at(uint8_t reg, int sz) {
    HAL_I2C_Mem_Read(&hi2c1, VL53L0X_Address, reg, I2C_MEMADD_SIZE_8BIT, buf, sz, 1000);
}



void Vl53L0X_Test(void){

     uint8_t val1 ;
   //CHK Param
      val1 = read_byte_data_at(VL53L0X_REG_IDENTIFICATION_REVISION_ID);
      printf("Revision ID: %d, ",val1);

      val1 = read_byte_data_at(VL53L0X_REG_IDENTIFICATION_MODEL_ID);
      printf("Device ID:  %d \n",val1);

      val1 = read_byte_data_at(VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD);
      printf("PRE_RANGE_CONFIG_VCSEL_PERIOD: %d \n",val1);
      printf(" decode:   %d \n",VL53L0X_decode_vcsel_period(val1));

      val1 = read_byte_data_at(VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD);
      printf("FINAL_RANGE_CONFIG_VCSEL_PERIOD: %d \n",val1);
      printf(" decode:   %d \n",VL53L0X_decode_vcsel_period(val1));

   //Init Start
      write_byte_data_at(VL53L0X_REG_SYSRANGE_START, 0x01);

      uint8_t val = 0;
      int cnt = 0;
      while (cnt < 100) { // 1 second waiting time max
          HAL_Delay(10);
        val = read_byte_data_at(VL53L0X_REG_RESULT_RANGE_STATUS);
        if (val & 0x01) break;
        cnt++;
      }
      if (val & 0x01) printf("Ready!! \n"); else printf("Not Ready!!");

      read_block_data_at(0x14, 12);
      uint16_t acnt = convuint16(buf[7], buf[6]);
      uint16_t scnt = convuint16(buf[9], buf[8]);
      uint16_t dist = convuint16(buf[11], buf[10]);
      uint8_t DeviceRangeStatusInternal = ((buf[0] & 0x78) >> 3);

      //printf("ambient count: %d, signal count: %d, distance: %d, status: %d  \n",
      //        acnt,scnt,dist,DeviceRangeStatusInternal);
   printf("RES: %d mm  \n",dist);

}

uint8_t VL53L0X_Address_Test(void){

     uint8_t tmp[2];
     HAL_I2C_Mem_Read(&hi2c1, VL53L0X_Address, 0xC1, I2C_MEMADD_SIZE_8BIT, tmp, 1, 100);
   
     if(tmp[0]==0xAA){
         printf("VL53L0X is Found! \n");
         return true;
     }
     else{
         printf("VL53L0X is NOT Found! ERROR! \n");
         return false;
     }

}


実際にVl53L0X_Testを実行して距離を計測してみました。



vl53.png



最初、内部メモリ内のデータに異常があったようで
SPAD初期化に失敗するという状況でした。
最低限の初期化のみを実行すると正常そうな値を返すようになりました。

STのサイトからダウンロードしたライブラリやAPIはあまりにも
膨大で複雑な処理をしているため、
遊びの距離センサとして使うには少し敷居が高いかもしれません。




posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 電子部品 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック