今回は秋月のレーザー測距センサモジュール(ToF)に挑戦です。
このモジュールには STマイクロエレクトロニクス社の VL53L0X
(Time-of-Flight ranging sensor)が使われています。
こんな小さなチップで光が1mm進むレベルの時間が測れるなんて;;
ほんと凄い時代です。
商品はこれ
端子接続
端子接続(Qube 正面コネクタ)
Sensor | QubeIO | QubeIO | Sensor |
---|---|---|---|
3:SDA | IO 7 SDA | 3V3 | 1:+V |
- | IO15 | IO21 | - |
- | IO20 | IO 8 | - |
2:GND | GND | IO 6 SCL | 4:SCL |
センサの 5:xshut、6:gpio1 は接続しませんでした。
奮闘記08 の液晶モジュールも同じI2Cバス上にいるのでこのプルアップ抵抗も生きています。
コード
VL53L0Xの制御コードを一から作るスキルはないので。
micropython向けに書かれたこのモジュールを使わせて頂きました。
上記VL53L0X.pyをMaixPy IDEのツール→ transfer file to boad を使ってQUBEへ予め転送しておきます。
そして本体画面と液晶の両方に距離を表示させるバージョンがこれ。
sample1_VL53L0X.py
from machine import I2C
import utime,lcd,image,sensor
from VL53L0X import VL53L0X
def putstr(string):
BUFF = bytearray([0x40]) #Co=0,RS=1 Data
for char in string:
BUFF += char
print(BUFF)
i2c.writeto(DEFAULT_I2C_ADDR,BUFF)
def putcmd(command):
BUFF = bytearray([0x00,command]) #Co=0,RS=0 Control byte
print(BUFF)
i2c.writeto(DEFAULT_I2C_ADDR,BUFF)
def custom_char(location,charmap):
#"""Write a character to one of the 8 CGRAM locations, available
#as chr(0) through chr(7).
location &= 0x07
BUFF = bytearray([0x00,(0x40|(location << 3))])
i2c.writeto(DEFAULT_I2C_ADDR,BUFF)
utime.sleep_ms(50)
BUFF = chr(0x40) #Co=0,RS=1 Data
for i in range(8):
BUFF += chr(charmap[i])
i2c.writeto(DEFAULT_I2C_ADDR,BUFF)
DEFAULT_I2C_ADDR = 0x3E
print(DEFAULT_I2C_ADDR)
i2c = I2C(I2C.I2C3, freq=300*1000, sda=7, scl=6) # cube
putcmd(0x38)#ファンクションリセット
utime.sleep_ms(5)
putcmd(0x39)#ファンクションセット
utime.sleep_ms(5)
putcmd(0x14)#発信周波数
utime.sleep_ms(5)
#液晶のコントラスト
putcmd(0x70|0x03)#コントラスト下位4ビット デフォルト0x73
utime.sleep_ms(5)
putcmd(0x54|0x02)#コントラスト上位2ビット デフォルト0x02
utime.sleep_ms(1)
putcmd(0x6C)
utime.sleep_ms(300)
putcmd(0x38)#ファンクションリセット
utime.sleep_ms(5)
putcmd(0x01)
utime.sleep_ms(1)
putcmd(0x0C)
utime.sleep_ms(1)
#オリジナルキャラクタの定義
happy = bytearray([0x00,0x0A,0x00,0x04,0x00,0x11,0x0E,0x00])
bell = bytearray([0x04,0x0e,0x0e,0x0e,0x1f,0x00,0x04,0x00])
custom_char(0x0,happy)
custom_char(0x1,bell)
sensor.reset(freq=22000000, dual_buff=False)
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) # 320x240
img = sensor.snapshot()
lcd.init(type=2, invert=True) # cube ips
lcd.rotation(2)
lcd.clear(36, 36, 100)
#color: The color initialized by LCD, which can be a 16-bit RGB565 color value, such as 0xFFFF
#or a tuple of RGB888, such as (236, 36, 36)
vl=VL53L0X(i2c)
vl.init()
while(True):
Lengh = vl.read()
print(Lengh)
putcmd(0x80|0x40)
putstr(str('{:2d}'.format(Lengh))+' mm ')
img = sensor.snapshot()
img.clear()
img.draw_string(65,100,(str('{:2d}'.format(Lengh))+' mm'),scale=5)
#lcd.clear(36, 36, 100)
#lcd.draw_string(60, 100,(str('{:2d}'.format(Lengh))+' mm'),(100,100,100),3,lcd.RED,lcd.BLACK)
#image.draw_string(x, y, text[, color[, scale=1[, x_spacing=0[, y_spacing=0[, mono_space=True]]]]])
lcd.display(img)
utime.sleep_ms(200)
i2c.deinit()
そして本体画面のみに表示させるバージョンがこれ。(キャラクタLCD表示無し)
sample2_VL53L0X.py
from machine import I2C
import utime,lcd,image,sensor
from VL53L0X import VL53L0X
sensor.reset(freq=22000000, dual_buff=False)
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) # 320x240
img = sensor.snapshot()
lcd.init(type=2, invert=True) # cube ips
lcd.rotation(2)
lcd.clear(36, 36, 100)
#color: The color initialized by LCD, which can be a 16-bit RGB565 color value, such as 0xFFFF
#or a tuple of RGB888, such as (236, 36, 36)
i2c = I2C(I2C.I2C3,mode=I2C.MODE_MASTER, freq=100000, scl=6, sda=7)
vl=VL53L0X(i2c)
vl.init()
while(True):
Lengh = vl.read()
print(Lengh)
img = sensor.snapshot()
img.clear()
img.draw_string(65,100,(str('{:2d}'.format(Lengh))+' mm'),scale=5)
#lcd.clear(36, 36, 100)
#lcd.draw_string(60, 100,(str('{:2d}'.format(Lengh))+' mm'),(100,100,100),3,lcd.RED,lcd.BLACK)
#image.draw_string(x, y, text[, color[, scale=1[, x_spacing=0[, y_spacing=0[, mono_space=True]]]]])
lcd.display(img)
utime.sleep_ms(200)
i2c.deinit()