From d40f87541d61b44033e8fc4687a80ccf5b256f03 Mon Sep 17 00:00:00 2001 From: Murray Taylor Date: Mon, 16 Oct 2023 15:17:21 +1100 Subject: [PATCH 1/8] PiicoDev device presence tests added --- PiicoDev_Unified.py | 385 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 385 insertions(+) diff --git a/PiicoDev_Unified.py b/PiicoDev_Unified.py index b78b819..0202131 100644 --- a/PiicoDev_Unified.py +++ b/PiicoDev_Unified.py @@ -177,3 +177,388 @@ def create_unified_i2c(bus=None, freq=None, sda=None, scl=None, suppress_warning else: i2c = I2CUnifiedMachine(bus=bus, freq=freq, sda=sda, scl=scl) return i2c + + +# +# PiicoDev devices presence tests +# +# Mjt 20231016 +# + +_Debug = 1 # can be chucked out, used to print short WIP messages, and to execute the function tests. + + +class PiicoDev_test(): + """ + # PiicoDev devices presence tests + # + # Mjt 20231016 + + the simple tests without this module + ------------------------------------ + i2c = I2C(id=0) # PiicoDev chain on i2c channel 0 + connected = i2c.scan() # whats connected + print(connected) + for i in connected: + print(i, hex(i)) + + What this module provides + ========================= + Instantiation + ------------- + tests = PiicoDev_test() + + Immediately after this you can display what has been detected on the default i2c bus by either + + print(tests.connected) + or + tests.show() + + these print a list of detected i2c ID's + [16, 60, 82, 83, 119] + + Available functions + ------------------- + clear() - clears the list of connected i2c devices + rescan() - clears and rescans the default i2c bus and repopulates the list + show() - prints the list of connected ID's detected by the original/most recent scan + is_ID_connected(id) - returns 1 if the ID is in the list, otherwise 0 + how_many_connected() - returns count of detected ID's + + details() - prints 'human name' of the connected ID's e.g. 'OLED Module' + details('what') - prints 'human name' of the connected ID's e.g. 'OLED Module' + details('short') - prints 'short_name' of the connected ID's e.g. 'SSD1306' + details('long') - prints 'long_name' of the connected ID's e.g. 'PiicoDev OLED Module SSD1306' + + what_is(id) - prints 'human name' of the connected ID e.g. 'RGB LED Module' + what_is(id, 'what') - prints 'human name' of the connected ID e.g. 'RGB LED Module' + what_is(id, 'short')- prints 'short_name' of the connected ID e.g. 'LED' + what_is(id, 'long') - prints 'long_name' of the connected ID e.g. 'PiicoDev 3x RGB LED Module' + + show_all() - prints all 'human names' from the main internal dictonary + show_all('what') - prints all 'human names' from the main internal dictonary + show_all('short') - prints all 'short names' from the main internal dictonary + show_all('long') - prints all 'long names' from the main internal dictonary + ** with extra option 'show' also displays similar entries from the conflicts dictionary + show_all('what', 'show') - prints all 'human names' from the conflict internal dictonary + show_all('short', show') - prints all 'shout names' from the conflict internal dictonary + show_all('long', 'show') - prints all 'long names' from the conflict internal dictonary + + Address conflicts + ----------------- + Where possible this module will highlight potential conflicts, since some PiicoDev devices + do have addresses that could collide. This can be dealt with by setting the module address switch (ASW) + to a non default setting (if available), OR by programatically changing the device address if possible. + + This module only 'knows' about PiicoDev devices. + + 'Constant' values + ----------------- + Internally there is a set of constant names for the PiicoDev addresses, both the default address, and + if available the alternate address that can be selected by changing the address switch (ASW) + (at this time only one alternate is provided) + + These constants can be used after instantiation in user code + + tests.__BME280_ID # == 0x77 or 119. this is a fixed address + tests.__VEML6030_0_ID # == 0x10 or 16. this is the value when the ASW is OFF + tests.__VEML6030_1_ID # == 0x48 or 72. this is the value is the ASW is ON + + """ + + # + # declare "CONSTANTS" + # these are used to uniquely identify the various (conflicting) PiicoDev addresses + # can use outside the class if prefixed with instantiated classname + # i.e. + # tests = PiicoDev_test() + # if tests.is_ID_connected(tests.__BME280_ID): + # print('have BME280') + + # + __LED_ID = 0x8 # 8. RGB LEDS + # ------ + __VEML6030_0_ID = 0x10 # 16. xx Light sensor (ASW off) + __VEML6040_ID = 0x10 # 16. xx Colour sensor + # ------ + __LIS3DH_1_ID = 0x18 # 24. Accelerometer - ASW ON + __LIS3DH_0_ID = 0x19 # 25. Accelerometer - ASW OFF + __TRANSCEIVER_ID = 0x1a # 26. Transceiver + __QMC6310_ID = 0x1c # 28. Magnetometer + __TOUCH_ID = 0x28 # 40. Capacitive sensor + __VL53L1X_ID = 0x29 # 41. Laser distance sensor + __RFID_ID = 0x2c # 44. RFID module + # ------ + __ULTRASONIC_ID = 0x35 # 53. xx Ultrasonic rangefinder + __POTENTIOMETER_ID = 0x35 # 53. xx Potentiometer + # ------ + __SSD1306_ID = 0x3c # 60. OLED display + __BUTTON_ID = 0x42 # 66. Pushbutton + __SERVO_ID = 0x44 # 68. Servo controller + # ------ + __TMP117_ID = 0x48 # 72. xx Temperature sensor + __VEML6030_1_ID = 0x48 # 72. xx Light sensor (ASW on) + # ------ + __RV3028_ID = 0x52 # 82. xx RTC + __ENS160_1_ID = 0x52 # 82. xx Air quality sensor (ASW on) + # ------ + __ENS160_0_ID = 0x53 # 83. Air quality sensor (ASW off) + __BUZZER_ID = 0x5c # 92. Buzzer + __MS5637_ID = 0x76 # 118. Pressuure sensor + __BME280_ID = 0x77 # 119. Atmospheric sensor + + ################ + ## the MAIN list + ################ + # the dictionary of the fixed, and where possible the default (ASW off) ID's + # also has some non-conflicting (ASW on) ID's + PiicoDev_list: dict = { + __LED_ID: { # 8. 0x8 + 'what': 'RGB LED Module', + 'long_name': 'PiicoDev 3x RGB LED Module', + 'short_name': 'LED'}, + __VEML6040_ID: { # 16. 0x10 + 'what': 'Colour Sensor', + 'long_name': 'PiicoDev VEML6030 Colour Sensor', + 'short_name': 'VEML6040'}, + __LIS3DH_1_ID: { # 24. 0x18 + 'what': 'Accelerometer (ASW on)', + 'long_name': 'PiicoDev 3-Axis Accelerometer LIS3DH (ASW on)', + 'short_name': 'LIS3DH (ASW on)'}, + __LIS3DH_0_ID: { # 25. 0x19 + 'what': 'Accelerometer (ASW off)', + 'long_name': 'PiicoDev 3-Axis Accelerometer LIS3DH (ASW off)', + 'short_name': 'LIS3DH (ASW off)'}, + __TRANSCEIVER_ID: { # 26. 0x1A + 'what': 'Transceiver', + 'long_name': 'PiicoDev Transceiver 915MHz', + 'short_name': 'TRANSCEIVER'}, + __QMC6310_ID: { # 28. 0x1c + 'what': 'Magnetometer', + 'long_name': 'PiicoDev Magnetometer QMC6310', + 'short_name': 'QMC6310'}, + __TOUCH_ID: { # 40. 0x28 + 'what': 'Capacitive Touch Sensor', + 'long_name': 'PiicoDev Capacitive Touch Sensor', + 'short_name': 'TOUCH'}, + __VL53L1X_ID: { # 41. 0x29 + 'what': 'Laser Distance Sensor', + 'long_name': 'PiicoDev Laser Distance Sensor VL53L1X', + 'short_name': 'VL53L1X'}, + __RFID_ID: { # 45. 0x2c + 'what': 'RFID Module', + 'long_name': 'PiicoDev RFID Module (NFC 13.56MHz)', + 'short_name': 'RFID'}, + __ULTRASONIC_ID: { # 53. 0x35 + 'what': 'Ultrasonic Rangefinder', + 'long_name': 'PiicoDev Ultrasonic Rangefinder Module', + 'short_name': 'ULTRASONIC'}, + __SSD1306_ID: { # 60. 0x3c + 'what': 'OLED Module', + 'long_name': 'PiicoDev OLED Module SSD1306', + 'short_name': 'SSD1306', + 'initme': 'create_PiicoDev_SSD1306()'}, + __BUTTON_ID: { # 66. 0x42 + 'what': 'Button', + 'long_name': 'PiicoDev Button', + 'short_name': 'BUTTON'}, + __SERVO_ID: { # 68. 0x44 + 'what': 'Servo Driver', + 'long_name': 'PiicoDev Servo Driver (4 Channel)', + 'short_name': 'SERVO'}, + __TMP117_ID: { # 72. 0x48 + 'what': 'Precision Temperature Sensor', + 'long_name': 'PiicoDev TMP117 Precision Temperature Sensor', + 'short_name': 'TMP117'}, + __RV3028_ID: { # 82. 0x52 + 'what': 'Real Time Clock', + 'long_name': 'PiicoDev Real Time Clock (RTC) RV3028', + 'short_name': 'RV3028'}, + __ENS160_0_ID: { # 83. 0x53 + 'what': 'Air Quality Sensor (ASW off)', + 'long_name': 'PiicoDev Air Quality Sensor ENS160 (ASW off)', + 'short_name': 'ENS160 (ASW off)'}, + __BUZZER_ID: { # 92. 0x5c + 'what': 'Buzzer Module', + 'long_name': 'PiicoDev Buzzer Module', + 'short_name': 'BUZZER'}, + __MS5637_ID: { # 118. 0x76 + 'what': 'Pressure Sensor', + 'long_name': 'PiicoDev Pressure Sensor MS5637', + 'short_name': 'MS5637'}, + __BME280_ID: { # 119. 0x77 + 'what': 'Atmospheric Sensor', + 'long_name': 'PiicoDev BME280 Atmospheric Sensor', + 'short_name': 'BME280'}, + } + + ##################### + ## the conflicts list + ##################### + # the dictionary of the conflicting fixed, and conflicting (ASW on) ID's + # also has some conflicting (ASW off) ID's + PiicoDev_conf_list: dict = { + __VEML6030_0_ID: { # 16. 0x10 + 'what': 'Ambient Light Sensor (ASW off)', + 'long_name': 'PiicoDev VEML6030 Ambient Light Sensor (ASW off)', + 'short_name': 'VEML6030 (ASW off)'}, + __POTENTIOMETER_ID: { # 53. 0x35 + 'what': 'Potentiometer', + 'long_name': 'PiicoDev Potentiometer (Rotary)', + 'short_name': 'Potentiometer'}, + __VEML6030_1_ID: { # 72. 0x48 + 'what': 'Ambient Light Sensor (ASW on)', + 'long_name': 'PiicoDev VEML6030 Ambient Light Sensor (ASW on)', + 'short_name': 'VEML6030 (ASW on)'}, + __ENS160_1_ID: { # 82. 0x52 + 'what': 'Air Quality Sensor (ASW on)', + 'long_name': 'PiicoDev Air Quality Sensor ENS160 (ASW on)', + 'short_name': 'ENS160 (ASW on)'}, + } + + + def __init__(self): + self.i2c = I2C(id=0) + self.connected = self.i2c.scan() + + def clear(self): + self.connected = [] + + def rescan(self): + self.connected = [] + self.connected = self.i2c.scan() + + def show(self): + print(self.connected) + + def is_ID_connected(self, id): + if _Debug == 1: + print('is_ID_connected(',id,')') + if self.connected.count(id) == 1: + return(1) + else: + return(0) + + def how_many_connected(self): + if _Debug == 1: + print('how_many__connected()') + return(len(self.connected)) + + def details(self, mode='what'): + if _Debug == 1: + print('details(',mode,')') + if len(self.connected) == 0: + print('nothing connected') + else: + for i in self.connected: + hit = 0 + if i in self.PiicoDev_list: + if mode == 'long': + s = self.PiicoDev_list[i]['long_name'] + elif mode == 'short': + s = self.PiicoDev_list[i]['short_name'] + else: # assume 'what' + s = self.PiicoDev_list[i]['what'] + print(i, hex(i), s) + hit = 1 + if i in self.PiicoDev_conf_list: + if mode == 'long': + s = self.PiicoDev_conf_list[i]['long_name'] + elif mode == 'short': + s = self.PiicoDev_conf_list[i]['short_name'] + else: # assume 'what' + s = self.PiicoDev_conf_list[i]['what'] + print(i, hex(i), s, '<<<<< Possible conflict') + hit = 1 + if hit == 0: + print('Unknown device at ID ', i) + + def what_is(self, id, mode='what'): + hit = 0 + if id in self.PiicoDev_list: + if mode == 'long': + s = self.PiicoDev_list[id]['long_name'] + elif mode == 'short': + s = self.PiicoDev_list[id]['short_name'] + else: # assume 'what' + s = self.PiicoDev_list[id]['what'] + print('Found:', id, hex(id), s) + hit = 1 + if id in self.PiicoDev_conf_list: + if mode == 'long': + s = self.PiicoDev_conf_list[id]['long_name'] + elif mode == 'short': + s = self.PiicoDev_conf_list[id]['short_name'] + else: # assume 'what' + s = self.PiicoDev_conf_list[id]['what'] + print('Found but possible conflict:', id, hex(id), s) + hit = 1 + if hit == 0: + print('Unknown ID ', id) + + def show_all(self, mode='what', conf='noshow' ): + for i in sorted(self.PiicoDev_list): + if mode == 'long': + print(i, hex(i), self.PiicoDev_list[i]['long_name']) + elif mode == 'short': + print(i, hex(i), self.PiicoDev_list[i]['short_name']) + else: # assume 'what' + print(i, hex(i), self.PiicoDev_list[i]['what']) + if conf != 'noshow': + print('-- conflicting --') + for i in sorted(self.PiicoDev_conf_list): + if mode == 'long': + print(i, hex(i), self.PiicoDev_conf_list[i]['long_name']) + elif mode == 'short': + print(i, hex(i), self.PiicoDev_conf_list[i]['short_name']) + else: # assume 'what' + print(i, hex(i), self.PiicoDev_conf_list[i]['what']) + +# end of class + +if _Debug: + tests = PiicoDev_test() + + print('tests.connected') + print(tests.connected) + print('clear()') + tests.clear() + print(tests.connected) + print('rescan()') + tests.rescan() + print(tests.connected) + print('show()') + tests.show() + print('how many') + aa = tests.how_many_connected() + print(aa) + print('details()') + tests.details() + tests.details('short') + tests.details('long') + + aa = tests.is_ID_connected(119) + print(aa) + + aa = tests.is_ID_connected(0x77) + print(aa) + + if tests.is_ID_connected(tests.__BME280_ID): + print('have BME280') + + if tests.is_ID_connected(tests.__POTENTIOMETER_ID): + print('have Ultrasonic rangfinder - cant distinguish conflicting IDs') + else: + print('oops') + + tests.what_is(0xff) # no such ID, will complain + + tests.what_is(53, 'long') + + tests.show_all() + + tests.show_all('long','show') + + print('***************************************************') + + From 24dd422f8f2477daea327185948ec70e8bad7032 Mon Sep 17 00:00:00 2001 From: Murray Taylor Date: Mon, 16 Oct 2023 18:55:31 +1100 Subject: [PATCH 2/8] Cleaned up documentation --- PiicoDev_Unified.py | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/PiicoDev_Unified.py b/PiicoDev_Unified.py index 0202131..a61d88a 100644 --- a/PiicoDev_Unified.py +++ b/PiicoDev_Unified.py @@ -219,30 +219,30 @@ class PiicoDev_test(): Available functions ------------------- - clear() - clears the list of connected i2c devices - rescan() - clears and rescans the default i2c bus and repopulates the list - show() - prints the list of connected ID's detected by the original/most recent scan - is_ID_connected(id) - returns 1 if the ID is in the list, otherwise 0 - how_many_connected() - returns count of detected ID's + clear() - clears the list of connected i2c devices + rescan() - clears and rescans the default i2c bus and repopulates the list + show() - prints the list of connected ID's detected by the original/most recent scan + is_ID_connected(id) - returns 1 if the ID is in the list, otherwise 0 + how_many_connected() - returns count of detected ID's - details() - prints 'human name' of the connected ID's e.g. 'OLED Module' - details('what') - prints 'human name' of the connected ID's e.g. 'OLED Module' - details('short') - prints 'short_name' of the connected ID's e.g. 'SSD1306' - details('long') - prints 'long_name' of the connected ID's e.g. 'PiicoDev OLED Module SSD1306' + details() - prints 'human name' of the connected ID's e.g. 'OLED Module' + details('what') - prints 'human name' of the connected ID's e.g. 'OLED Module' + details('short') - prints 'short_name' of the connected ID's e.g. 'SSD1306' + details('long') - prints 'long_name' of the connected ID's e.g. 'PiicoDev OLED Module SSD1306' - what_is(id) - prints 'human name' of the connected ID e.g. 'RGB LED Module' - what_is(id, 'what') - prints 'human name' of the connected ID e.g. 'RGB LED Module' - what_is(id, 'short')- prints 'short_name' of the connected ID e.g. 'LED' - what_is(id, 'long') - prints 'long_name' of the connected ID e.g. 'PiicoDev 3x RGB LED Module' + what_is(id) - prints 'human name' of the given ID e.g. 'RGB LED Module' + what_is(id, 'what') - prints 'human name' of the given ID e.g. 'RGB LED Module' + what_is(id, 'short')- prints 'short_name' of the given ID e.g. 'LED' + what_is(id, 'long') - prints 'long_name' of the given ID e.g. 'PiicoDev 3x RGB LED Module' - show_all() - prints all 'human names' from the main internal dictonary - show_all('what') - prints all 'human names' from the main internal dictonary - show_all('short') - prints all 'short names' from the main internal dictonary - show_all('long') - prints all 'long names' from the main internal dictonary + show_all() - prints all 'human names' from the main internal dictonary + show_all('what') - prints all 'human names' from the main internal dictonary + show_all('short') - prints all 'short names' from the main internal dictonary + show_all('long') - prints all 'long names' from the main internal dictonary ** with extra option 'show' also displays similar entries from the conflicts dictionary - show_all('what', 'show') - prints all 'human names' from the conflict internal dictonary - show_all('short', show') - prints all 'shout names' from the conflict internal dictonary - show_all('long', 'show') - prints all 'long names' from the conflict internal dictonary + show_all('what', 'show') - prints all 'human names' from the conflict internal dictonary + show_all('short', show') - prints all 'shout names' from the conflict internal dictonary + show_all('long', 'show') - prints all 'long names' from the conflict internal dictonary Address conflicts ----------------- @@ -260,9 +260,9 @@ class PiicoDev_test(): These constants can be used after instantiation in user code - tests.__BME280_ID # == 0x77 or 119. this is a fixed address - tests.__VEML6030_0_ID # == 0x10 or 16. this is the value when the ASW is OFF - tests.__VEML6030_1_ID # == 0x48 or 72. this is the value is the ASW is ON + tests.__BME280_ID # == 0x77 or 119. this is a fixed address + tests.__VEML6030_0_ID # == 0x10 or 16. this is the value when the ASW is OFF + tests.__VEML6030_1_ID # == 0x48 or 72. this is the value is the ASW is ON """ From 062220d5482257e9cdb1abf153e6057f4e645151 Mon Sep 17 00:00:00 2001 From: Murray Taylor Date: Tue, 17 Oct 2023 10:28:15 +1100 Subject: [PATCH 3/8] Added show_hex() function --- PiicoDev_Unified.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/PiicoDev_Unified.py b/PiicoDev_Unified.py index a61d88a..b6f09c1 100644 --- a/PiicoDev_Unified.py +++ b/PiicoDev_Unified.py @@ -221,7 +221,8 @@ class PiicoDev_test(): ------------------- clear() - clears the list of connected i2c devices rescan() - clears and rescans the default i2c bus and repopulates the list - show() - prints the list of connected ID's detected by the original/most recent scan + show_int() - prints the list of connected ID's in DECIMAL detected by the original/most recent scan + show_hex() - prints the list of connected ID's in HEXADECIMAL detected by the original/most recent scan is_ID_connected(id) - returns 1 if the ID is in the list, otherwise 0 how_many_connected() - returns count of detected ID's @@ -428,9 +429,12 @@ def rescan(self): self.connected = [] self.connected = self.i2c.scan() - def show(self): + def show_int(self): print(self.connected) + def show_hex(self): + print( [hex(i) for i in self.connected] ) + def is_ID_connected(self, id): if _Debug == 1: print('is_ID_connected(',id,')') @@ -528,7 +532,8 @@ def show_all(self, mode='what', conf='noshow' ): tests.rescan() print(tests.connected) print('show()') - tests.show() + tests.show_int() + tests.show_hex() print('how many') aa = tests.how_many_connected() print(aa) From ef58217aae65867eba61123a73de40ba372ce057 Mon Sep 17 00:00:00 2001 From: Murray Taylor Date: Wed, 18 Oct 2023 11:18:51 +1100 Subject: [PATCH 4/8] Changed __init__ to allow alternate i2c bus setup --- PiicoDev_Unified.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/PiicoDev_Unified.py b/PiicoDev_Unified.py index b6f09c1..593787f 100644 --- a/PiicoDev_Unified.py +++ b/PiicoDev_Unified.py @@ -278,10 +278,10 @@ class PiicoDev_test(): # __LED_ID = 0x8 # 8. RGB LEDS - # ------ + # ----vv __VEML6030_0_ID = 0x10 # 16. xx Light sensor (ASW off) __VEML6040_ID = 0x10 # 16. xx Colour sensor - # ------ + # ----^^ __LIS3DH_1_ID = 0x18 # 24. Accelerometer - ASW ON __LIS3DH_0_ID = 0x19 # 25. Accelerometer - ASW OFF __TRANSCEIVER_ID = 0x1a # 26. Transceiver @@ -289,20 +289,21 @@ class PiicoDev_test(): __TOUCH_ID = 0x28 # 40. Capacitive sensor __VL53L1X_ID = 0x29 # 41. Laser distance sensor __RFID_ID = 0x2c # 44. RFID module - # ------ + # ----vv __ULTRASONIC_ID = 0x35 # 53. xx Ultrasonic rangefinder - __POTENTIOMETER_ID = 0x35 # 53. xx Potentiometer - # ------ + __POTENTIOMETER_ID = 0x35 # 53. xx Potentiometer + # ----^^ __SSD1306_ID = 0x3c # 60. OLED display __BUTTON_ID = 0x42 # 66. Pushbutton __SERVO_ID = 0x44 # 68. Servo controller - # ------ + # ----vv __TMP117_ID = 0x48 # 72. xx Temperature sensor __VEML6030_1_ID = 0x48 # 72. xx Light sensor (ASW on) - # ------ + # ----^^ + # ----vv __RV3028_ID = 0x52 # 82. xx RTC __ENS160_1_ID = 0x52 # 82. xx Air quality sensor (ASW on) - # ------ + # ----^^ __ENS160_0_ID = 0x53 # 83. Air quality sensor (ASW off) __BUZZER_ID = 0x5c # 92. Buzzer __MS5637_ID = 0x76 # 118. Pressuure sensor @@ -418,8 +419,12 @@ class PiicoDev_test(): } - def __init__(self): - self.i2c = I2C(id=0) + # + # PiicoDev defaults pre-defined + # can be overloaded with other values if needed to establish a second/alternate i2c bus + # + def __init__(self, id=0, scl=Pin(9), sda=Pin(8), freq=400_000): + self.i2c = I2C(id=id, scl=scl, sda=sda, freq=freq) self.connected = self.i2c.scan() def clear(self): @@ -523,6 +528,9 @@ def show_all(self, mode='what', conf='noshow' ): if _Debug: tests = PiicoDev_test() + # for an alternate i2c bus on GPIO6 and GPOI7 + test_altbus = PiicoDev_test(id=1, scl=Pin(7), sda=Pin(6)) + print('tests.connected') print(tests.connected) print('clear()') From eaa0eec5dcae9ccf20effb7fedd7f3da42422b19 Mon Sep 17 00:00:00 2001 From: Murray Taylor Date: Wed, 18 Oct 2023 17:31:06 +1100 Subject: [PATCH 5/8] More text in PiicoDev_test class intro comments --- PiicoDev_Unified.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/PiicoDev_Unified.py b/PiicoDev_Unified.py index 593787f..6f02fbb 100644 --- a/PiicoDev_Unified.py +++ b/PiicoDev_Unified.py @@ -206,7 +206,12 @@ class PiicoDev_test(): ========================= Instantiation ------------- + # the default for standard PiicoDev setup tests = PiicoDev_test() + OR + # for an alternate i2c bus on GPIO6 and GPOI7 + test_altbus = PiicoDev_test(id=1, scl=Pin(7), sda=Pin(6)) + Immediately after this you can display what has been detected on the default i2c bus by either @@ -265,19 +270,29 @@ class PiicoDev_test(): tests.__VEML6030_0_ID # == 0x10 or 16. this is the value when the ASW is OFF tests.__VEML6030_1_ID # == 0x48 or 72. this is the value is the ASW is ON + NOTE: ============================================================================= + NOTE: + NOTE: The "Constants" and the __TWO__ dictionary lists MUST be checked / updated + NOTE: when new PiicoDev devices are created by Core Electronics + NOTE: sorry team ;-) + NOTE: + NOTE: ============================================================================= """ # # declare "CONSTANTS" # these are used to uniquely identify the various (conflicting) PiicoDev addresses + # note the 'conflict' markers ----vv and ----^^ + # # can use outside the class if prefixed with instantiated classname # i.e. + # # tests = PiicoDev_test() # if tests.is_ID_connected(tests.__BME280_ID): # print('have BME280') - # - __LED_ID = 0x8 # 8. RGB LEDS + + __LED_ID = 0x8 # 8. RGB LEDS # ----vv __VEML6030_0_ID = 0x10 # 16. xx Light sensor (ASW off) __VEML6040_ID = 0x10 # 16. xx Colour sensor From 645220ff55b5b8192a3f35e5c8ed95723f071771 Mon Sep 17 00:00:00 2001 From: Murray Taylor Date: Fri, 20 Oct 2023 16:26:41 +1100 Subject: [PATCH 6/8] details() fn can now access external device dictionary, moved duplicate print actions into common fns --- PiicoDev_Unified.py | 153 +++++++++++++++++++++++++++++++------------- 1 file changed, 108 insertions(+), 45 deletions(-) diff --git a/PiicoDev_Unified.py b/PiicoDev_Unified.py index 6f02fbb..7938711 100644 --- a/PiicoDev_Unified.py +++ b/PiicoDev_Unified.py @@ -185,7 +185,7 @@ def create_unified_i2c(bus=None, freq=None, sda=None, scl=None, suppress_warning # Mjt 20231016 # -_Debug = 1 # can be chucked out, used to print short WIP messages, and to execute the function tests. +_Debug = 0 # can be chucked out, used to print short WIP messages, and to execute the function tests. class PiicoDev_test(): @@ -235,7 +235,28 @@ class PiicoDev_test(): details('what') - prints 'human name' of the connected ID's e.g. 'OLED Module' details('short') - prints 'short_name' of the connected ID's e.g. 'SSD1306' details('long') - prints 'long_name' of the connected ID's e.g. 'PiicoDev OLED Module SSD1306' - + ***** + The details() function can also access a user defined dictionary of devices from other manufacturers. + The user dictionary MUST be in the same format as the internal dictionaries + + extern_list: dict = { + 0x53: { # 16. 0x10 + 'what': 'Ambient Light-UV Sensor', + 'long_name': 'Adafruit LTR390 Ambient Light-UV Sensor', + 'short_name': 'LTR390'}, + : { # possible comment + 'what': 'simple description', + 'long_name': 'lengthy description', + 'short_name': 'MFR code'}, + } + + then calliing the details() function as below _AFTER_ the user dictionary is defined, will + display this if the LTR390 is in the connected devices list + + details('what', extern_list ) - prints 'human name' of the connected ID's e.g. 'Ambient Light-UV Sensor' + details('short', extern_list) - prints 'short_name' of the connected ID's e.g. 'LTR390' + details('long', extern_list) - prints 'long_name' of the connected ID's e.g. 'Adafruit LTR390 Ambient Light-UV Sensor' + what_is(id) - prints 'human name' of the given ID e.g. 'RGB LED Module' what_is(id, 'what') - prints 'human name' of the given ID e.g. 'RGB LED Module' what_is(id, 'short')- prints 'short_name' of the given ID e.g. 'LED' @@ -336,7 +357,7 @@ class PiicoDev_test(): 'short_name': 'LED'}, __VEML6040_ID: { # 16. 0x10 'what': 'Colour Sensor', - 'long_name': 'PiicoDev VEML6030 Colour Sensor', + 'long_name': 'PiicoDev VEML6040 Colour Sensor', 'short_name': 'VEML6040'}, __LIS3DH_1_ID: { # 24. 0x18 'what': 'Accelerometer (ASW on)', @@ -468,7 +489,7 @@ def how_many_connected(self): print('how_many__connected()') return(len(self.connected)) - def details(self, mode='what'): + def details(self, mode='what', extlist=None): if _Debug == 1: print('details(',mode,')') if len(self.connected) == 0: @@ -477,67 +498,107 @@ def details(self, mode='what'): for i in self.connected: hit = 0 if i in self.PiicoDev_list: - if mode == 'long': - s = self.PiicoDev_list[i]['long_name'] - elif mode == 'short': - s = self.PiicoDev_list[i]['short_name'] - else: # assume 'what' - s = self.PiicoDev_list[i]['what'] - print(i, hex(i), s) + self.print_main(i, mode) +# if mode == 'long': +# s = self.PiicoDev_list[i]['long_name'] +# elif mode == 'short': +# s = self.PiicoDev_list[i]['short_name'] +# else: # assume 'what' +# s = self.PiicoDev_list[i]['what'] +# print(i, hex(i), s) hit = 1 if i in self.PiicoDev_conf_list: - if mode == 'long': - s = self.PiicoDev_conf_list[i]['long_name'] - elif mode == 'short': - s = self.PiicoDev_conf_list[i]['short_name'] - else: # assume 'what' - s = self.PiicoDev_conf_list[i]['what'] - print(i, hex(i), s, '<<<<< Possible conflict') + print(' vvv Possible conflict vvv') + self.print_conf(i, mode) +# if mode == 'long': +# s = self.PiicoDev_conf_list[i]['long_name'] +# elif mode == 'short': +# s = self.PiicoDev_conf_list[i]['short_name'] +# else: # assume 'what' +# s = self.PiicoDev_conf_list[i]['what'] +# print(i, hex(i), s, '<<<<< Possible conflict') hit = 1 + if extlist != None: + if i in extlist: + print(' vvv EXTERNAL LIST --- Possible conflict vvv') + if mode == 'long': + s = extlist[i]['long_name'] + elif mode == 'short': + s = extlist[i]['short_name'] + else: # assume 'what' + s = extlist[i]['what'] + print(i, hex(i), s) + hit = 1 if hit == 0: print('Unknown device at ID ', i) def what_is(self, id, mode='what'): hit = 0 if id in self.PiicoDev_list: - if mode == 'long': - s = self.PiicoDev_list[id]['long_name'] - elif mode == 'short': - s = self.PiicoDev_list[id]['short_name'] - else: # assume 'what' - s = self.PiicoDev_list[id]['what'] - print('Found:', id, hex(id), s) + self.print_main(id, mode) +# if mode == 'long': +# s = self.PiicoDev_list[id]['long_name'] +# elif mode == 'short': +# s = self.PiicoDev_list[id]['short_name'] +# else: # assume 'what' +# s = self.PiicoDev_list[id]['what'] +# print('Found:', id, hex(id), s) hit = 1 if id in self.PiicoDev_conf_list: - if mode == 'long': - s = self.PiicoDev_conf_list[id]['long_name'] - elif mode == 'short': - s = self.PiicoDev_conf_list[id]['short_name'] - else: # assume 'what' - s = self.PiicoDev_conf_list[id]['what'] - print('Found but possible conflict:', id, hex(id), s) + print(' vvv Possible conflict vvv') + self.print_conf(id, mode) +# if mode == 'long': +# s = self.PiicoDev_conf_list[id]['long_name'] +# elif mode == 'short': +# s = self.PiicoDev_conf_list[id]['short_name'] +# else: # assume 'what' +# s = self.PiicoDev_conf_list[id]['what'] +# print('Found but possible conflict:', id, hex(id), s) hit = 1 if hit == 0: print('Unknown ID ', id) def show_all(self, mode='what', conf='noshow' ): for i in sorted(self.PiicoDev_list): - if mode == 'long': - print(i, hex(i), self.PiicoDev_list[i]['long_name']) - elif mode == 'short': - print(i, hex(i), self.PiicoDev_list[i]['short_name']) - else: # assume 'what' - print(i, hex(i), self.PiicoDev_list[i]['what']) + self.print_main(i, mode) +# if mode == 'long': +# print(i, hex(i), self.PiicoDev_list[i]['long_name']) +# elif mode == 'short': +# print(i, hex(i), self.PiicoDev_list[i]['short_name']) +# else: # assume 'what' +# print(i, hex(i), self.PiicoDev_list[i]['what']) if conf != 'noshow': print('-- conflicting --') for i in sorted(self.PiicoDev_conf_list): - if mode == 'long': - print(i, hex(i), self.PiicoDev_conf_list[i]['long_name']) - elif mode == 'short': - print(i, hex(i), self.PiicoDev_conf_list[i]['short_name']) - else: # assume 'what' - print(i, hex(i), self.PiicoDev_conf_list[i]['what']) + self.print_conf(i, mode) +# if mode == 'long': +# print(i, hex(i), self.PiicoDev_conf_list[i]['long_name']) +# elif mode == 'short': +# print(i, hex(i), self.PiicoDev_conf_list[i]['short_name']) +# else: # assume 'what' +# print(i, hex(i), self.PiicoDev_conf_list[i]['what']) +# +# Print common functions +# + def print_main(self, id, mode): + if mode == 'long': + s = self.PiicoDev_list[id]['long_name'] + elif mode == 'short': + s = self.PiicoDev_list[id]['short_name'] + else: # assume 'what' + s = self.PiicoDev_list[id]['what'] + print(id, hex(id), s) + + def print_conf(self, id, mode): + if mode == 'long': + s = self.PiicoDev_conf_list[id]['long_name'] + elif mode == 'short': + s = self.PiicoDev_conf_list[id]['short_name'] + else: # assume 'what' + s = self.PiicoDev_conf_list[id]['what'] + print(id, hex(id), s) + # end of class if _Debug: @@ -564,7 +625,9 @@ def show_all(self, mode='what', conf='noshow' ): tests.details() tests.details('short') tests.details('long') - + print('************') + tests.details('what', extern_list) + print('************') aa = tests.is_ID_connected(119) print(aa) From ccdadf9bf1524b41a056f43ef368cb98aca26f39 Mon Sep 17 00:00:00 2001 From: Murray Taylor Date: Fri, 20 Oct 2023 18:45:23 +1100 Subject: [PATCH 7/8] comment cleanup, marked internally as v 1.0 --- PiicoDev_Unified.py | 116 +++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 77 deletions(-) diff --git a/PiicoDev_Unified.py b/PiicoDev_Unified.py index 7938711..2f1a467 100644 --- a/PiicoDev_Unified.py +++ b/PiicoDev_Unified.py @@ -178,29 +178,26 @@ def create_unified_i2c(bus=None, freq=None, sda=None, scl=None, suppress_warning i2c = I2CUnifiedMachine(bus=bus, freq=freq, sda=sda, scl=scl) return i2c - +###################################### # # PiicoDev devices presence tests # -# Mjt 20231016 -# _Debug = 0 # can be chucked out, used to print short WIP messages, and to execute the function tests. class PiicoDev_test(): """ - # PiicoDev devices presence tests - # - # Mjt 20231016 + PiicoDev devices presence tests + Murray T 20231020 (v 1.0) the simple tests without this module ------------------------------------ i2c = I2C(id=0) # PiicoDev chain on i2c channel 0 connected = i2c.scan() # whats connected - print(connected) - for i in connected: - print(i, hex(i)) + print(connected) # prints decimal list + for i in connected: # prints hexadecimal list + print(i, hex(i)) # / What this module provides ========================= @@ -211,15 +208,14 @@ class PiicoDev_test(): OR # for an alternate i2c bus on GPIO6 and GPOI7 test_altbus = PiicoDev_test(id=1, scl=Pin(7), sda=Pin(6)) - Immediately after this you can display what has been detected on the default i2c bus by either print(tests.connected) or - tests.show() + tests.show_int() - these print a list of detected i2c ID's + these print a list of detected i2c ID's in decimal [16, 60, 82, 83, 119] Available functions @@ -231,7 +227,7 @@ class PiicoDev_test(): is_ID_connected(id) - returns 1 if the ID is in the list, otherwise 0 how_many_connected() - returns count of detected ID's - details() - prints 'human name' of the connected ID's e.g. 'OLED Module' + details() - prints 'human name' of the connected ID's e.g. 'OLED Module' (default is 'what') details('what') - prints 'human name' of the connected ID's e.g. 'OLED Module' details('short') - prints 'short_name' of the connected ID's e.g. 'SSD1306' details('long') - prints 'long_name' of the connected ID's e.g. 'PiicoDev OLED Module SSD1306' @@ -250,19 +246,19 @@ class PiicoDev_test(): 'short_name': 'MFR code'}, } - then calliing the details() function as below _AFTER_ the user dictionary is defined, will + then calling the details() function as below _AFTER_ the user dictionary is defined, will display this if the LTR390 is in the connected devices list details('what', extern_list ) - prints 'human name' of the connected ID's e.g. 'Ambient Light-UV Sensor' details('short', extern_list) - prints 'short_name' of the connected ID's e.g. 'LTR390' details('long', extern_list) - prints 'long_name' of the connected ID's e.g. 'Adafruit LTR390 Ambient Light-UV Sensor' - what_is(id) - prints 'human name' of the given ID e.g. 'RGB LED Module' + what_is(id) - prints 'human name' of the given ID e.g. 'RGB LED Module' (default is 'what') what_is(id, 'what') - prints 'human name' of the given ID e.g. 'RGB LED Module' what_is(id, 'short')- prints 'short_name' of the given ID e.g. 'LED' what_is(id, 'long') - prints 'long_name' of the given ID e.g. 'PiicoDev 3x RGB LED Module' - show_all() - prints all 'human names' from the main internal dictonary + show_all() - prints all 'human names' from the main internal dictonary (default is 'what') show_all('what') - prints all 'human names' from the main internal dictonary show_all('short') - prints all 'short names' from the main internal dictonary show_all('long') - prints all 'long names' from the main internal dictonary @@ -273,11 +269,13 @@ class PiicoDev_test(): Address conflicts ----------------- - Where possible this module will highlight potential conflicts, since some PiicoDev devices + Where appropriate this module will provide information about potential conflicts, since some PiicoDev devices do have addresses that could collide. This can be dealt with by setting the module address switch (ASW) to a non default setting (if available), OR by programatically changing the device address if possible. - This module only 'knows' about PiicoDev devices. + This module only 'knows' about PiicoDev devices, however an external dictionary can be provided by the user. + + ** The module CANNOT detect an actual address conflict on a given i2c bus. This is a characteristic of the bus itself. 'Constant' values ----------------- @@ -285,11 +283,15 @@ class PiicoDev_test(): if available the alternate address that can be selected by changing the address switch (ASW) (at this time only one alternate is provided) - These constants can be used after instantiation in user code + These constants can be used after instantiation in user code if prefixed with instantiated classname tests.__BME280_ID # == 0x77 or 119. this is a fixed address tests.__VEML6030_0_ID # == 0x10 or 16. this is the value when the ASW is OFF tests.__VEML6030_1_ID # == 0x48 or 72. this is the value is the ASW is ON + + tests = PiicoDev_test() + if tests.is_ID_connected(tests.__BME280_ID): + print('have BME280') NOTE: ============================================================================= NOTE: @@ -304,16 +306,8 @@ class PiicoDev_test(): # declare "CONSTANTS" # these are used to uniquely identify the various (conflicting) PiicoDev addresses # note the 'conflict' markers ----vv and ----^^ - # - # can use outside the class if prefixed with instantiated classname - # i.e. - # - # tests = PiicoDev_test() - # if tests.is_ID_connected(tests.__BME280_ID): - # print('have BME280') - # - __LED_ID = 0x8 # 8. RGB LEDS + __LED_ID = 0x8 # 8. RGB LEDS # ----vv __VEML6030_0_ID = 0x10 # 16. xx Light sensor (ASW off) __VEML6040_ID = 0x10 # 16. xx Colour sensor @@ -327,7 +321,7 @@ class PiicoDev_test(): __RFID_ID = 0x2c # 44. RFID module # ----vv __ULTRASONIC_ID = 0x35 # 53. xx Ultrasonic rangefinder - __POTENTIOMETER_ID = 0x35 # 53. xx Potentiometer + __POTENTIOMETER_ID = 0x35 # 53. xx Potentiometer # ----^^ __SSD1306_ID = 0x3c # 60. OLED display __BUTTON_ID = 0x42 # 66. Pushbutton @@ -454,7 +448,6 @@ class PiicoDev_test(): 'short_name': 'ENS160 (ASW on)'}, } - # # PiicoDev defaults pre-defined # can be overloaded with other values if needed to establish a second/alternate i2c bus @@ -463,19 +456,24 @@ def __init__(self, id=0, scl=Pin(9), sda=Pin(8), freq=400_000): self.i2c = I2C(id=id, scl=scl, sda=sda, freq=freq) self.connected = self.i2c.scan() + # clear() - clears the list of connected i2c devices def clear(self): self.connected = [] + # rescan() - clears and rescans the default i2c bus and repopulates the list def rescan(self): self.connected = [] self.connected = self.i2c.scan() + # show_int() - prints the list of connected ID's in DECIMAL detected by the original/most recent scan def show_int(self): print(self.connected) + # show_hex() - prints the list of connected ID's in HEXADECIMAL detected by the original/most recent scan def show_hex(self): print( [hex(i) for i in self.connected] ) + # is_ID_connected(id) - returns 1 if the ID is in the list, otherwise 0 def is_ID_connected(self, id): if _Debug == 1: print('is_ID_connected(',id,')') @@ -484,39 +482,27 @@ def is_ID_connected(self, id): else: return(0) + # how_many_connected() - returns count of detected ID's def how_many_connected(self): if _Debug == 1: print('how_many__connected()') return(len(self.connected)) + # details() - prints various levels of information of the connected ID's def details(self, mode='what', extlist=None): if _Debug == 1: print('details(',mode,')') if len(self.connected) == 0: - print('nothing connected') + print('Nothing connected') else: for i in self.connected: hit = 0 if i in self.PiicoDev_list: self.print_main(i, mode) -# if mode == 'long': -# s = self.PiicoDev_list[i]['long_name'] -# elif mode == 'short': -# s = self.PiicoDev_list[i]['short_name'] -# else: # assume 'what' -# s = self.PiicoDev_list[i]['what'] -# print(i, hex(i), s) hit = 1 if i in self.PiicoDev_conf_list: print(' vvv Possible conflict vvv') self.print_conf(i, mode) -# if mode == 'long': -# s = self.PiicoDev_conf_list[i]['long_name'] -# elif mode == 'short': -# s = self.PiicoDev_conf_list[i]['short_name'] -# else: # assume 'what' -# s = self.PiicoDev_conf_list[i]['what'] -# print(i, hex(i), s, '<<<<< Possible conflict') hit = 1 if extlist != None: if i in extlist: @@ -532,55 +518,30 @@ def details(self, mode='what', extlist=None): if hit == 0: print('Unknown device at ID ', i) + # what_is(id) - prints various levels of information from the dictionaries of the given ID def what_is(self, id, mode='what'): hit = 0 if id in self.PiicoDev_list: self.print_main(id, mode) -# if mode == 'long': -# s = self.PiicoDev_list[id]['long_name'] -# elif mode == 'short': -# s = self.PiicoDev_list[id]['short_name'] -# else: # assume 'what' -# s = self.PiicoDev_list[id]['what'] -# print('Found:', id, hex(id), s) hit = 1 if id in self.PiicoDev_conf_list: print(' vvv Possible conflict vvv') self.print_conf(id, mode) -# if mode == 'long': -# s = self.PiicoDev_conf_list[id]['long_name'] -# elif mode == 'short': -# s = self.PiicoDev_conf_list[id]['short_name'] -# else: # assume 'what' -# s = self.PiicoDev_conf_list[id]['what'] -# print('Found but possible conflict:', id, hex(id), s) hit = 1 if hit == 0: print('Unknown ID ', id) + # show_all() - prints various levels of information from the main/conflict internal dictonaries def show_all(self, mode='what', conf='noshow' ): for i in sorted(self.PiicoDev_list): self.print_main(i, mode) -# if mode == 'long': -# print(i, hex(i), self.PiicoDev_list[i]['long_name']) -# elif mode == 'short': -# print(i, hex(i), self.PiicoDev_list[i]['short_name']) -# else: # assume 'what' -# print(i, hex(i), self.PiicoDev_list[i]['what']) if conf != 'noshow': print('-- conflicting --') for i in sorted(self.PiicoDev_conf_list): self.print_conf(i, mode) -# if mode == 'long': -# print(i, hex(i), self.PiicoDev_conf_list[i]['long_name']) -# elif mode == 'short': -# print(i, hex(i), self.PiicoDev_conf_list[i]['short_name']) -# else: # assume 'what' -# print(i, hex(i), self.PiicoDev_conf_list[i]['what']) -# -# Print common functions -# + # Print common functions + # print information from the main dictionary def print_main(self, id, mode): if mode == 'long': s = self.PiicoDev_list[id]['long_name'] @@ -590,6 +551,7 @@ def print_main(self, id, mode): s = self.PiicoDev_list[id]['what'] print(id, hex(id), s) + # print information from the conflicts dictionary def print_conf(self, id, mode): if mode == 'long': s = self.PiicoDev_conf_list[id]['long_name'] @@ -599,7 +561,10 @@ def print_conf(self, id, mode): s = self.PiicoDev_conf_list[id]['what'] print(id, hex(id), s) +# # end of class +# +########################################### if _Debug: tests = PiicoDev_test() @@ -625,9 +590,6 @@ def print_conf(self, id, mode): tests.details() tests.details('short') tests.details('long') - print('************') - tests.details('what', extern_list) - print('************') aa = tests.is_ID_connected(119) print(aa) From 145014496ba061d22dfcf70c96d650416445d796 Mon Sep 17 00:00:00 2001 From: Murray Taylor Date: Sun, 12 Nov 2023 12:16:37 +1100 Subject: [PATCH 8/8] Added CoreElectronics forum id --- PiicoDev_Unified.py | 1 + 1 file changed, 1 insertion(+) diff --git a/PiicoDev_Unified.py b/PiicoDev_Unified.py index 2f1a467..a258bc2 100644 --- a/PiicoDev_Unified.py +++ b/PiicoDev_Unified.py @@ -190,6 +190,7 @@ class PiicoDev_test(): """ PiicoDev devices presence tests Murray T 20231020 (v 1.0) + @Murray125532 the simple tests without this module ------------------------------------