import sys
import time
from machine import Pin
# Define pins for software inverted UART
# GP2: TX, GP3: RX
tx_pin = Pin(2, Pin.OUT, value=0) # Idle state is Low (0)
rx_pin = Pin(3, Pin.IN, Pin.PULL_DOWN) # Idle state is Low
BAUD_RATE = 9600
BIT_TIME_US = int(1000000 / BAUD_RATE) # Duration of one bit in microseconds (~104us)
def send_byte(b):
# Start bit: High (1) for inverted UART
tx_pin.value(1)
time.sleep_us(BIT_TIME_US)
# 8 Data bits (LSB first)
for i in range(8):
bit = (b >> i) & 1
tx_pin.value(bit)
time.sleep_us(BIT_TIME_US)
# 2 Stop bits: Low (0) - returning to idle level
tx_pin.value(0)
time.sleep_us(BIT_TIME_US * 2)
def receive_byte():
# Wait for start bit (transition from Low to High)
timeout_count = 0
while rx_pin.value() == 0:
timeout_count += 1
if timeout_count > 200000: # Timeout guard
return None
# Center sample: Wait 1 full bit time (start bit) + half bit time
time.sleep_us(BIT_TIME_US + BIT_TIME_US // 2)
data = 0
for i in range(8):
bit = rx_pin.value()
data |= bit << i
time.sleep_us(BIT_TIME_US)
# Wait through the stop bits
time.sleep_us(BIT_TIME_US * 2)
return data
print("Software Inverted UART Ready. Type a string and press Enter:")
while True:
line = sys.stdin.readline()
if not line:
continue
text = line.strip()
if not text:
continue
print(f"Transmitting: {text}")
received_chars = []
for char in text:
b = ord(char)
send_byte(b)
# Receive back via loopback connection
rx_b = receive_byte()
if rx_b is not None:
received_chars.append(chr(rx_b))
else:
received_chars.append("?")
decoded_str = "".join(received_chars)
print(f"Received (Decoded): {decoded_str}")