Comments (12)
Using GPIO for UART has no reliable timing. The suggestion was to use the PIO state machine, which runs at exact timing. An example for TX is here: https://github.com/raspberrypi/pico-micropython-examples/blob/master/pio/pio_uart_tx.py
You can easily expand that to any bit length. Data is supplied to the state machine by sm.put, which may be a word of up to 32 bit. A parity bit could be added to the bit pattern before pushing them to the state machine. Alternative PIO code for RX canbe found at https://github.com/raspberrypi/pico-examples/blob/master/pio/uart_rx
Even if that is using C code, you can take the PIO script from the uart_rx.pio file.
from micropython.
I had to play around with the delays 1550 gave me around the correct delay between bytes. 275 gave me around the correct delay between messages.
from micropython.
9 Bit is not supported by the RP2040 MCU. At least an error should be raised. AFAIK, the only port that supports 9 bit is the STM32 port.
from micropython.
fantabulous. Do you have some recommended boards from mamazone for this? This is, I'm not kidding, the 4th board I try to get this very simple task done and some how I get one more face smash at the wall. I have a raspberry py zero lying around, do you think that might do it? I'll go see if I can find it in the mean time.
from micropython.
You can get a PyBoard V1.1 from the MicroPython store https://store.micropython.org/product/PYBv1.1
The Adafruit Feather STM32F405 Express should work as well https://www.adafruit.com/product/4382, sold on Amazon as well.
If you search for PyBoard on Amazon, you get links to other STM32F405VG boards, which may work as well with the MicroPython firmware. Only that the board names for the Pins will not match.
from micropython.
Just bit-bang your serial, with PIO 25000bauds should be fairly doable.
from micropython.
this sort of worked:
from machine import Pin
import utime
class UART:
def __init__(self, tx_pin, baud_rate=2500):
self.tx_pin = Pin(tx_pin, Pin.OUT)
self.baud_rate = baud_rate
self.bit_period_us = int(1000000 / baud_rate)
def send_data(self, data):
for byte in data:
# Start bit
self.tx_pin.value(0)
utime.sleep_us(self.bit_period_us) # Start bit duration
for _ in range(8): # 8 data bits
self.tx_pin.value(byte & 1)
byte >>= 1
utime.sleep_us(self.bit_period_us) # Data bit duration
# Stop bit
self.tx_pin.value(1)
utime.sleep_us(self.bit_period_us) # Stop bit duration
# Ensure total byte transmission duration
utime.sleep_us(self.bit_period_us * 2 - 4) # Total byte transmission duration
# Example usage:
if __name__ == "__main__":
uart = UART(tx_pin=8, baud_rate=2500) # Initialize UART with TX pin connected to GPIO pin 8 and baud rate of 2500
data = bytearray([102, 104, 0x0F9]) # Data to be transmitted
uart.send_data(data) # Send data
from micropython.
but it doesn't look exactly like the original signal from the projector i'm trying to reverse engineer:
from micropython.
Over in raspberry pi land, I got this to work but the timing seems really unstable, the waveform looks exactly as it should be but some times the timing is 400us, some times its 530us so you get framing errors:
import pigpio
import time
# Set up GPIO mode
pi = pigpio.pi() # Use default BCM numbering
# UART settings
BAUD_RATE = 2500 # Change baud rate to 2500 bps
BIT_PERIOD = 400000/ BAUD_RATE # Time for one bit in microseconds
START_BIT = 0
STOP_BIT = 1
pin = 14
# Data to send
DATA = [
(0x02, 1),
(0x04, 1),
(0xF9, 0)
]
# Function to send a single byte
def send_byte(byte, parity_bit, pin):
pi.set_mode(pin, pigpio.OUTPUT)
# Start bit
pi.write(pin, START_BIT)
time.sleep(BIT_PERIOD / 1000000) # Sleep for the bit period in microseconds
# Data bits
for i in range(8):
bit = (byte >> i) & 0x01
pi.write(pin, bit)
time.sleep(BIT_PERIOD / 1000000) # Sleep for the bit period in microseconds
# Parity bit
pi.write(pin, parity_bit)
time.sleep(BIT_PERIOD / 1000000) # Sleep for the bit period in microseconds
# Stop bit
pi.write(pin, STOP_BIT)
time.sleep(BIT_PERIOD / 1000000) # Sleep for the bit period in microseconds
try:
while True:
# Send data on pins 8, 10, and 27 (BCM numbering)
#for pin in [14,8, 10, 27]:
for byte, parity_bit in DATA:
send_byte(byte, parity_bit, pin)
#time.sleep(0.000681) # Sleep for the bit period in microseconds
#time.sleep(0.000450) # Sleep for the bit period in microseconds
time.sleep(0.371) # Sleep for the bit period in microseconds
except KeyboardInterrupt:
pass
# Clean up GPIO
pi.stop()
from micropython.
Robert-hh, you're so cool! Look I got it to work! its a baby step, I gotta see if the projector actually gets fooled so simply, but man this gives me the tool to replicate the responses the lamp is supposed to give. Thanks for the tip!
from machine import Pin, Timer
from rp2 import PIO, StateMachine, asm_pio
UART_BAUD = 2500
PIN_BASE = 8
NUM_UARTS = 1
# Define the hexadecimal values to be sent
hex_values = [0x102, 0x104, 0x0F9]
# Assembly code for UART transmission
@asm_pio(sideset_init=PIO.OUT_HIGH, out_init=PIO.OUT_HIGH, out_shiftdir=PIO.SHIFT_RIGHT)
def uart_tx():
# Block with TX deasserted until data available
pull()
# Initialise bit counter, assert start bit for 8 cycles
set(x, 8) .side(0) [7]
# Shift out 9 data bits, 9 execution cycles per bit
label("bitloop")
out(pins, 1) [7]
jmp(x_dec, "bitloop")
# Assert stop bit for 8 cycles total (incl 1 for pull())
nop() .side(1) [6]
# Initialize StateMachine for UART
sm = StateMachine(
0, uart_tx, freq=9 * UART_BAUD, sideset_base=Pin(PIN_BASE), out_base=Pin(PIN_BASE)
)
sm.active(1)
# Function to print the hexadecimal values
def pio_uart_hex(sm, hex_values):
for hex_val in hex_values:
sm.put(hex_val)
# Insert a slight delay between bytes
for _ in range(1550): # Adjust this number for the desired delay
pass
# Print the hexadecimal values from the UART
pio_uart_hex(sm, hex_values)
# Function to repeat the transmission every 200ms
def repeat_send(timer):
pio_uart_hex(sm, hex_values)
# Initialize timer for repeating transmission
tim = Timer(-1)
tim.init(period=275, mode=Timer.PERIODIC, callback=repeat_send)
from micropython.
best of all, you plug it and it runs, no 2 minutes booting up delay from a lazy raspberry pi :)
from micropython.
Glad that it works. To be honest, the hint for using PIO came from @Blafy. I just pointed to suitable examples.
from micropython.
Related Issues (20)
- Update libffi to 3.3 or later to unblock CI for RV64. HOT 6
- ESP32-S3-FN8 SPIRAM errors on boot. HOT 8
- EXTI Power Voltage Detector doesn't work on STM32WB55 and STM32WL55 HOT 7
- RV32 native emitter fails compiling some of the tests HOT 22
- ESP32 wifi issues HOT 2
- Implement machine.USBDevice for ESP32-S3 HOT 2
- NUCLEO_F746ZG LAN stops working after few days.
- frambuf initalizes with ValueError HOT 8
- examples/network/https_client.py + cloudflare.com = OSError: 97 HOT 3
- ESP32-S3 FH4R2 v0.2 No WiFi HOT 3
- docs: Information missing about 'status' options while wifi is in AP mode + "Constants" module about security?
- Const with type hints is not optimized HOT 1
- Native code decorator should be best-effort
- docs: esp32s2 has no BLE support
- RP2350 / Pico 2 machine.lightsleep not working correctly HOT 1
- RP2350 / Pico 2 machine.deepsleep results in crash HOT 2
- asyncio: sleep_ms terminates early HOT 3
- BLE GATT descriptor set to DESCRIPTOR_READ (0x01) returns Error Code: Read Not Permitted (0x02) HOT 4
- memory allocation ESP32's HOT 3
- Concatenation (without "+" sign) of string and f-string becomes f-string HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from micropython.