Raspberry Pi上のPythonでVL53L0Xからデータを取得する為に、adafruit-circuitpython-vl53l0xモジュールを使用します。
adafruit-circuitpython-vl53l0xモジュールがインストールされていない場合、下記コマンドでインストールしてください。
sudo pip3 install adafruit-circuitpython-vl53l0x
vl53l0x.pyはパッケージとしてimportして使用しますが、テスト用に単体で距離データを取得できます。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
MH VL53L0X script.
==================
"""
import threading
import time
i2c_enable = False
try:
import adafruit_vl53l0x
import board
import busio
i2c_enable = True
except:
i2c_enable = False
import numpy as np
import random
class VL53L0X():
def __init__(self, *args, **kwargs):
"""
mesure length: 30 - 2000[mm]
Optionally adjust the measurement timing budget to change speed and accuracy.
See the example here for more details:
https://github.com/pololu/vl53l0x-arduino/blob/master/examples/Single/Single.ino
For example a higher speed but less accurate timing budget of 20ms:
vl53.measurement_timing_budget = 20000
Or a slower but more accurate timing budget of 200ms:
vl53.measurement_timing_budget = 200000
The default timing budget is 33ms, a good compromise of speed and accuracy.
***
avg: Average counts.
range: Default is (30, 2000).
in_range: If distance is inth range then True.
"""
self.i2c_enable = i2c_enable
self._distance = 0
self._history = []
self._shutdowning = False
self._in_range = False
self._avg = 1
self.avg = kwargs.get('avg', self._avg)
self._range = (30, 2000)
self.range = kwargs.get('range', self._range)
self.vl53 = None
if self.i2c_enable:
i2c = busio.I2C(board.SCL, board.SDA)
try:
self.vl53 = adafruit_vl53l0x.VL53L0X(i2c)
except:
self.i2c_enable = False
self._processing()
def __call__(self, *args, **kwargs):
return self.distance
@property
def avg(self):
return self._avg
@avg.setter
def avg(self, value):
self._avg = value
self._history = [0]
for _ in range(self.avg - 1):
self._history.append(0)
def __del__(self):
self._shutdowning = True
@property
def distance(self):
return self._distance
@property
def in_range(self):
return self._in_range
def _processing(self):
if self._shutdowning:
return
tmp = 0
if self.i2c_enable:
# For I2C error at pushed power switch.
try:
tmp = self.vl53.range
except:
pass
else:
# This value is for D6T-44L-06.
tmp = random.randint(500, 550)
if tmp <= 2000:
self._history[1: self.avg] = self._history[0: self.avg - 1]
self._history[0] = tmp
self._distance = np.average(self._history)
if (self._distance >= self._range[0]) \
& (self._distance <= self._range[1]):
self._in_range = True
else:
self._in_range = False
time.sleep(0.1)
thread = threading.Thread(
name='VL53L0X_Measuring',
target=self._processing,
)
thread.daeom = True
thread.start()
@property
def range(self):
return self._range
@range.setter
def range(self, value):
self._range = value
def stop(self):
self._shutdowning = True
if __name__ == '__main__':
vl = VL53L0X(avg=10)
while True:
print(f'Range: {vl()}[mm] {vl.in_range}')
time.sleep(0.1)
pass