From 6bd766ee41eae9378e9357d1657344299e48f63d Mon Sep 17 00:00:00 2001 From: jonny Date: Tue, 28 Jan 2025 16:30:25 +0100 Subject: [PATCH] Fix shift-register, pin assignment - Digital in/out tests work --- .gitignore | 7 +++ .../pass_through_inputs_to_outputs.py | 57 +++++++++++++++++++ rpi-scripts/examples/read_digital_inputs.py | 11 +++- .../write_digital_outputs_shift_reg.py | 50 +++++++++------- .../interface_board_libs/shift_register.py | 10 ++-- rpi-scripts/interface_board_pins.py | 10 ++-- 6 files changed, 116 insertions(+), 29 deletions(-) create mode 100644 rpi-scripts/examples/pass_through_inputs_to_outputs.py diff --git a/.gitignore b/.gitignore index 0fa35b9..f7814f2 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,10 @@ fp-info-cache #freecad *.FCBak *.stl + + +#vim +*.swp + +#python +__pycache__ diff --git a/rpi-scripts/examples/pass_through_inputs_to_outputs.py b/rpi-scripts/examples/pass_through_inputs_to_outputs.py new file mode 100644 index 0000000..4a1517c --- /dev/null +++ b/rpi-scripts/examples/pass_through_inputs_to_outputs.py @@ -0,0 +1,57 @@ +import os +import sys +import time +import RPi.GPIO as GPIO + +# Add the parent directory to the module search path +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +# Import pin assignments and custom libraries +from interface_board_pins import GPIO_DIGITAL_INPUTS # Input GPIO mapping +from interface_board_pins import ( # Shift register pin assignment + GPIO_SHIFT_REG_DATA, + GPIO_SHIFT_REG_LATCH, + GPIO_SHIFT_REG_CLOCK, +) +from interface_board_libs.shift_register import ShiftRegister # Custom shift register class + +# Initialize GPIO for digital inputs +GPIO.setmode(GPIO.BCM) +for pin in GPIO_DIGITAL_INPUTS.values(): + print(f"Configuring GPIO pin {pin} as input") + GPIO.setup(pin, GPIO.IN) + +# Initialize shift register +sr = ShiftRegister(GPIO_SHIFT_REG_DATA, GPIO_SHIFT_REG_LATCH, GPIO_SHIFT_REG_CLOCK) + +# Main loop: Read inputs and write to shift register +print("\nStarting passthrough mode: Digital inputs → Shift register outputs") +try: + while True: + shift_register_value = 0 # Byte to be written to the shift register + print("\nReading inputs and updating shift register...") + + for i, (label, pin) in enumerate(GPIO_DIGITAL_INPUTS.items()): + state = GPIO.input(pin) # Read GPIO state + print(f"Input {label} (GPIO {pin}): {'HIGH' if state else 'LOW'}") + + # Set corresponding bit in shift register byte + if state: + shift_register_value |= (1 << i) # Set bit at position `i` + else: + shift_register_value &= ~(1 << i) # Clear bit at position `i` + + # Write the final byte to the shift register + sr.write_byte(shift_register_value) + print(f"Shift Register Output: {bin(shift_register_value)}") + + time.sleep(0.5) # Small delay to prevent excessive polling + +except KeyboardInterrupt: + print("\nExiting...") + +finally: + sr.clear() # Clear shift register before exiting + print("Shift register cleared.") + GPIO.cleanup() # Cleanup GPIO settings + diff --git a/rpi-scripts/examples/read_digital_inputs.py b/rpi-scripts/examples/read_digital_inputs.py index de2a5eb..3a3dde7 100644 --- a/rpi-scripts/examples/read_digital_inputs.py +++ b/rpi-scripts/examples/read_digital_inputs.py @@ -1,15 +1,19 @@ +import os +import sys # Add the parent directory to the module search path sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) # Include the common pin assignment (from parent folder) -from interface_board_pins.py import GPIO_DIGITAL_INPUTS # map of which GPIO pins are associated with which input terminal (1-8) +from interface_board_pins import GPIO_DIGITAL_INPUTS # map of which GPIO pins are associated with which input terminal (1-8) import RPi.GPIO as GPIO +import time # Initialize GPIO GPIO.setmode(GPIO.BCM) -for pin in DIGITAL_INPUTS.values(): +for pin in GPIO_DIGITAL_INPUTS.values(): + print(f"configuring pin {pin} as input") GPIO.setup(pin, GPIO.IN) @@ -18,10 +22,13 @@ for pin in DIGITAL_INPUTS.values(): print("Reading digital inputs:") try: while True: + print("reading all gpio pins...") for label, pin in GPIO_DIGITAL_INPUTS.items(): + print(f"reading pin {pin}") state = GPIO.input(pin) print(f"Input {label} (GPIO {pin}): {'HIGH' if state else 'LOW'}") print("-" * 40) + time.sleep(0.5) except KeyboardInterrupt: print("Exiting...") diff --git a/rpi-scripts/examples/write_digital_outputs_shift_reg.py b/rpi-scripts/examples/write_digital_outputs_shift_reg.py index 1f40901..57b08e8 100644 --- a/rpi-scripts/examples/write_digital_outputs_shift_reg.py +++ b/rpi-scripts/examples/write_digital_outputs_shift_reg.py @@ -18,6 +18,11 @@ from interface_board_pins import ( # pin / channel assignment ) + +# Config +COUNT_UP_TEST_ENABLED = True + + # Initialize the shift register sr = ShiftRegister(GPIO_SHIFT_REG_DATA, GPIO_SHIFT_REG_LATCH, GPIO_SHIFT_REG_CLOCK) @@ -26,40 +31,47 @@ try: # repeatedly write to shift register while True: - # # Cycle through all combinations of pin states (write entire byte) - # print("Writing all byte values (0-255)...") - # for value in range(256): - # sr.write_byte(value) # Write the current value - # print(f"Output: {bin(value)}") # Print binary representation - # sleep(0.05) # Delay between each byte + # Cycle through all combinations of pin states (write entire byte) + if COUNT_UP_TEST_ENABLED: + print("Writing all byte values (0-255)...") + for value in range(256): + sr.write_byte(value) # Write the current value + print(f"Output: {bin(value)}") # Print binary representation + sleep(0.01) # Delay between each byte + + sleep(1) + sr.clear() # Clear the shift register + # Turn each pin on and off one by one print("\nToggling each pin one by one...") - # channels 0-4 are connected to terminal only - for pin in range(4): # 0-4 are connected to terminal only - print(f"Setting pin {pin} HIGH.") - sr.set_pin(pin, True) # Set the pin HIGH - sleep(0.5) - print(f"Setting pin {pin} LOW.") - sr.set_pin(pin, False) # Set the pin LOW - sleep(0.5) - - # channels 5-7 are connected to terminal AND buzzer/relays - print("Activating buzzer...") + # channels 0-2 are connected to buzzer and relays: + print(f"Num {SHIFT_REG_CHANNEL_BUZZER}: Toggling buzzer...") # channel 0 sr.set_pin(SHIFT_REG_CHANNEL_BUZZER, True) # Turn buzzer ON sleep(0.5) sr.set_pin(SHIFT_REG_CHANNEL_BUZZER, False) # Turn buzzer OFF - print("Toggling Relay 1...") + print(f"Num {SHIFT_REG_CHANNEL_RELAY1}: Toggling Relay 1...") # channel 1 sr.toggle_pin(SHIFT_REG_CHANNEL_RELAY1) sleep(0.5) sr.toggle_pin(SHIFT_REG_CHANNEL_RELAY1) - print("Activating Relay 2...") + print(f"Num {SHIFT_REG_CHANNEL_RELAY2}: Toggling Relay 2...") # channel 2 sr.set_pin(SHIFT_REG_CHANNEL_RELAY2, True) # Turn relay ON sleep(0.5) sr.set_pin(SHIFT_REG_CHANNEL_RELAY2, False) # Turn relay OFF + + # channels 3-7 are connected to terminals only (no dedicated device on pcb): + for pin in range(3,8): # 3-7 are connected to terminal only + print(f"Num: {pin}: Toggling Terminal") + sr.set_pin(pin, True) # Set the pin HIGH + sleep(0.5) + #print(f"Setting pin {pin} LOW.") + sr.set_pin(pin, False) # Set the pin LOW + #sleep(0.5) + + finally: sr.clear() # Clear the shift register print("Shift register cleared.") diff --git a/rpi-scripts/interface_board_libs/shift_register.py b/rpi-scripts/interface_board_libs/shift_register.py index 8ab1f0e..1745798 100644 --- a/rpi-scripts/interface_board_libs/shift_register.py +++ b/rpi-scripts/interface_board_libs/shift_register.py @@ -31,19 +31,21 @@ class ShiftRegister: def set_pin(self, pin, state): """ Sets an individual pin to HIGH (1) or LOW (0). - Pins are numbered 0-7, with 0 being the MSB. + Pins are numbered 0-7, with 0 being the LSB (Q0) and 7 being the MSB (Q7). """ if not 0 <= pin <= 7: raise ValueError("Pin must be in range 0-7.") if state: - self.current_byte |= (1 << (7 - pin)) # Set the bit to 1 + self.current_byte |= (1 << pin) # Set the bit to 1 else: - self.current_byte &= ~(1 << (7 - pin)) # Set the bit to 0 + self.current_byte &= ~(1 << pin) # Set the bit to 0 self.write_byte(self.current_byte) + def toggle_pin(self, pin): """Toggles the state of an individual pin.""" if not 0 <= pin <= 7: raise ValueError("Pin must be in range 0-7.") - self.current_byte ^= (1 << (7 - pin)) # Flip the bit + self.current_byte ^= (1 << pin) # Flip the bit self.write_byte(self.current_byte) + diff --git a/rpi-scripts/interface_board_pins.py b/rpi-scripts/interface_board_pins.py index afadddf..7b38ef4 100644 --- a/rpi-scripts/interface_board_pins.py +++ b/rpi-scripts/interface_board_pins.py @@ -23,10 +23,12 @@ GPIO_SHIFT_REG_DATA = 27 GPIO_SHIFT_REG_LATCH = 17 GPIO_SHIFT_REG_CLOCK = 4 + +# FIXME: numbering in schematic is wrong (inverse) layout / terminal order matches the shift register though (left to right -> 0-7) # Shift Register Channel Assignments -SHIFT_REG_CHANNEL_BUZZER = 7 # Buzzer connected to shift register channel 7 -SHIFT_REG_CHANNEL_RELAY1 = 6 # Relay 1 connected to shift register channel 6 -SHIFT_REG_CHANNEL_RELAY2 = 5 # Relay 2 connected to shift register channel 5 +SHIFT_REG_CHANNEL_BUZZER = 0 # Buzzer connected to shift register channel 7 +SHIFT_REG_CHANNEL_RELAY1 = 1 # Relay 1 connected to shift register channel 6 +SHIFT_REG_CHANNEL_RELAY2 = 2 # Relay 2 connected to shift register channel 5 @@ -82,4 +84,4 @@ GPIO_PWM2 = 18 # RPI_PWM0 too # === UART / RS485 === GPIO_UART_TX = 14 # RPI TXD GPIO_UART_RX = 15 # RPI RXD -GPIO_UART_DIR = 23 \ No newline at end of file +GPIO_UART_DIR = 23