From a0981fca71b1baa6569247614a4118fdaf9f0445 Mon Sep 17 00:00:00 2001 From: mutesplash <49622611+mutesplash@users.noreply.github.com> Date: Tue, 12 Sep 2023 00:20:40 -0400 Subject: [PATCH 01/13] Add movement counter to WeDo 2.0 Motion Sensor --- buildhat/wedo.py | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/buildhat/wedo.py b/buildhat/wedo.py index df99dd6..fc874c2 100644 --- a/buildhat/wedo.py +++ b/buildhat/wedo.py @@ -35,6 +35,7 @@ class MotionSensor(Device): :param port: Port of device :raises DeviceError: Occurs if there is no motion sensor attached to port """ + default_mode = 0 def __init__(self, port): """ @@ -43,7 +44,18 @@ def __init__(self, port): :param port: Port of device """ super().__init__(port) - self.mode(0) + self.mode(self.default_mode) + + def set_default_data_mode(self, mode): + """ + Set the mode most often queried from this device to significantly + improve performance when repeatedly accessing data + + :param mode: 0 for distance (default), 1 for movement count + """ + if mode == 1 or mode == 0: + self.default_mode = mode + self.mode(mode) def get_distance(self): """ @@ -52,4 +64,24 @@ def get_distance(self): :return: Distance from motion sensor :rtype: int """ - return self.get()[0] + return self._get_data_from_mode(0) + + def get_movement_count(self): + """ + Return the movement counter: The count of how many times the sensor has + detected an object that moved within 4 blocks of the sensor since the + sensor has been plugged in or the BuildHAT reset + + :return: Count of objects detected + :rtype: int + """ + return self._get_data_from_mode(1) + + def _get_data_from_mode(self, mode): + if self.default_mode == mode: + return self.get()[0] + else: + self.mode(mode) + retval = self.get()[0] + self.mode(self.default_mode) + return retval From e2b9a7910cadcfabff47df7d022bd39afceb925d Mon Sep 17 00:00:00 2001 From: mutesplash <49622611+mutesplash@users.noreply.github.com> Date: Tue, 12 Sep 2023 00:36:32 -0400 Subject: [PATCH 02/13] Didn't have all the flake8 checkers installed --- buildhat/wedo.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/buildhat/wedo.py b/buildhat/wedo.py index fc874c2..372524e 100644 --- a/buildhat/wedo.py +++ b/buildhat/wedo.py @@ -35,6 +35,7 @@ class MotionSensor(Device): :param port: Port of device :raises DeviceError: Occurs if there is no motion sensor attached to port """ + default_mode = 0 def __init__(self, port): @@ -48,8 +49,9 @@ def __init__(self, port): def set_default_data_mode(self, mode): """ - Set the mode most often queried from this device to significantly - improve performance when repeatedly accessing data + Set the mode most often queried from this device. + + This significantly improves performance when repeatedly accessing data :param mode: 0 for distance (default), 1 for movement count """ @@ -68,9 +70,11 @@ def get_distance(self): def get_movement_count(self): """ - Return the movement counter: The count of how many times the sensor has - detected an object that moved within 4 blocks of the sensor since the - sensor has been plugged in or the BuildHAT reset + Return the movement counter + + This is the count of how many times the sensor has detected an object + that moved within 4 blocks of the sensor since the sensor has been + plugged in or the BuildHAT reset :return: Count of objects detected :rtype: int From 4f0ac084488bbf7eab04fb58633a4a52800580c9 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Thu, 23 Nov 2023 15:22:32 +0000 Subject: [PATCH 03/13] Fix Build HAT library to work on Raspberry Pi 5 --- buildhat/serinterface.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/buildhat/serinterface.py b/buildhat/serinterface.py index af1ab1b..fbed704 100644 --- a/buildhat/serinterface.py +++ b/buildhat/serinterface.py @@ -5,6 +5,7 @@ import tempfile import threading import time +import os from enum import Enum from threading import Condition, Timer @@ -105,6 +106,11 @@ def __init__(self, firmware, signature, version, device="/dev/serial0", debug=Fa self.rampftr.append([]) self.motorqueue.append(queue.Queue()) + # On a Pi 5 /dev/serial0 will point to /dev/ttyAMA10 (which *only* + # exists on a Pi 5, and is the 3-pin debug UART connector) + # The UART on the Pi 5 GPIO header is /dev/ttyAMA0 + if device == "/dev/serial0" and os.readlink(device) == "ttyAMA10": + device = "/dev/ttyAMA0" self.ser = serial.Serial(device, 115200, timeout=5) # Check if we're in the bootloader or the firmware self.write(b"version\r") From e6e642d21aaab7d327a41dbd21f6bd38d446d3c9 Mon Sep 17 00:00:00 2001 From: Greg Annandale Date: Thu, 23 Nov 2023 17:03:01 +0000 Subject: [PATCH 04/13] Release version 0.6.0 --- CHANGELOG.md | 6 ++++++ VERSION | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e070036..2d3d92c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 0.6.0 + +### Added + +* Support for Raspberry Pi 5 (https://github.com/RaspberryPiFoundation/python-build-hat/pull/203) + ## 0.5.12 ### Added diff --git a/VERSION b/VERSION index 9d6c175..a918a2a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.12 +0.6.0 From 84e31014568fa4c35dab5bbf74b39cb9d091559e Mon Sep 17 00:00:00 2001 From: Greg Annandale Date: Thu, 23 Nov 2023 17:15:34 +0000 Subject: [PATCH 05/13] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f6d7f91..7112796 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ share/python-wheels/ .installed.cfg *.egg MANIFEST +.pypirc # Installer logs pip-log.txt From d60686f6c353918eac29f10ea54c9ce4dc751188 Mon Sep 17 00:00:00 2001 From: Greg Annandale Date: Thu, 23 Nov 2023 17:23:16 +0000 Subject: [PATCH 06/13] Fix linting error --- buildhat/serinterface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildhat/serinterface.py b/buildhat/serinterface.py index fbed704..c8e5063 100644 --- a/buildhat/serinterface.py +++ b/buildhat/serinterface.py @@ -1,11 +1,11 @@ """Build HAT handling functionality""" import logging +import os import queue import tempfile import threading import time -import os from enum import Enum from threading import Condition, Timer From ea87bafc957380c8d2a6092e5769eac155e2e049 Mon Sep 17 00:00:00 2001 From: mutesplash <49622611+mutesplash@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:14:46 -0500 Subject: [PATCH 07/13] Public access to the filename of the debug log --- buildhat/hat.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/buildhat/hat.py b/buildhat/hat.py index 395a3d6..227b054 100644 --- a/buildhat/hat.py +++ b/buildhat/hat.py @@ -41,6 +41,9 @@ def get(self): "description": desc} return devices + def get_logfile(self): + return Device._instance.debug_filename + def get_vin(self): """Get the voltage present on the input power jack From 338296334f65ffad2e9b04d20de991bebb447cad Mon Sep 17 00:00:00 2001 From: mutesplash <49622611+mutesplash@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:15:39 -0500 Subject: [PATCH 08/13] Save debug log filename vs throwing it away in the logging framework --- buildhat/serinterface.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buildhat/serinterface.py b/buildhat/serinterface.py index c8e5063..77ee53e 100644 --- a/buildhat/serinterface.py +++ b/buildhat/serinterface.py @@ -94,8 +94,10 @@ def __init__(self, firmware, signature, version, device="/dev/serial0", debug=Fa self.motorqueue = [] self.fin = False self.running = True + self.debug_filename = None if debug: tmp = tempfile.NamedTemporaryFile(suffix=".log", prefix="buildhat-", delete=False) + self.debug_filename = tmp.name logging.basicConfig(filename=tmp.name, format='%(asctime)s %(message)s', level=logging.DEBUG) From 057e98662990c54ed0d8593d2f048f1e947da2fe Mon Sep 17 00:00:00 2001 From: mutesplash <49622611+mutesplash@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:31:07 -0500 Subject: [PATCH 09/13] Flake8 compliance --- buildhat/hat.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/buildhat/hat.py b/buildhat/hat.py index 227b054..0a277eb 100644 --- a/buildhat/hat.py +++ b/buildhat/hat.py @@ -42,6 +42,11 @@ def get(self): return devices def get_logfile(self): + """Get the filename of the debug log (If enabled, None otherwise) + + :return: Path of the debug logfile + :rtype: str or None + """ return Device._instance.debug_filename def get_vin(self): From 3670a2f19fde8df221093e612d8082b0e9204ea0 Mon Sep 17 00:00:00 2001 From: mutesplash <49622611+mutesplash@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:09:03 -0500 Subject: [PATCH 10/13] Support Mode 7 IR Transmission As described in "LEGO Power Functions RC" PDF https://www.philohome.com/pf/pf.htm --- buildhat/colordistance.py | 334 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) diff --git a/buildhat/colordistance.py b/buildhat/colordistance.py index 3447e17..52cae03 100644 --- a/buildhat/colordistance.py +++ b/buildhat/colordistance.py @@ -25,6 +25,9 @@ def __init__(self, port): self.mode(6) self.avg_reads = 4 self._old_color = None + self._ir_channel = 0x0 + self._ir_address = 0x0 + self._ir_toggle = 0x0 def segment_color(self, r, g, b): """Return the color name from HSV @@ -197,6 +200,337 @@ def wait_for_new_color(self): self.callback(None) return self._old_color + @property + def ir_channel(self): + return self._ir_channel + + @ir_channel.setter + def ir_channel(self, channel=1): + """ + Set the IR channel for RC Tx + + :param channel: 1-4 indicating the selected IR channel on the reciever + """ + check_chan = channel + if check_chan > 4: + check_chan = 4 + elif check_chan < 1: + check_chan = 1 + # Internally: 0-3 + self._ir_channel = int(check_chan)-1 + + @property + def ir_address(self): + """ + IR Address space of 0x0 for default PoweredUp or 0x1 for extra space + """ + return self._ir_address + + def toggle_ir_toggle(self): + """ + Toggle the IR toggle bit + + """ + # IYKYK, because the RC documents are not clear + if self._ir_toggle: + self._ir_toggle = 0x0 + else: + self._ir_toggle = 0x1 + return self._ir_toggle + + def send_ir_sop(self, port, mode): + """ + Send an IR message via Power Functions RC Protocol in Single Output PWM mode + https://www.philohome.com/pf/pf.htm + + Port B is blue + + Valid values for mode are: + 0x0: Float output + 0x1: Forward/Clockwise at speed 1 + 0x2: Forward/Clockwise at speed 2 + 0x3: Forward/Clockwise at speed 3 + 0x4: Forward/Clockwise at speed 4 + 0x5: Forward/Clockwise at speed 5 + 0x6: Forward/Clockwise at speed 6 + 0x7: Forward/Clockwise at speed 7 + 0x8: Brake (then float v1.20) + 0x9: Backwards/Counterclockwise at speed 7 + 0xA: Backwards/Counterclockwise at speed 6 + 0xB: Backwards/Counterclockwise at speed 5 + 0xC: Backwards/Counterclockwise at speed 4 + 0xD: Backwards/Counterclockwise at speed 3 + 0xE: Backwards/Counterclockwise at speed 2 + 0xF: Backwards/Counterclockwise at speed 1 + + :param port: 'A' or 'B' + :param mode: 0-15 indicating the port's mode to set + """ + escape_modeselect = 0x0 + escape = escape_modeselect + + ir_mode_single_output = 0x4 + ir_mode = ir_mode_single_output + + so_mode_pwm = 0x0 + so_mode = so_mode_pwm + + output_port_a = 0x0 + output_port_b = 0x1 + + output_port = None + if port == 'A' or port == 'a': + output_port = output_port_a + elif port == 'B' or port == 'b': + output_port = output_port_b + else: + return False + + ir_mode = ir_mode | (so_mode << 1) | output_port + + nibble1 = (self._ir_toggle << 3) | (escape << 2) | self._ir_channel + nibble2 = (self._ir_address << 3) | ir_mode + + # Mode range checked here + return self._send_ir_nibbles(nibble1, nibble2, mode) + + def send_ir_socstid(self, port, mode): + """ + Send an IR message via Power Functions RC Protocol in Single Output Clear/Set/Toggle/Increment/Decrement mode + https://www.philohome.com/pf/pf.htm + + Valid values for mode are: + 0x0: Toggle full Clockwise/Forward (Stop to Clockwise, Clockwise to Stop, Counterclockwise to Clockwise) + 0x1: Toggle direction + 0x2: Increment numerical PWM + 0x3: Decrement numerical PWM + 0x4: Increment PWM + 0x5: Decrement PWM + 0x6: Full Clockwise/Forward + 0x7: Full Counterclockwise/Backward + 0x8: Toggle full (defaults to Forward, first) + 0x9: Clear C1 (C1 to High) + 0xA: Set C1 (C1 to Low) + 0xB: Toggle C1 + 0xC: Clear C2 (C2 to High) + 0xD: Set C2 (C2 to Low) + 0xE: Toggle C2 + 0xF: Toggle full Counterclockwise/Backward (Stop to Clockwise, Counterclockwise to Stop, Clockwise to Counterclockwise) + + :param port: 'A' or 'B' + :param mode: 0-15 indicating the port's mode to set + """ + + escape_modeselect = 0x0 + escape = escape_modeselect + + ir_mode_single_output = 0x4 + ir_mode = ir_mode_single_output + + so_mode_cstid = 0x1 + so_mode = so_mode_cstid + + output_port_a = 0x0 + output_port_b = 0x1 + + output_port = None + if port == 'A' or port == 'a': + output_port = output_port_a + elif port == 'B' or port == 'b': + output_port = output_port_b + else: + return False + + ir_mode = ir_mode | (so_mode << 1) | output_port + + nibble1 = (self._ir_toggle << 3) | (escape << 2) | self._ir_channel + nibble2 = (self._ir_address << 3) | ir_mode + + # Mode range checked here + return self._send_ir_nibbles(nibble1, nibble2, mode) + + def send_ir_combo_pwm(self, port_b_mode, port_a_mode): + """ + Send an IR message via Power Functions RC Protocol in Combo PWM mode + https://www.philohome.com/pf/pf.htm + + Valid values for the modes are: + 0x0 Float + 0x1 PWM Forward step 1 + 0x2 PWM Forward step 2 + 0x3 PWM Forward step 3 + 0x4 PWM Forward step 4 + 0x5 PWM Forward step 5 + 0x6 PWM Forward step 6 + 0x7 PWM Forward step 7 + 0x8 Brake (then float v1.20) + 0x9 PWM Backward step 7 + 0xA PWM Backward step 6 + 0xB PWM Backward step 5 + 0xC PWM Backward step 4 + 0xD PWM Backward step 3 + 0xE PWM Backward step 2 + 0xF PWM Backward step 1 + + :param port_b_mode: 0-15 indicating the command to send to port B + :param port_a_mode: 0-15 indicating the command to send to port A + """ + + escape_combo_pwm = 0x1 + escape = escape_combo_pwm + + nibble1 = (self._ir_toggle << 3) | (escape << 2) | self._ir_channel + + # Port modes are range checked here + return self._send_ir_nibbles(nibble1, port_b_mode, port_a_mode) + + def send_ir_combo_direct(self, port_b_output, port_a_output): + """ + Send an IR message via Power Functions RC Protocol in Combo Direct mode + https://www.philohome.com/pf/pf.htm + + Valid values for the output variables are: + 0x0: Float output + 0x1: Clockwise/Forward + 0x2: Counterclockwise/Backwards + 0x3: Brake then float + + :param port_b_output: 0-3 indicating the output to send to port B + :param port_a_output: 0-3 indicating the output to send to port A + """ + escape_modeselect = 0x0 + escape = escape_modeselect + + ir_mode_combo_direct = 0x1 + ir_mode = ir_mode_combo_direct + + nibble1 = (self._ir_toggle << 3) | (escape << 2) | self._ir_channel + nibble2 = (self._ir_address << 3) | ir_mode + + if port_b_output > 0x3 or port_a_output > 0x3: + return False + if port_b_output < 0x0 or port_a_output < 0x0: + return False + + nibble3 = (port_b_output << 2) | port_a_output + + return self._send_ir_nibbles(nibble1, nibble2, nibble3) + + def send_ir_extended(self, mode): + """ + Send an IR message via Power Functions RC Protocol in Extended mode + https://www.philohome.com/pf/pf.htm + + Valid values for the mode are: + 0x0: Brake Port A (timeout) + 0x1: Increment Speed on Port A + 0x2: Decrement Speed on Port A + + 0x4: Toggle Forward/Clockwise/Float on Port B + + 0x6: Toggle Address bit + 0x7: Align toggle bit + + :param mode: 0-2,4,6-7 + """ + escape_modeselect = 0x0 + escape = escape_modeselect + + ir_mode_extended = 0x0 + ir_mode = ir_mode_extended + + nibble1 = (self._ir_toggle << 3) | (escape << 2) | self._ir_channel + nibble2 = (self._ir_address << 3) | ir_mode + + if mode < 0x0 or mode == 0x3 or mode == 0x5 or mode > 0x7: + return False + + return self._send_ir_nibbles(nibble1, nibble2, mode) + + def send_ir_single_pin(self, port, pin, mode, timeout): + """ + Send an IR message via Power Functions RC Protocol in Single Pin mode + https://www.philohome.com/pf/pf.htm + + Valid values for the mode are: + 0x0: No-op + 0x1: Clear + 0x2: Set + 0x3: Toggle + + Note: The unlabeled IR receiver (vs the one labeled V2) has a "firmware bug in Single Pin mode" + https://www.philohome.com/pfrec/pfrec.htm + + :param port: 'A' or 'B' + :param pin: 1 or 2 + :param mode: 0-3 indicating the pin's mode to set + :param timeout: True or False + """ + escape_mode = 0x0 + escape = escape_mode + + ir_mode_single_continuous = 0x2 + ir_mode_single_timeout = 0x3 + ir_mode = None + if timeout: + ir_mode = ir_mode_single_timeout + else: + ir_mode = ir_mode_single_continuous + + output_port_a = 0x0 + output_port_b = 0x1 + + output_port = None + if port == 'A' or port == 'a': + output_port = output_port_a + elif port == 'B' or port == 'b': + output_port = output_port_b + else: + return False + + if pin != 1 and pin != 2: + return False + pin_value = pin-1 + + if mode > 0x3 or mode < 0x0: + return False + + nibble1 = (self._ir_toggle << 3) | (escape << 2) | self._ir_channel + nibble2 = (self._ir_address << 3) | ir_mode + nibble3 = (output_port << 3) | (pin_value << 3) | mode + + return self._send_ir_nibbles(nibble1, nibble2, mode) + + def _send_ir_nibbles(self, nibble1, nibble2, nibble3): + + # M7 IR Tx SI = N/A + # format count=1 type=1 chars=5 dp=0 + # RAW: 00000000 0000FFFF PCT: 00000000 00000064 SI: 00000000 0000FFFF + + mode = 7 + self.mode(mode) + + # The upper bits of data[2] are ignored + if nibble1 > 0xF or nibble2 > 0xF or nibble3 > 0xF: + return False + if nibble1 < 0x0 or nibble2 < 0x0 or nibble3 < 0x0: + return False + + byte_two = (nibble2 << 4) | nibble3 + + data = bytearray(3) + data[0] = (0xc << 4) | mode + data[1] = byte_two + data[2] = nibble1 + + # print(" ".join('{:04b}'.format(nibble1))) + # print(" ".join('{:04b}'.format(nibble2))) + # print(" ".join('{:04b}'.format(nibble3))) + # print(" ".join('{:08b}'.format(n) for n in data)) + + self._write1(data) + return True + def on(self): """Turn on the sensor and LED""" self.reverse() From a306d01951de028d9323d4295905bbcb31a3ceae Mon Sep 17 00:00:00 2001 From: mutesplash <49622611+mutesplash@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:26:40 -0500 Subject: [PATCH 11/13] Flake8 compliance ... and a bugfix, thanks to flake8... so mad that it actually helped --- buildhat/colordistance.py | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/buildhat/colordistance.py b/buildhat/colordistance.py index 52cae03..3c722a3 100644 --- a/buildhat/colordistance.py +++ b/buildhat/colordistance.py @@ -202,6 +202,7 @@ def wait_for_new_color(self): @property def ir_channel(self): + """Get the IR channel for message transmission""" return self._ir_channel @ir_channel.setter @@ -217,20 +218,15 @@ def ir_channel(self, channel=1): elif check_chan < 1: check_chan = 1 # Internally: 0-3 - self._ir_channel = int(check_chan)-1 + self._ir_channel = int(check_chan) - 1 @property def ir_address(self): - """ - IR Address space of 0x0 for default PoweredUp or 0x1 for extra space - """ + """IR Address space of 0x0 for default PoweredUp or 0x1 for extra space""" return self._ir_address def toggle_ir_toggle(self): - """ - Toggle the IR toggle bit - - """ + """Toggle the IR toggle bit""" # IYKYK, because the RC documents are not clear if self._ir_toggle: self._ir_toggle = 0x0 @@ -241,7 +237,8 @@ def toggle_ir_toggle(self): def send_ir_sop(self, port, mode): """ Send an IR message via Power Functions RC Protocol in Single Output PWM mode - https://www.philohome.com/pf/pf.htm + + PF IR RC Protocol documented at https://www.philohome.com/pf/pf.htm Port B is blue @@ -297,7 +294,8 @@ def send_ir_sop(self, port, mode): def send_ir_socstid(self, port, mode): """ Send an IR message via Power Functions RC Protocol in Single Output Clear/Set/Toggle/Increment/Decrement mode - https://www.philohome.com/pf/pf.htm + + PF IR RC Protocol documented at https://www.philohome.com/pf/pf.htm Valid values for mode are: 0x0: Toggle full Clockwise/Forward (Stop to Clockwise, Clockwise to Stop, Counterclockwise to Clockwise) @@ -320,7 +318,6 @@ def send_ir_socstid(self, port, mode): :param port: 'A' or 'B' :param mode: 0-15 indicating the port's mode to set """ - escape_modeselect = 0x0 escape = escape_modeselect @@ -352,7 +349,8 @@ def send_ir_socstid(self, port, mode): def send_ir_combo_pwm(self, port_b_mode, port_a_mode): """ Send an IR message via Power Functions RC Protocol in Combo PWM mode - https://www.philohome.com/pf/pf.htm + + PF IR RC Protocol documented at https://www.philohome.com/pf/pf.htm Valid values for the modes are: 0x0 Float @@ -375,7 +373,6 @@ def send_ir_combo_pwm(self, port_b_mode, port_a_mode): :param port_b_mode: 0-15 indicating the command to send to port B :param port_a_mode: 0-15 indicating the command to send to port A """ - escape_combo_pwm = 0x1 escape = escape_combo_pwm @@ -387,7 +384,8 @@ def send_ir_combo_pwm(self, port_b_mode, port_a_mode): def send_ir_combo_direct(self, port_b_output, port_a_output): """ Send an IR message via Power Functions RC Protocol in Combo Direct mode - https://www.philohome.com/pf/pf.htm + + PF IR RC Protocol documented at https://www.philohome.com/pf/pf.htm Valid values for the output variables are: 0x0: Float output @@ -419,7 +417,8 @@ def send_ir_combo_direct(self, port_b_output, port_a_output): def send_ir_extended(self, mode): """ Send an IR message via Power Functions RC Protocol in Extended mode - https://www.philohome.com/pf/pf.htm + + PF IR RC Protocol documented at https://www.philohome.com/pf/pf.htm Valid values for the mode are: 0x0: Brake Port A (timeout) @@ -450,7 +449,8 @@ def send_ir_extended(self, mode): def send_ir_single_pin(self, port, pin, mode, timeout): """ Send an IR message via Power Functions RC Protocol in Single Pin mode - https://www.philohome.com/pf/pf.htm + + PF IR RC Protocol documented at https://www.philohome.com/pf/pf.htm Valid values for the mode are: 0x0: No-op @@ -490,7 +490,7 @@ def send_ir_single_pin(self, port, pin, mode, timeout): if pin != 1 and pin != 2: return False - pin_value = pin-1 + pin_value = pin - 1 if mode > 0x3 or mode < 0x0: return False @@ -499,7 +499,7 @@ def send_ir_single_pin(self, port, pin, mode, timeout): nibble2 = (self._ir_address << 3) | ir_mode nibble3 = (output_port << 3) | (pin_value << 3) | mode - return self._send_ir_nibbles(nibble1, nibble2, mode) + return self._send_ir_nibbles(nibble1, nibble2, nibble3) def _send_ir_nibbles(self, nibble1, nibble2, nibble3): @@ -516,7 +516,7 @@ def _send_ir_nibbles(self, nibble1, nibble2, nibble3): if nibble1 < 0x0 or nibble2 < 0x0 or nibble3 < 0x0: return False - byte_two = (nibble2 << 4) | nibble3 + byte_two = (nibble2 << 4) | nibble3 data = bytearray(3) data[0] = (0xc << 4) | mode From e73e4153be9e73fde0269f20a37e9efa1b95884a Mon Sep 17 00:00:00 2001 From: Greg Annandale Date: Tue, 19 Dec 2023 07:42:21 -0600 Subject: [PATCH 12/13] Release version 0.7.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a918a2a..faef31a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.0 +0.7.0 From 78c0c6988f9c786113b12c4c6309aecccb36b1da Mon Sep 17 00:00:00 2001 From: Greg Annandale Date: Tue, 19 Dec 2023 07:45:38 -0600 Subject: [PATCH 13/13] Adds 0.7.0 changes to Change Log --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d3d92c..7cbdc59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 0.7.0 + +Adds: + +* Mode 7 IR transmission to ColorDistanceSensor https://github.com/RaspberryPiFoundation/python-build-hat/pull/205 +* Debug log filename access https://github.com/RaspberryPiFoundation/python-build-hat/pull/204 +* Movement counter to WeDo 2.0 Motion Sensor https://github.com/RaspberryPiFoundation/python-build-hat/pull/201 + ## 0.6.0 ### Added