You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As shown below the two commented lines to uart.write() and uart_wait_tx_done() end up causing 1 character followed by 10 garbage characters. When the write is replaced with write_nb() which does not use the uart tx buffer it works correctly.
I would greatly appreciate the proper esp_idf_hal example code to reset the watchdog timer at the bottom of the loop so I can remove the sleep_ms(15). I know that we can do this with async or threads but what I really want here is a demonstration of a fast polling loop. I find they scale better and provide more predictable timing than spawning a bunch of threads.
### Results working copied from linux screen correctly echoing keys hit from linux screen connected as uart device on other end
abcdefghijklmnopaewwabcdefghijklmnopabcdefg
### Results copied from linux screen when the write() is used instead of write_nb()
�������������b����������c�555555555�MMMMMMMMMM���555555555�����������e�555555555�����������e������������d����������f�55555555��55555555555555�������i����������j����������k����������l����������m����������n�55555555��SSSSSSSSSSSSSS����������������aSSSSSSSSSSSSSS
��555555555쪪��������c�555555555�����������a�55555555��555555555������������a����������b�55555555��MMMMMMMMMMMMMm��555555555�����������a�555555555�SSSSSSSSSSSS������������d����������e55555555555555�����������g�555555555�������iSSSSSSSSSSSS�����������k�555555555�55555555555������������n����������o�555555555����������
Source that works correctly
//! Non Blocking fast poll Uart RS485 1/2 duplex echo for RS485 style transciever
//! test
//!
//! Folowing pins are used:
//! TX GPIO43
//! RX GPIO44
//!//!
//! This example transfers data via UART.
//! Connect TX and RX pins to see the outgoing data is read as incoming data.
//! Echo characters sent from terminal such as linux screen.
#![allow(unused_imports)]
#![allow(dead_code)]
use anyhow::Result;
use esp_idf_hal::delay::NON_BLOCK;
use esp_idf_hal::gpio;
use esp_idf_hal::gpio::PinDriver;
use esp_idf_hal::delay::Delay;
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::prelude::*;
use esp_idf_hal::uart::*;
use esp_idf_sys;
// TODO: Figure out how to make WDT work esp_idf_hal https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/watchdog.rs
// Until then disable WDT in menu config
fn main() -> anyhow::Result<()> {
esp_idf_hal::sys::link_patches();
let peripherals = Peripherals::take()?;
let tx = peripherals.pins.gpio43;
let rx = peripherals.pins.gpio44;
let led_pin = peripherals.pins.gpio11;
let rs_48_en_pin = peripherals.pins.gpio21;
let delay: Delay = Default::default();
let mut led = PinDriver::output(led_pin)?;
let mut rs48_enable = PinDriver::output(rs_48_en_pin)?;
println!("Starting UART loopback test");
let config = config::Config::new().baudrate(Hertz(115_200));
let uart = UartDriver::new(
peripherals.uart1,
tx,
rx,
Option::<gpio::Gpio0>::None,
Option::<gpio::Gpio1>::None,
&config,
)?;
loop {
let mut buf = [0_u8; 1];
uart.read(&mut buf, NON_BLOCK)?;
// we know read will return a 0 in buf
// when nothing is available so we ignore
if buf[0] != 0 {
println!("Written 0xaa, read {:?} {:?} 0x{:02x}", buf[0] as char, buf[0],buf[0]);
rs48_enable.set_high()?;
delay.delay_us(150); // need to allow transceiver time to enter active mode
// Calling Write directly causes mutliple garbage characters to
// be sent. I think the uart is not properly managing it's buffer.
//uart.write(&buf)?;
//uart.wait_tx_done(150);
uart.write_nb(&mut buf)?;
delay.delay_ms(1);
//buf[0] = 0;
rs48_enable.set_low()?;
led.toggle()?;
}
// Only need this delay because watchdog fires otherwise
delay.delay_ms(18); // TODO: TO RESET WATCHDOG IN TIGHT LOOP LIKE THIS USING esp_idf_hal
// TODO: DO SOME OTHER WORK SINCE WE ARE NO LONGER BLOCKING
// ON DATA IN UART AVAILABILITY
}
}
### Cargo for this file
The example https://github.com/esp-rs/esp-idf-hal/blob/master/examples/uart_loopback.rs fails to compile due to a missing import. I adapted it to my needs and fixed a couple errors so it both compiles and provides proper response when tested with linux screen.
As shown below the two commented lines to uart.write() and uart_wait_tx_done() end up causing 1 character followed by 10 garbage characters. When the write is replaced with write_nb() which does not use the uart tx buffer it works correctly.
I would greatly appreciate the proper esp_idf_hal example code to reset the watchdog timer at the bottom of the loop so I can remove the sleep_ms(15). I know that we can do this with async or threads but what I really want here is a demonstration of a fast polling loop. I find they scale better and provide more predictable timing than spawning a bunch of threads.
Source that works correctly
[package]
name = "ex-uart-non-block-rs485"
version = "0.1.0"
authors = ["joe ellsworth [email protected]"]
edition = "2021"
resolver = "2"
rust-version = "1.71"
[profile.release]
opt-level = "s"
[profile.dev]
debug = true # Symbols are nice and they don't increase the size on Flash
opt-level = "z"
[features]
default = ["std", "embassy", "esp-idf-svc/native"]
pio = ["esp-idf-svc/pio"]
std = ["alloc", "esp-idf-svc/binstart", "esp-idf-svc/std"]
alloc = ["esp-idf-svc/alloc"]
nightly = ["esp-idf-svc/nightly"]
experimental = ["esp-idf-svc/experimental"]
embassy = ["esp-idf-svc/embassy-sync", "esp-idf-svc/critical-section", "esp-idf-svc/embassy-time-driver"]
[dependencies]
log = { version = "0.4", default-features = false }
esp-idf-svc = { version = "0.48", default-features = false }
esp-idf-hal = "0.43.1"
anyhow = "1.0.82"
esp-idf-sys = "0.34.1"
[build-dependencies]
embuild = "0.31.3"
The text was updated successfully, but these errors were encountered: