I am using a Raspberry Pi Pico 2 (RP2350)with Thonny IDE. I am writing a PIO program to send an 8-bit byte with binary from GPIO pins 0-7 and receive that data on pins 8-15. I have a simple connection system, where output pins are directly connected to input pins with short jumper cables. For example, pin 0 is connected to 8, 1 to 9 and so on until 8 to 15. My MicroPython code is below. It is writing the data correctly, but only 0s are being read. What is the problem? Do I need to fix hardware connections or is the problem with software?
In order to break down the issue, the code below is ONLY for connection between pins 0 and 8. Once I resolve the issue with this program, I think I should be able to scale it up for all eight connections.
Below is the code.
from machine import Pin
from rp2 import StateMachine, asm_pio, PIO
from time import sleep
# --- Define GPIO Pins ---
OUTPUT_PIN = 0 # GPIO0
INPUT_PIN = 8 # GPIO8
# --- Define the PIO Programs ---
# Single Output PIO Program
@asm_pio(
out_init=(PIO.OUT_LOW,), # Initialize output pin to low (as a tuple)
out_shiftdir=PIO.SHIFT_RIGHT, # Shift direction right
autopull=True, # Automatically pull data from TX FIFO
pull_thresh=1 # Pull threshold set to 1 bit
)
def single_output_prog():
label("start")
pull() # Pull 1 bit from the TX FIFO
out(pins, 1) # Output the 1 bit to the assigned GPIO pin
jmp("start") # Jump back to 'start' to loop
# Single Input PIO Program
@asm_pio(
in_shiftdir=PIO.SHIFT_RIGHT, # Shift direction right
autopush=True, # Automatically push data to RX FIFO
push_thresh=1 # Push threshold set to 1 bit
)
def single_input_prog():
label("start")
in_(pins, 1) # Read 1 bit from the assigned GPIO pin
push() # Push the read bit to the RX FIFO
jmp("start") # Jump back to 'start' to loop
# --- Initialize the State Machines ---
# Initialize Output State Machine (SM0 on PIO0)
sm_out = StateMachine(
0, # SM ID: 0 (PIO0.SM0)
single_output_prog, # PIO program for output
freq=100_000, # PIO frequency: 100 kHz (reduced for debugging)
out_base=OUTPUT_PIN, # Base output pin: GPIO0
)
sm_out.active(1) # Activate the Output SM
# Initialize Input State Machine (SM4 on PIO1)
sm_in = StateMachine(
4, # SM ID: 4 (PIO1.SM0)
single_input_prog, # PIO program for input
freq=100_000, # PIO frequency: 100 kHz
in_base=INPUT_PIN, # Base input pin: GPIO8
)
sm_in.active(1) # Activate the Input SM
# --- Define Bit Transmission Functions ---
def write_bit(bit_val, enable_logging=False):
"""
Writes a single bit to GPIO0 using SM0.
Args:
bit_val (int): The bit value to send (0 or 1).
enable_logging (bool): Whether to print debug information.
"""
if bit_val not in (0, 1):
raise ValueError("bit_val must be 0 or 1.")
if sm_out.tx_fifo() < 4: # Each SM has a TX FIFO depth of 4 by default
sm_out.put(bit_val)
if enable_logging:
print(f"Sent bit: {bit_val} to GPIO {OUTPUT_PIN}")
else:
print(f"SM{sm_out.id} TX FIFO is full. Bit {bit_val} not sent.")
def read_bit(enable_logging=False):
"""
Reads a single bit from GPIO8 using SM4.
Args:
enable_logging (bool): Whether to print debug information.
Returns:
int or None: The read bit (0 or 1) if available, else None.
"""
if sm_in.rx_fifo() > 0:
bit = sm_in.get() & 0x01
if enable_logging:
print(f"Received bit: {bit} from GPIO {INPUT_PIN}")
return bit
else:
if enable_logging:
print(f"SM{sm_in.id} RX FIFO is empty. No bit to read.")
return None
# --- Diagnostic Function ---
def check_state_machines():
"""
Checks the status of the output and input state machines.
"""
print("Checking State Machines Status:")
# Output SM
print(f"Output SM{sm_out} is {'active' if sm_out.active() else 'inactive'}")
print(f" TX FIFO: {sm_out.tx_fifo()} items")
# Input SM
print(f"Input SM{sm_in} is {'active' if sm_in.active() else 'inactive'}")
print(f" RX FIFO: {sm_in.rx_fifo()} items")
# --- Test Transmission ---
def test_single_bit():
"""
Tests sending and receiving single bits.
"""
print("Testing single bit transmission...")
test_bits = [0, 1, 1, 0, 1]
received_bits = []
for bit in test_bits:
write_bit(bit, enable_logging=True)
sleep(0.05) # Increased delay to allow PIO to process
received = read_bit(enable_logging=True)
if received is not None:
received_bits.append(received)
print(f"Sent bits: {test_bits}")
print(f"Received bits: {received_bits}")
if received_bits == test_bits:
print("Single bit transmission test passed.")
else:
print("Single bit transmission test failed.")
# --- Execute the Test ---
if __name__ == "__main__":
check_state_machines()
test_single_bit()
In order to break down the issue, the code below is ONLY for connection between pins 0 and 8. Once I resolve the issue with this program, I think I should be able to scale it up for all eight connections.
Below is the code.
from machine import Pin
from rp2 import StateMachine, asm_pio, PIO
from time import sleep
# --- Define GPIO Pins ---
OUTPUT_PIN = 0 # GPIO0
INPUT_PIN = 8 # GPIO8
# --- Define the PIO Programs ---
# Single Output PIO Program
@asm_pio(
out_init=(PIO.OUT_LOW,), # Initialize output pin to low (as a tuple)
out_shiftdir=PIO.SHIFT_RIGHT, # Shift direction right
autopull=True, # Automatically pull data from TX FIFO
pull_thresh=1 # Pull threshold set to 1 bit
)
def single_output_prog():
label("start")
pull() # Pull 1 bit from the TX FIFO
out(pins, 1) # Output the 1 bit to the assigned GPIO pin
jmp("start") # Jump back to 'start' to loop
# Single Input PIO Program
@asm_pio(
in_shiftdir=PIO.SHIFT_RIGHT, # Shift direction right
autopush=True, # Automatically push data to RX FIFO
push_thresh=1 # Push threshold set to 1 bit
)
def single_input_prog():
label("start")
in_(pins, 1) # Read 1 bit from the assigned GPIO pin
push() # Push the read bit to the RX FIFO
jmp("start") # Jump back to 'start' to loop
# --- Initialize the State Machines ---
# Initialize Output State Machine (SM0 on PIO0)
sm_out = StateMachine(
0, # SM ID: 0 (PIO0.SM0)
single_output_prog, # PIO program for output
freq=100_000, # PIO frequency: 100 kHz (reduced for debugging)
out_base=OUTPUT_PIN, # Base output pin: GPIO0
)
sm_out.active(1) # Activate the Output SM
# Initialize Input State Machine (SM4 on PIO1)
sm_in = StateMachine(
4, # SM ID: 4 (PIO1.SM0)
single_input_prog, # PIO program for input
freq=100_000, # PIO frequency: 100 kHz
in_base=INPUT_PIN, # Base input pin: GPIO8
)
sm_in.active(1) # Activate the Input SM
# --- Define Bit Transmission Functions ---
def write_bit(bit_val, enable_logging=False):
"""
Writes a single bit to GPIO0 using SM0.
Args:
bit_val (int): The bit value to send (0 or 1).
enable_logging (bool): Whether to print debug information.
"""
if bit_val not in (0, 1):
raise ValueError("bit_val must be 0 or 1.")
if sm_out.tx_fifo() < 4: # Each SM has a TX FIFO depth of 4 by default
sm_out.put(bit_val)
if enable_logging:
print(f"Sent bit: {bit_val} to GPIO {OUTPUT_PIN}")
else:
print(f"SM{sm_out.id} TX FIFO is full. Bit {bit_val} not sent.")
def read_bit(enable_logging=False):
"""
Reads a single bit from GPIO8 using SM4.
Args:
enable_logging (bool): Whether to print debug information.
Returns:
int or None: The read bit (0 or 1) if available, else None.
"""
if sm_in.rx_fifo() > 0:
bit = sm_in.get() & 0x01
if enable_logging:
print(f"Received bit: {bit} from GPIO {INPUT_PIN}")
return bit
else:
if enable_logging:
print(f"SM{sm_in.id} RX FIFO is empty. No bit to read.")
return None
# --- Diagnostic Function ---
def check_state_machines():
"""
Checks the status of the output and input state machines.
"""
print("Checking State Machines Status:")
# Output SM
print(f"Output SM{sm_out} is {'active' if sm_out.active() else 'inactive'}")
print(f" TX FIFO: {sm_out.tx_fifo()} items")
# Input SM
print(f"Input SM{sm_in} is {'active' if sm_in.active() else 'inactive'}")
print(f" RX FIFO: {sm_in.rx_fifo()} items")
# --- Test Transmission ---
def test_single_bit():
"""
Tests sending and receiving single bits.
"""
print("Testing single bit transmission...")
test_bits = [0, 1, 1, 0, 1]
received_bits = []
for bit in test_bits:
write_bit(bit, enable_logging=True)
sleep(0.05) # Increased delay to allow PIO to process
received = read_bit(enable_logging=True)
if received is not None:
received_bits.append(received)
print(f"Sent bits: {test_bits}")
print(f"Received bits: {received_bits}")
if received_bits == test_bits:
print("Single bit transmission test passed.")
else:
print("Single bit transmission test failed.")
# --- Execute the Test ---
if __name__ == "__main__":
check_state_machines()
test_single_bit()
Statistics: Posted by rvbpico — Sun Oct 06, 2024 9:50 pm — Replies 0 — Views 5