From bc58642357f965352fd267d83248e895ae2ec22e Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Tue, 19 Dec 2017 14:24:06 +1300 Subject: [PATCH 01/13] Add setup.py --- python/VL53L0X.py | 10 ++++++++- setup.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 setup.py diff --git a/python/VL53L0X.py b/python/VL53L0X.py index 07c35ab..9633389 100755 --- a/python/VL53L0X.py +++ b/python/VL53L0X.py @@ -65,7 +65,15 @@ def i2c_write(address, reg, data_p, length): return ret_val # Load VL53L0X shared lib -tof_lib = CDLL("../bin/vl53l0x_python.so") +_possible_lib_locations = site.getsitepackages() + ['../bin'] +for lib_location in _possible_lib_locations: + try: + tof_lib = CDLL(lib_location + "/vl53l0x_python.so") + break + except OSError: + pass +else: + raise OSError('Could not find vl53l0x_python.so') # Create read function pointer READFUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte, POINTER(c_ubyte), c_ubyte) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..151f0b8 --- /dev/null +++ b/setup.py @@ -0,0 +1,56 @@ +from distutils.core import setup, Extension +from distutils.command.build_ext import build_ext + + +# Found this on stack overflow: +# https://stackoverflow.com/questions/4529555/building-a-ctypes-based-c-library-with-distutils +# noinspection PyPep8Naming +class build_ext(build_ext): + + def build_extension(self, ext): + # noinspection PyAttributeOutsideInit + self._ctypes = isinstance(ext, CTypesExtension) + return super().build_extension(ext) + + def get_export_symbols(self, ext): + if self._ctypes: + return ext.export_symbols + return super().get_export_symbols(ext) + + def get_ext_filename(self, ext_name): + if self._ctypes: + return ext_name + '.so' + return super().get_ext_filename(ext_name) + + +class CTypesExtension(Extension): + pass + + +extension = CTypesExtension( + 'vl53l0x_python', + define_macros=[], + include_dirs=['.', 'Api/core/inc', 'platform/inc'], + libraries=[], + library_dirs=[], + sources=['Api/core/src/vl53l0x_api_calibration.c', + 'Api/core/src/vl53l0x_api_core.c', + 'Api/core/src/vl53l0x_api_ranging.c', + 'Api/core/src/vl53l0x_api_strings.c', + 'Api/core/src/vl53l0x_api.c', + 'platform/src/vl53l0x_platform.c', + 'python_lib/vl53l0x_python.c']) + +setup(name='VL53L0X_rasp_python', + version='1.0.2', + description='VL53L0X sensor for raspberry PI', + # author='?', + # author_email='?', + url='https://github.com/johnbryanmoore/VL53L0X_rasp_python', + long_description=''' +VL53L0X sensor for raspberry PI. +''', + ext_modules=[extension], + package_dir={'': 'python'}, + py_modules=['VL53L0X'], + cmdclass={'build_ext': build_ext}) From 8a555c0fc6d7d0943a1a8e9a566276743f22a7e9 Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Tue, 19 Dec 2017 14:26:01 +1300 Subject: [PATCH 02/13] Use smbus2 Simpler python based implementation, works fine on Raspberry PI --- python/VL53L0X.py | 2 +- setup.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/python/VL53L0X.py b/python/VL53L0X.py index 9633389..6a2c14f 100755 --- a/python/VL53L0X.py +++ b/python/VL53L0X.py @@ -24,7 +24,7 @@ import time from ctypes import * -import smbus +import smbus2 as smbus VL53L0X_GOOD_ACCURACY_MODE = 0 # Good Accuracy mode VL53L0X_BETTER_ACCURACY_MODE = 1 # Better Accuracy mode diff --git a/setup.py b/setup.py index 151f0b8..667e60c 100644 --- a/setup.py +++ b/setup.py @@ -53,4 +53,5 @@ class CTypesExtension(Extension): ext_modules=[extension], package_dir={'': 'python'}, py_modules=['VL53L0X'], + requires=['smbus2'], cmdclass={'build_ext': build_ext}) From f24be9dfa60b3f40a92506bd0889befe527cc4a0 Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Tue, 19 Dec 2017 14:26:35 +1300 Subject: [PATCH 03/13] Tidy and add gitignore --- .gitignore | 2 ++ python/VL53L0X.py | 45 ++++++++++++++++++++++++--------------------- 2 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8461078 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +.idea diff --git a/python/VL53L0X.py b/python/VL53L0X.py index 6a2c14f..a19c864 100755 --- a/python/VL53L0X.py +++ b/python/VL53L0X.py @@ -21,38 +21,39 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - -import time from ctypes import * import smbus2 as smbus +import site -VL53L0X_GOOD_ACCURACY_MODE = 0 # Good Accuracy mode -VL53L0X_BETTER_ACCURACY_MODE = 1 # Better Accuracy mode -VL53L0X_BEST_ACCURACY_MODE = 2 # Best Accuracy mode -VL53L0X_LONG_RANGE_MODE = 3 # Longe Range mode -VL53L0X_HIGH_SPEED_MODE = 4 # High Speed mode +VL53L0X_GOOD_ACCURACY_MODE = 0 # Good Accuracy mode +VL53L0X_BETTER_ACCURACY_MODE = 1 # Better Accuracy mode +VL53L0X_BEST_ACCURACY_MODE = 2 # Best Accuracy mode +VL53L0X_LONG_RANGE_MODE = 3 # Longe Range mode +VL53L0X_HIGH_SPEED_MODE = 4 # High Speed mode i2cbus = smbus.SMBus(1) + # i2c bus read callback def i2c_read(address, reg, data_p, length): - ret_val = 0; + ret_val = 0 result = [] try: result = i2cbus.read_i2c_block_data(address, reg, length) except IOError: - ret_val = -1; + ret_val = -1 - if (ret_val == 0): + if ret_val == 0: for index in range(length): data_p[index] = result[index] return ret_val + # i2c bus write callback def i2c_write(address, reg, data_p, length): - ret_val = 0; + ret_val = 0 data = [] for index in range(length): @@ -60,11 +61,12 @@ def i2c_write(address, reg, data_p, length): try: i2cbus.write_i2c_block_data(address, reg, data) except IOError: - ret_val = -1; + ret_val = -1 return ret_val -# Load VL53L0X shared lib + +# Load VL53L0X shared lib _possible_lib_locations = site.getsitepackages() + ['../bin'] for lib_location in _possible_lib_locations: try: @@ -86,12 +88,13 @@ def i2c_write(address, reg, data_p, length): # pass i2c read and write function pointers to VL53L0X library tof_lib.VL53L0X_set_i2c(read_func, write_func) + class VL53L0X(object): """VL53L0X ToF.""" object_number = 0 - def __init__(self, address=0x29, TCA9548A_Num=255, TCA9548A_Addr=0, **kwargs): + def __init__(self, address=0x29, TCA9548A_Num=255, TCA9548A_Addr=0): """Initialize the VL53L0X ToF Sensor from ST""" self.device_address = address self.TCA9548A_Device = TCA9548A_Num @@ -99,9 +102,10 @@ def __init__(self, address=0x29, TCA9548A_Num=255, TCA9548A_Addr=0, **kwargs): self.my_object_number = VL53L0X.object_number VL53L0X.object_number += 1 - def start_ranging(self, mode = VL53L0X_GOOD_ACCURACY_MODE): + def start_ranging(self, mode=VL53L0X_GOOD_ACCURACY_MODE): """Start VL53L0X ToF Sensor Ranging""" - tof_lib.startRanging(self.my_object_number, mode, self.device_address, self.TCA9548A_Device, self.TCA9548A_Address) + tof_lib.startRanging(self.my_object_number, mode, self.device_address, + self.TCA9548A_Device, self.TCA9548A_Address) def stop_ranging(self): """Stop VL53L0X ToF Sensor Ranging""" @@ -114,12 +118,11 @@ def get_distance(self): # This function included to show how to access the ST library directly # from python instead of through the simplified interface def get_timing(self): - Dev = POINTER(c_void_p) - Dev = tof_lib.getDev(self.my_object_number) + dev = tof_lib.getDev(self.my_object_number) budget = c_uint(0) budget_p = pointer(budget) - Status = tof_lib.VL53L0X_GetMeasurementTimingBudgetMicroSeconds(Dev, budget_p) - if (Status == 0): - return (budget.value + 1000) + status = tof_lib.VL53L0X_GetMeasurementTimingBudgetMicroSeconds(dev, budget_p) + if status == 0: + return budget.value + 1000 else: return 0 From ac7e350cdce07cd06d591d1f16bf18b9c502bc9e Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Tue, 19 Dec 2017 14:39:15 +1300 Subject: [PATCH 04/13] Update readme --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f7fb983..331ef7c 100644 --- a/README.md +++ b/README.md @@ -31,13 +31,18 @@ Notes on Multiple sensor support: Notes on using TCA9548A I2C Multiplexer: - If limited on GPIO's that would be needed to set a new addresses for each sensor, using a TCA9548A I2C Multiplexer is a good option since it allows using up to 8 sensors without using GPIO's. - The TCA9548A is also a good option if using multiple boards on the same I2C bus and the total of all the combined I2C pullups would cause the bus not to function. -- Theoretically you can connect mutltiple TCA9548A Multiplexers, each with up to 8 sensors as long each TCA9548A has a different address. This has not been tested but should work in theory. +- Theoretically you can connect multiple TCA9548A Multiplexers, each with up to 8 sensors as long each TCA9548A has a different address. This has not been tested but should work in theory. (Please note that while the author is an embedded software engineer, this is a first attempt at extending python and the author is by no means a python expert so any improvement suggestions are appreciated). ### Installation - +```bash +# Python2 +pip2 install git+https://github.com/johnbryanmoore/VL53L0X_rasp_python.git +# Python3 +pip3 install git+https://github.com/johnbryanmoore/VL53L0X_rasp_python.git +``` ### Compilation From 9c998edb3ef445c35b3f14b0d88d083421c6721f Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Thu, 11 Jan 2018 15:54:44 +1300 Subject: [PATCH 05/13] Major refactor Split initialisation from "start ranging" Remove "object number", just always use device pointer Don't open I2C on module import, add additional open/close methods for completeness Add GPIO interrupt configuration --- python/VL53L0X.py | 187 ++++++++---- python_lib/vl53l0x_python.c | 568 +++++++++++++++++------------------- 2 files changed, 391 insertions(+), 364 deletions(-) diff --git a/python/VL53L0X.py b/python/VL53L0X.py index a19c864..4ce529f 100755 --- a/python/VL53L0X.py +++ b/python/VL53L0X.py @@ -21,108 +21,167 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from ctypes import * +from ctypes import CDLL, CFUNCTYPE, POINTER, c_int, c_uint, pointer, c_ubyte, c_uint8, c_uint32 import smbus2 as smbus import site -VL53L0X_GOOD_ACCURACY_MODE = 0 # Good Accuracy mode -VL53L0X_BETTER_ACCURACY_MODE = 1 # Better Accuracy mode -VL53L0X_BEST_ACCURACY_MODE = 2 # Best Accuracy mode -VL53L0X_LONG_RANGE_MODE = 3 # Longe Range mode -VL53L0X_HIGH_SPEED_MODE = 4 # High Speed mode -i2cbus = smbus.SMBus(1) +class Vl53l0xError(RuntimeError): + pass -# i2c bus read callback -def i2c_read(address, reg, data_p, length): - ret_val = 0 - result = [] - - try: - result = i2cbus.read_i2c_block_data(address, reg, length) - except IOError: - ret_val = -1 +class Vl53l0xAccuracyMode: + GOOD = 0 # 33 ms timing budget 1.2m range + BETTER = 1 # 66 ms timing budget 1.2m range + BEST = 2 # 200 ms 1.2m range + LONG_RANGE = 3 # 33 ms timing budget 2m range + HIGH_SPEED = 4 # 20 ms timing budget 1.2m range - if ret_val == 0: - for index in range(length): - data_p[index] = result[index] - return ret_val +class Vl53l0xDeviceMode: + SINGLE_RANGING = 0 + CONTINUOUS_RANGING = 1 + SINGLE_HISTOGRAM = 2 + CONTINUOUS_TIMED_RANGING = 3 + SINGLE_ALS = 10 + GPIO_DRIVE = 20 + GPIO_OSC = 21 -# i2c bus write callback -def i2c_write(address, reg, data_p, length): - ret_val = 0 - data = [] +class Vl53l0xGpioAlarmType: + OFF = 0 + THRESHOLD_CROSSED_LOW = 1 + THRESHOLD_CROSSED_HIGH = 2 + THRESHOLD_CROSSED_OUT = 3 + NEW_MEASUREMENT_READY = 4 - for index in range(length): - data.append(data_p[index]) - try: - i2cbus.write_i2c_block_data(address, reg, data) - except IOError: - ret_val = -1 - return ret_val +class Vl53l0xInterruptPolarity: + LOW = 0 + HIGH = 1 + +# Read/write function pointer types. +_I2C_READ_FUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte, POINTER(c_ubyte), c_ubyte) +_I2C_WRITE_FUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte, POINTER(c_ubyte), c_ubyte) # Load VL53L0X shared lib -_possible_lib_locations = site.getsitepackages() + ['../bin'] -for lib_location in _possible_lib_locations: +_POSSIBLE_LIBRARY_LOCATIONS = ['../bin'] + site.getsitepackages() +for lib_location in _POSSIBLE_LIBRARY_LOCATIONS: try: - tof_lib = CDLL(lib_location + "/vl53l0x_python.so") + _TOF_LIBRARY = CDLL(lib_location + "/vl53l0x_python.so") break except OSError: pass else: raise OSError('Could not find vl53l0x_python.so') -# Create read function pointer -READFUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte, POINTER(c_ubyte), c_ubyte) -read_func = READFUNC(i2c_read) - -# Create write function pointer -WRITEFUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte, POINTER(c_ubyte), c_ubyte) -write_func = WRITEFUNC(i2c_write) - -# pass i2c read and write function pointers to VL53L0X library -tof_lib.VL53L0X_set_i2c(read_func, write_func) - -class VL53L0X(object): +class VL53L0X: """VL53L0X ToF.""" - - object_number = 0 - - def __init__(self, address=0x29, TCA9548A_Num=255, TCA9548A_Addr=0): + def __init__(self, i2c_bus=1, i2c_address=0x29, tca9548a_num=255, tca9548a_addr=0): """Initialize the VL53L0X ToF Sensor from ST""" - self.device_address = address - self.TCA9548A_Device = TCA9548A_Num - self.TCA9548A_Address = TCA9548A_Addr - self.my_object_number = VL53L0X.object_number - VL53L0X.object_number += 1 - - def start_ranging(self, mode=VL53L0X_GOOD_ACCURACY_MODE): + self._i2c_bus = i2c_bus + self.i2c_address = i2c_address + self._tca9548a_num = tca9548a_num + self._tca9548a_addr = tca9548a_addr + self._i2c = smbus.SMBus() + self._dev = None + + def open(self): + self._i2c.open(bus=self._i2c_bus) + self._configure_i2c_library_functions() + self._dev = _TOF_LIBRARY.initialise(self.i2c_address, self._tca9548a_num, self._tca9548a_addr) + + def close(self): + self._i2c.close() + self._dev = None + + def _configure_i2c_library_functions(self): + # I2C bus read callback for low level library. + def _i2c_read(address, reg, data_p, length): + ret_val = 0 + result = [] + + try: + result = self._i2c.read_i2c_block_data(address, reg, length) + except IOError: + ret_val = -1 + + if ret_val == 0: + for index in range(length): + data_p[index] = result[index] + + return ret_val + + # I2C bus write callback for low level library. + def _i2c_write(address, reg, data_p, length): + ret_val = 0 + data = [] + + for index in range(length): + data.append(data_p[index]) + try: + self._i2c.write_i2c_block_data(address, reg, data) + except IOError: + ret_val = -1 + + return ret_val + + # Pass i2c read/write function pointers to VL53L0X library. + self._i2c_read_func = _I2C_READ_FUNC(_i2c_read) + self._i2c_write_func = _I2C_WRITE_FUNC(_i2c_write) + _TOF_LIBRARY.VL53L0X_set_i2c(self._i2c_read_func, self._i2c_write_func) + + def start_ranging(self, mode=Vl53l0xAccuracyMode.GOOD): """Start VL53L0X ToF Sensor Ranging""" - tof_lib.startRanging(self.my_object_number, mode, self.device_address, - self.TCA9548A_Device, self.TCA9548A_Address) - + _TOF_LIBRARY.startRanging(self._dev, mode) + def stop_ranging(self): """Stop VL53L0X ToF Sensor Ranging""" - tof_lib.stopRanging(self.my_object_number) + _TOF_LIBRARY.stopRanging(self._dev) def get_distance(self): """Get distance from VL53L0X ToF Sensor""" - return tof_lib.getDistance(self.my_object_number) + return _TOF_LIBRARY.getDistance(self._dev) # This function included to show how to access the ST library directly # from python instead of through the simplified interface def get_timing(self): - dev = tof_lib.getDev(self.my_object_number) budget = c_uint(0) budget_p = pointer(budget) - status = tof_lib.VL53L0X_GetMeasurementTimingBudgetMicroSeconds(dev, budget_p) + status = _TOF_LIBRARY.VL53L0X_GetMeasurementTimingBudgetMicroSeconds(self._dev, budget_p) if status == 0: return budget.value + 1000 else: return 0 + + def configure_gpio_interrupt( + self, proximity_alarm_type: Vl53l0xGpioAlarmType = Vl53l0xGpioAlarmType.THRESHOLD_CROSSED_LOW, + interrupt_polarity: Vl53l0xInterruptPolarity = Vl53l0xInterruptPolarity.HIGH, + threshold_low_mm: int = 250, threshold_high_mm: int = 500): + """ + Configures a GPIO interrupt from device, be sure to call "clear_interrupt" after interrupt is processed. + """ + pin = c_uint8(0) # 0 is only GPIO pin. + device_mode = c_uint8(Vl53l0xDeviceMode.CONTINUOUS_RANGING) + functionality = c_uint8(proximity_alarm_type) + polarity = c_uint8(interrupt_polarity) + status = _TOF_LIBRARY.VL53L0X_SetGpioConfig(self._dev, pin, device_mode, functionality, polarity) + if status != 0: + raise Vl53l0xError('Error setting VL53L0X GPIO config') + + threshold_low = c_uint32(threshold_low_mm << 16) + threshold_high = c_uint32(threshold_high_mm << 16) + status = _TOF_LIBRARY.VL53L0X_SetInterruptThresholds(self._dev, device_mode, threshold_low, threshold_high) + if status != 0: + raise Vl53l0xError('Error setting VL53L0X thresholds') + + # Ensure any pending interrupts are cleared. + self.clear_interrupt() + + def clear_interrupt(self): + mask = c_uint32(0) + status = _TOF_LIBRARY.VL53L0X_ClearInterruptMask(self._dev, mask) + if status != 0: + raise Vl53l0xError('Error clearing VL53L0X interrupt') diff --git a/python_lib/vl53l0x_python.c b/python_lib/vl53l0x_python.c index 20495aa..bd0e9d6 100644 --- a/python_lib/vl53l0x_python.c +++ b/python_lib/vl53l0x_python.c @@ -45,9 +45,6 @@ SOFTWARE. #define VL53L0X_LONG_RANGE_MODE 3 // Longe Range mode #define VL53L0X_HIGH_SPEED_MODE 4 // High Speed mode -#define MAX_DEVICES 16 - -static VL53L0X_Dev_t *pMyDevice[MAX_DEVICES]; static VL53L0X_RangingMeasurementData_t RangingMeasurementData; static VL53L0X_RangingMeasurementData_t *pRangingMeasurementData = &RangingMeasurementData; @@ -121,32 +118,15 @@ VL53L0X_Error WaitStopCompleted(VL53L0X_DEV Dev) } /****************************************************************************** - * @brief Start Ranging - * @param mode - ranging mode - * 0 - Good Accuracy mode - * 1 - Better Accuracy mode - * 2 - Best Accuracy mode - * 3 - Longe Range mode - * 4 - High Speed mode - * @note Mode Definitions - * Good Accuracy mode - * 33 ms timing budget 1.2m range - * Better Accuracy mode - * 66 ms timing budget 1.2m range - * Best Accuracy mode - * 200 ms 1.2m range - * Long Range mode (indoor,darker conditions) - * 33 ms timing budget 2m range - * High Speed Mode (decreased accuracy) - * 20 ms timing budget 1.2m range + * @brief Initialises the device. * @param i2c_address - I2C Address to set for this device * @param TCA9548A_Device - Device number on TCA9548A I2C multiplexer if * being used. If not being used, set to 255. * @param TCA9548A_Address - Address of TCA9548A I2C multiplexer if * being used. If not being used, set to 0. - * + * @retval The Dev Object to pass to other library functions. *****************************************************************************/ -void startRanging(int object_number, int mode, uint8_t i2c_address, uint8_t TCA9548A_Device, uint8_t TCA9548A_Address) +VL53L0X_Dev_t *initialise(uint8_t i2c_address, uint8_t TCA9548A_Device, uint8_t TCA9548A_Address) { VL53L0X_Error Status = VL53L0X_ERROR_NONE; uint32_t refSpadCount; @@ -160,382 +140,370 @@ void startRanging(int object_number, int mode, uint8_t i2c_address, uint8_t TCA9 if (TCA9548A_Device < 8) { - printf ("VL53L0X Start Ranging Object %d Address 0x%02X TCA9548A Device %d TCA9548A Address 0x%02X\n\n", - object_number, i2c_address, TCA9548A_Device, TCA9548A_Address); + printf ("VL53L0X Start Ranging Address 0x%02X TCA9548A Device %d TCA9548A Address 0x%02X\n\n", + i2c_address, TCA9548A_Device, TCA9548A_Address); } else { - printf ("VL53L0X Start Ranging Object %d Address 0x%02X\n\n", object_number, i2c_address); + printf ("VL53L0X Start Ranging Address 0x%02X\n\n", i2c_address); } - if (mode >= VL53L0X_GOOD_ACCURACY_MODE && - mode <= VL53L0X_HIGH_SPEED_MODE && - object_number < MAX_DEVICES) + VL53L0X_Dev_t *dev = (VL53L0X_Dev_t *)malloc(sizeof(VL53L0X_Dev_t)); + memset(dev, 0, sizeof(VL53L0X_Dev_t)); + + if (dev != NULL) { - pMyDevice[object_number] = (VL53L0X_Dev_t *)malloc(sizeof(VL53L0X_Dev_t)); - memset(pMyDevice[object_number], 0, sizeof(VL53L0X_Dev_t)); + // Initialize Comms to the default address to start + dev->I2cDevAddr = VL53L0X_DEFAULT_ADDRESS; + dev->TCA9548A_Device = TCA9548A_Device; + dev->TCA9548A_Address = TCA9548A_Address; + + VL53L0X_init(dev); + /* + * Get the version of the VL53L0X API running in the firmware + */ + + // If the requested address is not the default, change it in the device + if (i2c_address != VL53L0X_DEFAULT_ADDRESS) + { + printf("Setting I2C Address to 0x%02X\n", i2c_address); + // Address requested not default so set the address. + // This assumes that the shutdown pin has been controlled + // externally to this function. + // TODO: Why does this function divide the address by 2? To get + // the address we want we have to mutiply by 2 in the call so + // it gets set right + Status = VL53L0X_SetDeviceAddress(dev, (i2c_address * 2)); + dev->I2cDevAddr = i2c_address; + } - if (pMyDevice[object_number] != NULL) + if (Status == VL53L0X_ERROR_NONE) { - // Initialize Comms to the default address to start - pMyDevice[object_number]->I2cDevAddr = VL53L0X_DEFAULT_ADDRESS; - pMyDevice[object_number]->TCA9548A_Device = TCA9548A_Device; - pMyDevice[object_number]->TCA9548A_Address = TCA9548A_Address; - - VL53L0X_init(pMyDevice[object_number]); - /* - * Get the version of the VL53L0X API running in the firmware - */ - - // If the requested address is not the default, change it in the device - if (i2c_address != VL53L0X_DEFAULT_ADDRESS) + status_int = VL53L0X_GetVersion(pVersion); + if (status_int == 0) { - printf("Setting I2C Address to 0x%02X\n", i2c_address); - // Address requested not default so set the address. - // This assumes that the shutdown pin has been controlled - // externally to this function. - // TODO: Why does this function divide the address by 2? To get - // the address we want we have to mutiply by 2 in the call so - // it gets set right - Status = VL53L0X_SetDeviceAddress(pMyDevice[object_number], (i2c_address * 2)); - pMyDevice[object_number]->I2cDevAddr = i2c_address; - } + /* + * Verify the version of the VL53L0X API running in the firmrware + */ + + // Check the Api version. If it is not correct, put out a warning + if( pVersion->major != VERSION_REQUIRED_MAJOR || + pVersion->minor != VERSION_REQUIRED_MINOR || + pVersion->build != VERSION_REQUIRED_BUILD ) + { + printf("VL53L0X API Version Warning: Your firmware %d.%d.%d (revision %d). This requires %d.%d.%d.\n", + pVersion->major, pVersion->minor, pVersion->build, pVersion->revision, + VERSION_REQUIRED_MAJOR, VERSION_REQUIRED_MINOR, VERSION_REQUIRED_BUILD); + } + // End of implementation specific - if (Status == VL53L0X_ERROR_NONE) - { - status_int = VL53L0X_GetVersion(pVersion); - if (status_int == 0) + Status = VL53L0X_DataInit(dev); // Data initialization + if(Status == VL53L0X_ERROR_NONE) { - /* - * Verify the version of the VL53L0X API running in the firmrware - */ - - // Check the Api version. If it is not correct, put out a warning - if( pVersion->major != VERSION_REQUIRED_MAJOR || - pVersion->minor != VERSION_REQUIRED_MINOR || - pVersion->build != VERSION_REQUIRED_BUILD ) + Status = VL53L0X_GetDeviceInfo(dev, &DeviceInfo); + if(Status == VL53L0X_ERROR_NONE) { - printf("VL53L0X API Version Warning: Your firmware %d.%d.%d (revision %d). This requires %d.%d.%d.\n", - pVersion->major, pVersion->minor, pVersion->build, pVersion->revision, - VERSION_REQUIRED_MAJOR, VERSION_REQUIRED_MINOR, VERSION_REQUIRED_BUILD); + printf("VL53L0X_GetDeviceInfo:\n"); + printf("Device Name : %s\n", DeviceInfo.Name); + printf("Device Type : %s\n", DeviceInfo.Type); + printf("Device ID : %s\n", DeviceInfo.ProductId); + printf("ProductRevisionMajor : %d\n", DeviceInfo.ProductRevisionMajor); + printf("ProductRevisionMinor : %d\n", DeviceInfo.ProductRevisionMinor); + + if ((DeviceInfo.ProductRevisionMajor != 1) && (DeviceInfo.ProductRevisionMinor != 1)) { + printf("Error expected cut 1.1 but found cut %d.%d\n", + DeviceInfo.ProductRevisionMajor, DeviceInfo.ProductRevisionMinor); + Status = VL53L0X_ERROR_NOT_SUPPORTED; + } } - // End of implementation specific - Status = VL53L0X_DataInit(pMyDevice[object_number]); // Data initialization if(Status == VL53L0X_ERROR_NONE) { - Status = VL53L0X_GetDeviceInfo(pMyDevice[object_number], &DeviceInfo); - if(Status == VL53L0X_ERROR_NONE) - { - printf("VL53L0X_GetDeviceInfo:\n"); - printf("Device Name : %s\n", DeviceInfo.Name); - printf("Device Type : %s\n", DeviceInfo.Type); - printf("Device ID : %s\n", DeviceInfo.ProductId); - printf("ProductRevisionMajor : %d\n", DeviceInfo.ProductRevisionMajor); - printf("ProductRevisionMinor : %d\n", DeviceInfo.ProductRevisionMinor); - - if ((DeviceInfo.ProductRevisionMajor != 1) && (DeviceInfo.ProductRevisionMinor != 1)) { - printf("Error expected cut 1.1 but found cut %d.%d\n", - DeviceInfo.ProductRevisionMajor, DeviceInfo.ProductRevisionMinor); - Status = VL53L0X_ERROR_NOT_SUPPORTED; - } - } + Status = VL53L0X_StaticInit(dev); // Device Initialization + // StaticInit will set interrupt by default if(Status == VL53L0X_ERROR_NONE) { - Status = VL53L0X_StaticInit(pMyDevice[object_number]); // Device Initialization - // StaticInit will set interrupt by default + Status = VL53L0X_PerformRefCalibration(dev, + &VhvSettings, &PhaseCal); // Device Initialization if(Status == VL53L0X_ERROR_NONE) { - Status = VL53L0X_PerformRefCalibration(pMyDevice[object_number], - &VhvSettings, &PhaseCal); // Device Initialization + Status = VL53L0X_PerformRefSpadManagement(dev, + &refSpadCount, &isApertureSpads); // Device Initialization - if(Status == VL53L0X_ERROR_NONE) + if(Status != VL53L0X_ERROR_NONE) { - Status = VL53L0X_PerformRefSpadManagement(pMyDevice[object_number], - &refSpadCount, &isApertureSpads); // Device Initialization - - if(Status == VL53L0X_ERROR_NONE) - { - // Setup in continuous ranging mode - Status = VL53L0X_SetDeviceMode(pMyDevice[object_number], VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); - - if(Status == VL53L0X_ERROR_NONE) - { - // Set accuracy mode - switch (mode) - { - case VL53L0X_BEST_ACCURACY_MODE: - printf("VL53L0X_BEST_ACCURACY_MODE\n"); - if (Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_SetLimitCheckValue(pMyDevice[object_number], - VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, - (FixPoint1616_t)(0.25*65536)); - - if (Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_SetLimitCheckValue(pMyDevice[object_number], - VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, - (FixPoint1616_t)(18*65536)); - - if (Status == VL53L0X_ERROR_NONE) - { - Status = - VL53L0X_SetMeasurementTimingBudgetMicroSeconds(pMyDevice[object_number], 200000); - } - } - } - break; - - case VL53L0X_LONG_RANGE_MODE: - printf("VL53L0X_LONG_RANGE_MODE\n"); - if (Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_SetLimitCheckValue(pMyDevice[object_number], - VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, - (FixPoint1616_t)(0.1*65536)); - - if (Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_SetLimitCheckValue(pMyDevice[object_number], - VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, - (FixPoint1616_t)(60*65536)); - - if (Status == VL53L0X_ERROR_NONE) - { - Status = - VL53L0X_SetMeasurementTimingBudgetMicroSeconds(pMyDevice[object_number], 33000); - - if (Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_SetVcselPulsePeriod(pMyDevice[object_number], - VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18); - - if (Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_SetVcselPulsePeriod(pMyDevice[object_number], - VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14); - } - } - } - } - } - break; - - case VL53L0X_HIGH_SPEED_MODE: - printf("VL53L0X_HIGH_SPEED_MODE\n"); - if (Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_SetLimitCheckValue(pMyDevice[object_number], - VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, - (FixPoint1616_t)(0.25*65536)); - - if (Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_SetLimitCheckValue(pMyDevice[object_number], - VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, - (FixPoint1616_t)(32*65536)); - - if (Status == VL53L0X_ERROR_NONE) - { - Status = - VL53L0X_SetMeasurementTimingBudgetMicroSeconds(pMyDevice[object_number], 20000); - } - } - } - break; - - case VL53L0X_BETTER_ACCURACY_MODE: - printf("VL53L0X_BETTER_ACCURACY_MODE\n"); - if (Status == VL53L0X_ERROR_NONE) - { - Status = - VL53L0X_SetMeasurementTimingBudgetMicroSeconds(pMyDevice[object_number], 66000); - } - break; - - case VL53L0X_GOOD_ACCURACY_MODE: - default: - printf("VL53L0X_GOOD_ACCURACY_MODE\n"); - if (Status == VL53L0X_ERROR_NONE) - { - Status = - VL53L0X_SetMeasurementTimingBudgetMicroSeconds(pMyDevice[object_number], 33000); - } - break; - } - - if(Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_StartMeasurement(pMyDevice[object_number]); - } - else - { - printf("Set Accuracy\n"); - } - } - else - { - printf ("Call of VL53L0X_SetDeviceMode\n"); - } - } - else - { - printf ("Call of VL53L0X_PerformRefSpadManagement\n"); - } - } - else - { - printf ("Call of VL53L0X_PerformRefCalibration\n"); + printf ("Call of VL53L0X_PerformRefSpadManagement\n"); } } else { - printf ("Call of VL53L0X_StaticInit\n"); + printf ("Call of VL53L0X_PerformRefCalibration\n"); } } else { - printf ("Invalid Device Info\n"); + printf ("Call of VL53L0X_StaticInit\n"); } } else { - printf ("Call of VL53L0X_DataInit\n"); + printf ("Invalid Device Info\n"); } } else { - Status = VL53L0X_ERROR_CONTROL_INTERFACE; - printf("Call of VL53L0X_GetVersion\n"); + printf ("Call of VL53L0X_DataInit\n"); } } else { - printf("Call of VL53L0X_SetAddress\n"); + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + printf("Call of VL53L0X_GetVersion\n"); } - - print_pal_error(Status); } else { - printf("Object %d not initialized\n", object_number); + printf("Call of VL53L0X_SetAddress\n"); } + + print_pal_error(Status); } else { - if (object_number >= MAX_DEVICES) - { - printf("Max objects Exceeded\n"); - } - else - { - printf("Invalid mode %d specified\n", mode); - } + printf("Memory allocation failure\n"); } + + return dev; } /****************************************************************************** - * @brief Get current distance in mm - * @return Current distance in mm or -1 on error + * @brief Start Ranging + * @param mode - ranging mode + * 0 - Good Accuracy mode + * 1 - Better Accuracy mode + * 2 - Best Accuracy mode + * 3 - Longe Range mode + * 4 - High Speed mode + * @note Mode Definitions + * Good Accuracy mode + * 33 ms timing budget 1.2m range + * Better Accuracy mode + * 66 ms timing budget 1.2m range + * Best Accuracy mode + * 200 ms 1.2m range + * Long Range mode (indoor,darker conditions) + * 33 ms timing budget 2m range + * High Speed Mode (decreased accuracy) + * 20 ms timing budget 1.2m range + * @retval Error code, 0 for success. *****************************************************************************/ -int32_t getDistance(int object_number) +VL53L0X_Error startRanging(VL53L0X_Dev_t *dev, int mode) { - VL53L0X_Error Status = VL53L0X_ERROR_NONE; - int32_t current_distance = -1; + if (mode < VL53L0X_GOOD_ACCURACY_MODE && + mode > VL53L0X_HIGH_SPEED_MODE) + { + printf("Invalid mode %d specified\n", mode); + return -1; + } - if (object_number < MAX_DEVICES) + // Setup in continuous ranging mode + VL53L0X_Error Status = VL53L0X_SetDeviceMode(dev, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); + + if(Status == VL53L0X_ERROR_NONE) { - if (pMyDevice[object_number] != NULL) + // Set accuracy mode + switch (mode) { - Status = WaitMeasurementDataReady(pMyDevice[object_number]); + case VL53L0X_BEST_ACCURACY_MODE: + printf("VL53L0X_BEST_ACCURACY_MODE\n"); + if (Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_SetLimitCheckValue(dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + (FixPoint1616_t)(0.25*65536)); - if(Status == VL53L0X_ERROR_NONE) - { - Status = VL53L0X_GetRangingMeasurementData(pMyDevice[object_number], - pRangingMeasurementData); - if(Status == VL53L0X_ERROR_NONE) + if (Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_SetLimitCheckValue(dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + (FixPoint1616_t)(18*65536)); + + if (Status == VL53L0X_ERROR_NONE) + { + Status = + VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev, 200000); + } + } + } + break; + + case VL53L0X_LONG_RANGE_MODE: + printf("VL53L0X_LONG_RANGE_MODE\n"); + if (Status == VL53L0X_ERROR_NONE) { - current_distance = pRangingMeasurementData->RangeMilliMeter; + Status = VL53L0X_SetLimitCheckValue(dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + (FixPoint1616_t)(0.1*65536)); + + if (Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_SetLimitCheckValue(dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + (FixPoint1616_t)(60*65536)); + + if (Status == VL53L0X_ERROR_NONE) + { + Status = + VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev, 33000); + + if (Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_SetVcselPulsePeriod(dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18); + + if (Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_SetVcselPulsePeriod(dev, + VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14); + } + } + } + } } + break; - // Clear the interrupt - VL53L0X_ClearInterruptMask(pMyDevice[object_number], - VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); - // VL53L0X_PollingDelay(pMyDevice[object_number]); - } + case VL53L0X_HIGH_SPEED_MODE: + printf("VL53L0X_HIGH_SPEED_MODE\n"); + if (Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_SetLimitCheckValue(dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + (FixPoint1616_t)(0.25*65536)); + + if (Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_SetLimitCheckValue(dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + (FixPoint1616_t)(32*65536)); + + if (Status == VL53L0X_ERROR_NONE) + { + Status = + VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev, 20000); + } + } + } + break; + + case VL53L0X_BETTER_ACCURACY_MODE: + printf("VL53L0X_BETTER_ACCURACY_MODE\n"); + if (Status == VL53L0X_ERROR_NONE) + { + Status = + VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev, 66000); + } + break; + + case VL53L0X_GOOD_ACCURACY_MODE: + default: + printf("VL53L0X_GOOD_ACCURACY_MODE\n"); + if (Status == VL53L0X_ERROR_NONE) + { + Status = + VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev, 33000); + } + break; + } + + if(Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_StartMeasurement(dev); } else { - printf("Object %d not initialized\n", object_number); + printf("Set Accuracy\n"); } } else { - printf("Invalid object number %d specified\n", object_number); + printf ("Call of VL53L0X_SetDeviceMode\n"); } - return current_distance; + print_pal_error(Status); + + return Status; } /****************************************************************************** - * @brief Stop Ranging + * @brief Get current distance in mm + * @return Current distance in mm or -1 on error *****************************************************************************/ -void stopRanging(int object_number) +int32_t getDistance(VL53L0X_Dev_t *dev) { VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t current_distance = -1; - printf ("Call of VL53L0X_StopMeasurement\n"); - - if (object_number < MAX_DEVICES) + if (dev != NULL) { - if (pMyDevice[object_number] != NULL) - { - Status = VL53L0X_StopMeasurement(pMyDevice[object_number]); - - if(Status == VL53L0X_ERROR_NONE) - { - printf ("Wait Stop to be competed\n"); - Status = WaitStopCompleted(pMyDevice[object_number]); - } + Status = WaitMeasurementDataReady(dev); + if(Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_GetRangingMeasurementData(dev, + pRangingMeasurementData); if(Status == VL53L0X_ERROR_NONE) { - Status = VL53L0X_ClearInterruptMask(pMyDevice[object_number], - VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); + current_distance = pRangingMeasurementData->RangeMilliMeter; } - print_pal_error(Status); - - free(pMyDevice[object_number]); - } - else - { - printf("Object %d not initialized\n", object_number); + // Clear the interrupt + VL53L0X_ClearInterruptMask(dev, + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); + // VL53L0X_PollingDelay(dev); } } else { - printf("Invalid object number %d specified\n", object_number); + printf("Device not initialized\n"); } + + return current_distance; } /****************************************************************************** - * @brief Return the Dev Object to pass to Lib functions + * @brief Stop Ranging *****************************************************************************/ -VL53L0X_DEV getDev(int object_number) +void stopRanging(VL53L0X_Dev_t *dev) { - VL53L0X_DEV Dev = NULL; - if (object_number < MAX_DEVICES) + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + printf ("Call of VL53L0X_StopMeasurement\n"); + + if (dev != NULL) { - if (pMyDevice[object_number] != NULL) + Status = VL53L0X_StopMeasurement(dev); + + if(Status == VL53L0X_ERROR_NONE) { - Dev = pMyDevice[object_number]; + printf ("Wait Stop to be competed\n"); + Status = WaitStopCompleted(dev); } - } - return Dev; -} + if(Status == VL53L0X_ERROR_NONE) + { + Status = VL53L0X_ClearInterruptMask(dev, + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); + } + print_pal_error(Status); + + free(dev); + dev = NULL; + } + else + { + printf("Device not initialized\n"); + } +} From 53b871746f947cdc501747f0bfed0cfd9e61292d Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Thu, 11 Jan 2018 15:55:16 +1300 Subject: [PATCH 06/13] Update examples to interface change --- python/VL53L0X_TCA9548A_example.py | 26 +++++++++++++++----------- python/VL53L0X_example.py | 15 ++++++++------- python/VL53L0X_example_livegraph.py | 17 ++++++++++------- python/VL53L0X_multi_example.py | 28 ++++++++++++++++------------ 4 files changed, 49 insertions(+), 37 deletions(-) diff --git a/python/VL53L0X_TCA9548A_example.py b/python/VL53L0X_TCA9548A_example.py index ece11ea..550dfb8 100755 --- a/python/VL53L0X_TCA9548A_example.py +++ b/python/VL53L0X_TCA9548A_example.py @@ -26,33 +26,37 @@ import VL53L0X # Create a VL53L0X object for device on TCA9548A bus 1 -tof1 = VL53L0X.VL53L0X(TCA9548A_Num=1, TCA9548A_Addr=0x70) +tof1 = VL53L0X.VL53L0X(tca9548a_num=1, tca9548a_addr=0x70) # Create a VL53L0X object for device on TCA9548A bus 2 -tof2 = VL53L0X.VL53L0X(TCA9548A_Num=2, TCA9548A_Addr=0x70) +tof2 = VL53L0X.VL53L0X(tca9548a_num=2, tca9548a_addr=0x70) +tof1.open() +tof2.open() # Start ranging on TCA9548A bus 1 -tof1.start_ranging(VL53L0X.VL53L0X_BETTER_ACCURACY_MODE) +tof1.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER) # Start ranging on TCA9548A bus 2 -tof2.start_ranging(VL53L0X.VL53L0X_BETTER_ACCURACY_MODE) +tof2.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER) timing = tof1.get_timing() -if (timing < 20000): +if timing < 20000: timing = 20000 -print ("Timing %d ms" % (timing/1000)) +print("Timing %d ms" % (timing/1000)) -for count in range(1,101): +for count in range(1, 101): # Get distance from VL53L0X on TCA9548A bus 1 distance = tof1.get_distance() - if (distance > 0): - print ("1: %d mm, %d cm, %d" % (distance, (distance/10), count)) + if distance > 0: + print("1: %d mm, %d cm, %d" % (distance, (distance/10), count)) # Get distance from VL53L0X on TCA9548A bus 2 distance = tof2.get_distance() - if (distance > 0): - print ("2: %d mm, %d cm, %d" % (distance, (distance/10), count)) + if distance > 0: + print("2: %d mm, %d cm, %d" % (distance, (distance/10), count)) time.sleep(timing/1000000.00) tof1.stop_ranging() tof2.stop_ranging() +tof1.close() +tof2.close() diff --git a/python/VL53L0X_example.py b/python/VL53L0X_example.py index 50631f5..6f99ec2 100755 --- a/python/VL53L0X_example.py +++ b/python/VL53L0X_example.py @@ -27,21 +27,22 @@ # Create a VL53L0X object tof = VL53L0X.VL53L0X() - +tof.open() # Start ranging -tof.start_ranging(VL53L0X.VL53L0X_BETTER_ACCURACY_MODE) +tof.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER) timing = tof.get_timing() -if (timing < 20000): +if timing < 20000: timing = 20000 -print ("Timing %d ms" % (timing/1000)) +print("Timing %d ms" % (timing/1000)) -for count in range(1,101): +for count in range(1, 101): distance = tof.get_distance() - if (distance > 0): - print ("%d mm, %d cm, %d" % (distance, (distance/10), count)) + if distance > 0: + print("%d mm, %d cm, %d" % (distance, (distance/10), count)) time.sleep(timing/1000000.00) tof.stop_ranging() +tof.close() diff --git a/python/VL53L0X_example_livegraph.py b/python/VL53L0X_example_livegraph.py index 9194365..1072442 100755 --- a/python/VL53L0X_example_livegraph.py +++ b/python/VL53L0X_example_livegraph.py @@ -28,12 +28,13 @@ import VL53L0X fig = plt.figure() -ax1 = fig.add_subplot(1,1,1) +ax1 = fig.add_subplot(1, 1, 1) xarr = [] yarr = [] count = 0 + def animate(i): global count distance = tof.get_distance() @@ -42,22 +43,24 @@ def animate(i): yarr.append(distance) time.sleep(timing/1000000.00) ax1.clear() - ax1.plot(xarr,yarr) + ax1.plot(xarr, yarr) + # Create a VL53L0X object tof = VL53L0X.VL53L0X() - +tof.open() # Start ranging -tof.start_ranging(VL53L0X.VL53L0X_BETTER_ACCURACY_MODE) +tof.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER) timing = tof.get_timing() -if (timing < 20000): +if timing < 20000: timing = 20000 -print ("Timing %d ms" % (timing/1000)) +print("Timing %d ms" % (timing/1000)) -print ("Press ctrl-c to exit") +print("Press ctrl-c to exit") ani = animation.FuncAnimation(fig, animate, interval=100) plt.show() tof.stop_ranging() +tof.close() diff --git a/python/VL53L0X_multi_example.py b/python/VL53L0X_multi_example.py index 4f44e42..322a528 100755 --- a/python/VL53L0X_multi_example.py +++ b/python/VL53L0X_multi_example.py @@ -47,38 +47,40 @@ # Create one object per VL53L0X passing the address to give to # each. -tof = VL53L0X.VL53L0X(address=0x2B) -tof1 = VL53L0X.VL53L0X(address=0x2D) +tof = VL53L0X.VL53L0X(i2c_address=0x2B) +tof1 = VL53L0X.VL53L0X(i2c_address=0x2D) +tof.open() +tof1.open() # Set shutdown pin high for the first VL53L0X then # call to start ranging GPIO.output(sensor1_shutdown, GPIO.HIGH) time.sleep(0.50) -tof.start_ranging(VL53L0X.VL53L0X_BETTER_ACCURACY_MODE) +tof.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER) # Set shutdown pin high for the second VL53L0X then # call to start ranging GPIO.output(sensor2_shutdown, GPIO.HIGH) time.sleep(0.50) -tof1.start_ranging(VL53L0X.VL53L0X_BETTER_ACCURACY_MODE) +tof1.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER) timing = tof.get_timing() -if (timing < 20000): +if timing < 20000: timing = 20000 -print ("Timing %d ms" % (timing/1000)) +print("Timing %d ms" % (timing/1000)) for count in range(1,101): distance = tof.get_distance() - if (distance > 0): - print ("sensor %d - %d mm, %d cm, iteration %d" % (tof.my_object_number, distance, (distance/10), count)) + if distance > 0: + print("sensor %d - %d mm, %d cm, iteration %d" % (1, distance, (distance/10), count)) else: - print ("%d - Error" % tof.my_object_number) + print("%d - Error" % 1) distance = tof1.get_distance() - if (distance > 0): - print ("sensor %d - %d mm, %d cm, iteration %d" % (tof1.my_object_number, distance, (distance/10), count)) + if distance > 0: + print("sensor %d - %d mm, %d cm, iteration %d" % (2, distance, (distance/10), count)) else: - print ("%d - Error" % tof.my_object_number) + print("%d - Error" % 2) time.sleep(timing/1000000.00) @@ -87,3 +89,5 @@ tof.stop_ranging() GPIO.output(sensor1_shutdown, GPIO.LOW) +tof.close() +tof1.close() From 1f0e33e8e4c2f17aea50d355aefb2534e4539948 Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Thu, 11 Jan 2018 15:56:29 +1300 Subject: [PATCH 07/13] Update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 331ef7c..1a4dc57 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,9 @@ Notes on using TCA9548A I2C Multiplexer: ### Installation ```bash # Python2 -pip2 install git+https://github.com/johnbryanmoore/VL53L0X_rasp_python.git +pip2 install git+https://github.com/grantramsay/VL53L0X_rasp_python.git # Python3 -pip3 install git+https://github.com/johnbryanmoore/VL53L0X_rasp_python.git +pip3 install git+https://github.com/grantramsay/VL53L0X_rasp_python.git ``` ### Compilation From dbbf88435d133162f806379542e7ba8966076756 Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Thu, 11 Jan 2018 16:32:32 +1300 Subject: [PATCH 08/13] Python 2 compatibility --- python/VL53L0X.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/VL53L0X.py b/python/VL53L0X.py index 4ce529f..ff878c0 100755 --- a/python/VL53L0X.py +++ b/python/VL53L0X.py @@ -157,9 +157,8 @@ def get_timing(self): return 0 def configure_gpio_interrupt( - self, proximity_alarm_type: Vl53l0xGpioAlarmType = Vl53l0xGpioAlarmType.THRESHOLD_CROSSED_LOW, - interrupt_polarity: Vl53l0xInterruptPolarity = Vl53l0xInterruptPolarity.HIGH, - threshold_low_mm: int = 250, threshold_high_mm: int = 500): + self, proximity_alarm_type=Vl53l0xGpioAlarmType.THRESHOLD_CROSSED_LOW, + interrupt_polarity=Vl53l0xInterruptPolarity.HIGH, threshold_low_mm=250, threshold_high_mm=500): """ Configures a GPIO interrupt from device, be sure to call "clear_interrupt" after interrupt is processed. """ From d754b669ce0dae5e6c5f55c9383f6acb346ceddf Mon Sep 17 00:00:00 2001 From: Jonghoon Seo Date: Thu, 16 Aug 2018 11:38:40 +0900 Subject: [PATCH 09/13] Fix library path problem --- README.md | 6 +++--- python/VL53L0X.py | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1a4dc57..cbb7d8e 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,9 @@ Notes on using TCA9548A I2C Multiplexer: ### Installation ```bash # Python2 -pip2 install git+https://github.com/grantramsay/VL53L0X_rasp_python.git +pip2 install git+https://github.com/w4-jonghoon/VL53L0X_rasp_python.git # Python3 -pip3 install git+https://github.com/grantramsay/VL53L0X_rasp_python.git +pip3 install git+https://github.com/w4-jonghoon/VL53L0X_rasp_python.git ``` ### Compilation @@ -54,7 +54,7 @@ sudo apt-get install build-essential python-dev Then use following commands to clone the repository and compile: ```bash cd your_git_directory -git clone https://github.com/johnbryanmoore/VL53L0X_rasp_python.git +git clone https://github.com/w4-jonghoon/VL53L0X_rasp_python.git cd VL53L0X_rasp_python make ``` diff --git a/python/VL53L0X.py b/python/VL53L0X.py index ff878c0..b8b2076 100755 --- a/python/VL53L0X.py +++ b/python/VL53L0X.py @@ -21,9 +21,14 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from ctypes import CDLL, CFUNCTYPE, POINTER, c_int, c_uint, pointer, c_ubyte, c_uint8, c_uint32 -import smbus2 as smbus +import os + +from ctypes import (CDLL, CFUNCTYPE, POINTER, + c_int, c_uint, pointer, c_ubyte, c_uint8, c_uint32) import site +import smbus2 as smbus + +ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) class Vl53l0xError(RuntimeError): @@ -66,7 +71,8 @@ class Vl53l0xInterruptPolarity: _I2C_WRITE_FUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte, POINTER(c_ubyte), c_ubyte) # Load VL53L0X shared lib -_POSSIBLE_LIBRARY_LOCATIONS = ['../bin'] + site.getsitepackages() +_POSSIBLE_LIBRARY_LOCATIONS = ([os.path.join(ROOT_DIR, 'bin/')] + + site.getsitepackages()) for lib_location in _POSSIBLE_LIBRARY_LOCATIONS: try: _TOF_LIBRARY = CDLL(lib_location + "/vl53l0x_python.so") From de8020d131bd3f7eeee197657761812193829bc1 Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Sun, 26 Aug 2018 12:18:22 +1200 Subject: [PATCH 10/13] Simplify finding TOF library --- python/VL53L0X.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/python/VL53L0X.py b/python/VL53L0X.py index b8b2076..d2cea38 100755 --- a/python/VL53L0X.py +++ b/python/VL53L0X.py @@ -22,13 +22,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import os - from ctypes import (CDLL, CFUNCTYPE, POINTER, c_int, c_uint, pointer, c_ubyte, c_uint8, c_uint32) -import site import smbus2 as smbus -ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +THIS_FILE_DIR = os.path.dirname(os.path.abspath(__file__)) class Vl53l0xError(RuntimeError): @@ -71,16 +69,15 @@ class Vl53l0xInterruptPolarity: _I2C_WRITE_FUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte, POINTER(c_ubyte), c_ubyte) # Load VL53L0X shared lib -_POSSIBLE_LIBRARY_LOCATIONS = ([os.path.join(ROOT_DIR, 'bin/')] + - site.getsitepackages()) +# If built locally it will be in bin folder, if installed it will be next to the this file. +_POSSIBLE_LIBRARY_LOCATIONS = [THIS_FILE_DIR, os.path.join(THIS_FILE_DIR, '..', 'bin')] for lib_location in _POSSIBLE_LIBRARY_LOCATIONS: - try: - _TOF_LIBRARY = CDLL(lib_location + "/vl53l0x_python.so") + tof_lib = os.path.join(lib_location, "vl53l0x_python.so") + if os.path.isfile(tof_lib): + _TOF_LIBRARY = CDLL(tof_lib) break - except OSError: - pass else: - raise OSError('Could not find vl53l0x_python.so') + raise FileNotFoundError('Could not find vl53l0x_python.so (have you built it?)') class VL53L0X: From 48ddd64145eb22422f61e55faef9f752e8b90e80 Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Sun, 26 Aug 2018 12:23:05 +1200 Subject: [PATCH 11/13] Tidy inconsistency between TOF lib and ctypes Might cause issue if ever 64bit --- python/VL53L0X.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/VL53L0X.py b/python/VL53L0X.py index d2cea38..c2f21f2 100755 --- a/python/VL53L0X.py +++ b/python/VL53L0X.py @@ -23,7 +23,7 @@ # SOFTWARE. import os from ctypes import (CDLL, CFUNCTYPE, POINTER, - c_int, c_uint, pointer, c_ubyte, c_uint8, c_uint32) + c_int, pointer, c_ubyte, c_uint8, c_uint32) import smbus2 as smbus THIS_FILE_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -151,7 +151,7 @@ def get_distance(self): # This function included to show how to access the ST library directly # from python instead of through the simplified interface def get_timing(self): - budget = c_uint(0) + budget = c_uint32(0) budget_p = pointer(budget) status = _TOF_LIBRARY.VL53L0X_GetMeasurementTimingBudgetMicroSeconds(self._dev, budget_p) if status == 0: From cd54ab3f4d5f31c4dbe1cf5d2354574cfc7804bd Mon Sep 17 00:00:00 2001 From: "Ramsay, Grant (NZ)" Date: Sun, 26 Aug 2018 12:23:32 +1200 Subject: [PATCH 12/13] Tidy gitignore and readme --- .gitignore | 3 +++ README.md | 10 +++++----- setup.py | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 8461078..0c2994a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ build +obj +bin +*.pyc .idea diff --git a/README.md b/README.md index cbb7d8e..7e3f7a6 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,9 @@ Notes on using TCA9548A I2C Multiplexer: ### Installation ```bash # Python2 -pip2 install git+https://github.com/w4-jonghoon/VL53L0X_rasp_python.git +pip2 install git+https://github.com/grantramsay/VL53L0X_rasp_python.git # Python3 -pip3 install git+https://github.com/w4-jonghoon/VL53L0X_rasp_python.git +pip3 install git+https://github.com/grantramsay/VL53L0X_rasp_python.git ``` ### Compilation @@ -54,7 +54,7 @@ sudo apt-get install build-essential python-dev Then use following commands to clone the repository and compile: ```bash cd your_git_directory -git clone https://github.com/w4-jonghoon/VL53L0X_rasp_python.git +git clone https://github.com/grantramsay/VL53L0X_rasp_python.git cd VL53L0X_rasp_python make ``` @@ -69,9 +69,9 @@ VL53L0X_example_livegraph.py - This example plots the distance data from a singl VL53L0X_multi_example.py - This example accesses 2 sensors, setting the first to address 0x2B and the second to address 0x2D. It uses GPIOs 20 and 16 connected to the shutdown pins on the 2 sensors to control sensor activation. -![VL53L0X_multi_example.py Diagram](https://raw.githubusercontent.com/johnbryanmoore/VL53L0X_rasp_python/master/VL53L0X_Mutli_Rpi3_bb.jpg "Fritzing Diagram for VL53L0X_multi_example.py") +![VL53L0X_multi_example.py Diagram](https://raw.githubusercontent.com/grantramsay/VL53L0X_rasp_python/master/VL53L0X_Mutli_Rpi3_bb.jpg "Fritzing Diagram for VL53L0X_multi_example.py") VL53L0X_TCA9548A_example.py - This example accesses 2 sensors through a TCA9548A I2C Multiplexer with the first connected to bus 1 and the second on bus 2 on the TCA9548A. -![VL53L0X_TCA9548A_example.py Diagram](https://raw.githubusercontent.com/johnbryanmoore/VL53L0X_rasp_python/master/VL53L0X_TCA9548A_Rpi3_bb.jpg "Fritzing Diagram for VL53L0X_TCA9548A_example.py") +![VL53L0X_TCA9548A_example.py Diagram](https://raw.githubusercontent.com/grantramsay/VL53L0X_rasp_python/master/VL53L0X_TCA9548A_Rpi3_bb.jpg "Fritzing Diagram for VL53L0X_TCA9548A_example.py") diff --git a/setup.py b/setup.py index 667e60c..09080c7 100644 --- a/setup.py +++ b/setup.py @@ -46,7 +46,7 @@ class CTypesExtension(Extension): description='VL53L0X sensor for raspberry PI', # author='?', # author_email='?', - url='https://github.com/johnbryanmoore/VL53L0X_rasp_python', + url='https://github.com/grantramsay/VL53L0X_rasp_python', long_description=''' VL53L0X sensor for raspberry PI. ''', From b980d55d6fde35ed8b00335b39e9e933024d3bc0 Mon Sep 17 00:00:00 2001 From: Jonghoon Seo Date: Mon, 8 Oct 2018 17:32:30 +0900 Subject: [PATCH 13/13] Call VL53L0X.open() after GPIO goes HIGH --- python/VL53L0X_multi_example.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/VL53L0X_multi_example.py b/python/VL53L0X_multi_example.py index 322a528..436beea 100755 --- a/python/VL53L0X_multi_example.py +++ b/python/VL53L0X_multi_example.py @@ -49,19 +49,19 @@ # each. tof = VL53L0X.VL53L0X(i2c_address=0x2B) tof1 = VL53L0X.VL53L0X(i2c_address=0x2D) -tof.open() -tof1.open() # Set shutdown pin high for the first VL53L0X then # call to start ranging GPIO.output(sensor1_shutdown, GPIO.HIGH) time.sleep(0.50) +tof.open() tof.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER) # Set shutdown pin high for the second VL53L0X then # call to start ranging GPIO.output(sensor2_shutdown, GPIO.HIGH) time.sleep(0.50) +tof1.open() tof1.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER) timing = tof.get_timing()