Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UART read timeout? #461

Open
victorbnl opened this issue Jul 18, 2024 · 1 comment
Open

UART read timeout? #461

victorbnl opened this issue Jul 18, 2024 · 1 comment

Comments

@victorbnl
Copy link

I am trying to read a success code that is sent to my ESP by a UART sensor. To do so, I use read_exact this way

fn read_success(uart: &mut UartDriver) -> anyhow::Result<()> {
    let mut buffer = [0; 10];
    uart.read_exact(&mut buffer)?;
    assert_eq!(&buffer, b"$00023335&");
    Ok(())
}

Can I set a read timeout in case the sensor never responds?

There seems to be uart_set_rx_timeout but I couldn’t find any function that does this in the wrappers.

@armandas
Copy link

I had the same problem. Not sure if that's the best way to solve this, but what I did is implement my own ReadWithTimeout trait, based on the Read trait from embedded_io:

use esp_idf_hal::delay::TickType;
use esp_idf_hal::io::{EspIOError, ReadExactError};
use esp_idf_hal::uart::UartDriver;

pub trait ReadWithTimeout {
    fn read(&mut self, buf: &mut [u8], timeout_ms: u64) -> Result<usize, EspIOError>;

    fn read_exact(
        &mut self,
        mut buf: &mut [u8],
        timeout_ms: u64,
    ) -> Result<(), ReadExactError<EspIOError>> {
        while !buf.is_empty() {
            match self.read(buf, timeout_ms) {
                Ok(0) => break,
                Ok(n) => buf = &mut buf[n..],
                Err(e) => return Err(ReadExactError::Other(e)),
            }
        }
        if buf.is_empty() {
            Ok(())
        } else {
            Err(ReadExactError::UnexpectedEof)
        }
    }
}

impl<'d> ReadWithTimeout for UartDriver<'d> {
    fn read(&mut self, buf: &mut [u8], timeout_ms: u64) -> Result<usize, EspIOError> {
        UartDriver::read(self, buf, TickType::new_millis(timeout_ms).ticks()).map_err(EspIOError)
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Todo
Development

No branches or pull requests

2 participants