From 0e0e542b95a892037e3e94e59c76473b2f0bdcf2 Mon Sep 17 00:00:00 2001 From: MrPrattASH <101632496+MrPrattASH@users.noreply.github.com> Date: Wed, 8 Oct 2025 14:42:30 +0200 Subject: [PATCH 1/2] 0.5.1b firmware update 2 major changes to this repo since the latest 0.5.1b huskylens firmware 1. Several methods no longer return "Knocked Received" upon successful completion. These return values have been updated to return blank. There is presently no logic present to confirm that the changes have been made as the husky lens returns a blank byte array. Rest assured, the methods still do indeed change algorithms, display text, etc, they simply have no return values. 2. I've updated the read.me to reflect these changes in return values. --- README.md | 18 ++++++------------ circuitPyHuskyLib.py | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 82687cd..3e7e33e 100644 --- a/README.md +++ b/README.md @@ -217,8 +217,7 @@ Either `[block1, block2, ..., blockN]` or `[arrow1, arrow2, ..., arrowN]` > "ALGORITHM_OBJECT_CLASSIFICATION" > ``` > -> **Return:** -> "Knock Received" on success +> As of firmware 0.5.1b, no return value is sent. #### learn(id) > **Description:** @@ -227,15 +226,13 @@ Either `[block1, block2, ..., blockN]` or `[arrow1, arrow2, ..., arrowN]` > **Arguments:** > - id: (`int`) The desired ID of the object (1 - 1023 range). > -> **Return:** -> "Knock Received" on success +> As of firmware 0.5.1b, no return value is sent. #### forget() > **Description:** > Forget learned objects for the current running algorithm. > -> **Return:** -> "Knock Received" on success +> As of firmware 0.5.1b, no return value is sent. ## UI Related Functions #### setCustomName(name, id) @@ -246,8 +243,7 @@ Either `[block1, block2, ..., blockN]` or `[arrow1, arrow2, ..., arrowN]` > - name: (`str`) value for the desired name. > - id: (`int`) the object ID you wish to change. > -> **Return:** -> "Knock Received" on success +> As of firmware 0.5.1b, no return value is sent. #### customText(name, x, y) > **Description:** @@ -260,15 +256,13 @@ Either `[block1, block2, ..., blockN]` or `[arrow1, arrow2, ..., arrowN]` > - x: (`int`) x coordinate of the top left corner of the text > - y: (`int`) y coordinate of the top left corner of the text > -> **Return:** -> "Knock Received" on success +> As of firmware 0.5.1b, no return value is sent. #### clearText() > **Description:** > Clear and remove all custom UI texts from the screen. > -> **Return:** -> "Knock Received" on success +> As of firmware 0.5.1b, no return value is sent. ## Utility Functions #### saveModelToSDCard(idVal) diff --git a/circuitPyHuskyLib.py b/circuitPyHuskyLib.py index 5446347..62ed7f5 100644 --- a/circuitPyHuskyLib.py +++ b/circuitPyHuskyLib.py @@ -1,5 +1,5 @@ # HUSKYLENS CircuitPython Library -# 09 JUN 2023 +# 08 OCT 2025 # # Credit: # Code base (reference) for Raspberry Pi: @@ -8,6 +8,8 @@ # Code base (reference) for Raspberry Pi Pico (MicroPython): # https://community.dfrobot.com/makelog-310469.html # +# OCT 2025 - Updated by Brogan M. Pratt for HuskyLens Firmware v0.5.1b +# # You need to include these libraries in your CIRCUITPY/lib folder. You can download it from https://circuitpython.org/libraries # - adafruit_bus_device # @@ -146,6 +148,10 @@ def processReturnData(self, numIdLearnFlag=False, frameFlag=False): with self.huskylensSer: self.huskylensSer.readinto(byteString, start=5, end=len(byteString)) + # TODO: remove debug line + #print("RAW RESPONSE:", ''.join(['%02x' % b for b in byteString])) + + # Convert byteString to hex first before splitCommandToParts commandSplit = self.splitCommandToParts(''.join(['%02x' % b for b in byteString])) if(commandSplit[3] == "2e"): @@ -220,12 +226,12 @@ def learn(self, id): cmd += self.calculateChecksum(cmd) cmd = self.cmdToBytes(cmd) self.writeToHuskyLens(cmd) - return self.processReturnData() + return # depreciated on firmware > 0.5.1, no return self.processReturnData() def forget(self): cmd = self.cmdToBytes(commandHeaderAndAddress+"003747") self.writeToHuskyLens(cmd) - return self.processReturnData() + return # depreciated on firmware > 0.5.1, no return self.processReturnData() def setCustomName(self, name, id): localId = "{:02x}".format(id) @@ -243,7 +249,7 @@ def setCustomName(self, name, id): cmd += self.calculateChecksum(cmd) cmd = self.cmdToBytes(cmd) self.writeToHuskyLens(cmd) - return self.processReturnData() + return # depreciated on firmware > 0.5.1, no return self.processReturnData() def customText(self, name, x, y): name_="" @@ -268,12 +274,12 @@ def customText(self, name, x, y): cmd += self.calculateChecksum(cmd) cmd = self.cmdToBytes(cmd) self.writeToHuskyLens(cmd) - return self.processReturnData() + return # depreciated on firmware > 0.5.1, no return self.processReturnData() def clearText(self): cmd = self.cmdToBytes(commandHeaderAndAddress+"003545") self.writeToHuskyLens(cmd) - return self.processReturnData() + return # depreciated on firmware > 0.5.1, no return self.processReturnData() def requestAll(self): cmd = self.cmdToBytes(commandHeaderAndAddress+"002030") @@ -368,7 +374,7 @@ def algorithm(self, alg): cmd += self.calculateChecksum(cmd) cmd = self.cmdToBytes(cmd) self.writeToHuskyLens(cmd) - return self.processReturnData() + return # depreciated on firmware > 0.5.1, no return self.processReturnData() else: print("INCORRECT ALGORITHIM NAME") From 012a1a595d11b29c55b1666cc0be035697cf33fe Mon Sep 17 00:00:00 2001 From: MrPrattASH <101632496+MrPrattASH@users.noreply.github.com> Date: Thu, 9 Oct 2025 17:21:01 +0200 Subject: [PATCH 2/2] Sequential Read Request Add small delay to setting methods, to prevent skipped returns on multiple setting commands sequentially in quick succession. --- .gitignore | 1 + circuitPyHuskyLib.py | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7176f4b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**.DS_Store diff --git a/circuitPyHuskyLib.py b/circuitPyHuskyLib.py index 62ed7f5..923d46f 100644 --- a/circuitPyHuskyLib.py +++ b/circuitPyHuskyLib.py @@ -31,6 +31,7 @@ import binascii import busio import adafruit_bus_device.i2c_device as i2c_device +from time import sleep commandHeaderAndAddress = "55AA11" algorthimsByteID = { @@ -211,6 +212,7 @@ def convert_to_class_object(self,data,isBlock): def knock(self): cmd = self.cmdToBytes(commandHeaderAndAddress+"002c3c") self.writeToHuskyLens(cmd) + sleep(0.1) return self.processReturnData() def learn(self, id): @@ -226,11 +228,13 @@ def learn(self, id): cmd += self.calculateChecksum(cmd) cmd = self.cmdToBytes(cmd) self.writeToHuskyLens(cmd) + sleep(0.1) return # depreciated on firmware > 0.5.1, no return self.processReturnData() def forget(self): cmd = self.cmdToBytes(commandHeaderAndAddress+"003747") self.writeToHuskyLens(cmd) + sleep(0.1) return # depreciated on firmware > 0.5.1, no return self.processReturnData() def setCustomName(self, name, id): @@ -249,6 +253,8 @@ def setCustomName(self, name, id): cmd += self.calculateChecksum(cmd) cmd = self.cmdToBytes(cmd) self.writeToHuskyLens(cmd) + sleep(0.1) + # add a small 0.1s sleep here if renaming multiple tags in quick succession return # depreciated on firmware > 0.5.1, no return self.processReturnData() def customText(self, name, x, y): @@ -274,6 +280,7 @@ def customText(self, name, x, y): cmd += self.calculateChecksum(cmd) cmd = self.cmdToBytes(cmd) self.writeToHuskyLens(cmd) + sleep(0.1) return # depreciated on firmware > 0.5.1, no return self.processReturnData() def clearText(self): @@ -374,6 +381,7 @@ def algorithm(self, alg): cmd += self.calculateChecksum(cmd) cmd = self.cmdToBytes(cmd) self.writeToHuskyLens(cmd) + sleep(0.1) return # depreciated on firmware > 0.5.1, no return self.processReturnData() else: print("INCORRECT ALGORITHIM NAME")