from machine import Pin
import time
TX_PIN = 2
RX_PIN = 3
tx = Pin(TX_PIN, Pin.OUT)
rx = Pin(RX_PIN, Pin.IN)
BAUD_RATE = 9600
BIT_TIME_US = 86
tx.value(0)
def wait_until(target_time):
while time.ticks_diff(target_time, time.ticks_us()) > 0:
pass
def uart_transfer_byte(tx_byte):
rx_byte = 0
data_levels = []
for bit_index in range(8):
logical_bit = (tx_byte >> bit_index) & 1
physical_level = 1 - logical_bit
data_levels.append(physical_level)
frame_start = time.ticks_us()
tx.value(1)
start_sample_time = time.ticks_add(
frame_start,
BIT_TIME_US // 2
)
wait_until(start_sample_time)
if rx.value() != 1:
raise RuntimeError("Start bit error")
start_end = time.ticks_add(
frame_start,
BIT_TIME_US
)
wait_until(start_end)
for bit_index in range(8):
tx.value(data_levels[bit_index])
bit_start = time.ticks_add(
frame_start,
BIT_TIME_US * (bit_index + 1)
)
sample_time = time.ticks_add(
bit_start,
BIT_TIME_US // 2
)
wait_until(sample_time)
received_level = rx.value()
received_bit = 1 - received_level
rx_byte |= received_bit << bit_index
bit_end = time.ticks_add(
frame_start,
BIT_TIME_US * (bit_index + 2)
)
wait_until(bit_end)
tx.value(0)
stop1_start = time.ticks_add(
frame_start,
BIT_TIME_US * 9
)
stop1_sample = time.ticks_add(
stop1_start,
BIT_TIME_US // 2
)
wait_until(stop1_sample)
if rx.value() != 0:
raise RuntimeError("Stop bit 1 error")
stop1_end = time.ticks_add(
frame_start,
BIT_TIME_US * 10
)
wait_until(stop1_end)
tx.value(0)
stop2_start = time.ticks_add(
frame_start,
BIT_TIME_US * 10
)
stop2_sample = time.ticks_add(
stop2_start,
BIT_TIME_US // 2
)
wait_until(stop2_sample)
if rx.value() != 0:
raise RuntimeError("Stop bit 2 error")
stop2_end = time.ticks_add(
frame_start,
BIT_TIME_US * 11
)
wait_until(stop2_end)
tx.value(0)
return rx_byte
def uart_transfer_string(text):
received_chars = []
for ch in text:
tx_byte = ord(ch)
if tx_byte > 127:
raise ValueError("Only ASCII characters are allowed")
rx_byte = uart_transfer_byte(tx_byte)
print(
"TX: 0x%02X RX: 0x%02X"
% (tx_byte, rx_byte)
)
received_chars.append(chr(rx_byte))
return "".join(received_chars)
print()
print("Software INVERTED UART Loopback")
print("--------------------------------")
print("Baud rate : 9600")
print("TX : GP2")
print("RX : GP3")
print("Idle : LOW")
print("Start bit : HIGH")
print("Data bits : 8")
print("Parity : None")
print("Stop bits : 2")
print("Bit order : LSB First")
print()
while True:
text = input("Enter ASCII string: ")
if text == "":
print("Please enter at least one character.")
print()
continue
try:
received = uart_transfer_string(text)
print()
print("Sent :", text)
print("Received :", received)
if received == text:
print("Loopback test: PASS")
else:
print("Loopback test: FAIL")
print()
except (ValueError, RuntimeError) as error:
print("Error:", error)
print()