| Crates.io | uartcat |
| lib.rs | uartcat |
| version | 0.1.2 |
| created_at | 2025-12-13 18:06:48.322828+00 |
| updated_at | 2025-12-13 18:31:15.268159+00 |
| description | chained uart memory bus protocol strongly inspired from EtherCAT and simplified |
| homepage | |
| repository | https://github.com/jimy-byerley/uartcat |
| max_upload_size | |
| id | 1983261 |
| size | 74,320 |
UartCAT is a realtime memory bus protocol implemented on a UART daisy chain. Its concept are inspired from EtherCAT but with most of its complexity removed. UartCAT is a caterpillar propagating protocol using UART just like Ethercat is a caterpillar propagating protocol using Ethernet.
The main advantages of this protocol are
also differences due to UART instead of Ethernet:
root is the uartcat crate, that implements master and slave parties of the protocol
master is a collection of binaries running the uartcat master, for testing and examples
slave is a collection of binaries running a uartcat test slave, and other example slaves
master and slave suites are implemented for esp32 in this repo, but the uartcat protocol also works for any microcontroller with a UART bus and supported by rust.
hardware config
/dev/ttyUSB0/dev/ttyUSB1in one shell run the testing slave
cd uartcat/slave
ESP_LOG=debug cargo run
in a second shell run the tests at the master level
cd uartcat/master
RUST_LOG=debug cargo test
in one shell run the slave implementation of the example
cd uartcat/slave
cargo run --example basic
in a second shell run the example code with the same name
cd uartcat/master
cargo run --example basic
on your master (can be your PC):
const CUSTOM_REGISTER: SlaveRegister<u32> = Register::new(0x500);
let master = Master::new("/dev/ttyUSB1", 1_500_000).unwrap();
let custom = master.read(CUSTOM_REGISTER).await?.any()?;
master.write(CUSTOM_REGISTER, custom+1).await?.any()?;
assert_eq!(custom, 42);
on your slave (any microcontroller)
const CUSTOM_REGISTER: SlaveRegister<u32> = Register::new(0x500);
const BUFFER: usize = 0x504; // size of slave buffer accessible by master
let slave = Slave::<_, BUFFER>::new(
I2c(UART1, 1_500_000, GPIO1, GPIO2),
Device {...},
);
slave.lock().await.set(CUSTOM_REGISTER, 42);
slave.run().await;
for a complete example see master/examples/basic.rs and matching slave/examples/basic.rs