Custom error management

Hello everyone, I hope you are well :slight_smile:!

I managed to introduce an error in my robot, by creating a custom error management.

This is the working code:

use arduino_uno::prelude::*;
use arduino_uno::hal::port::mode::{Floating};

const TRIGGER_UP_TIME: u16 = 10u16;

/// struct sensor_unit is instantiated in main, as it needs
/// pins and timer.
pub struct SensorUnit {
    pub trig: arduino_uno::hal::port::portb::PB4<arduino_uno::hal::port::mode::Output>,
    pub echo: arduino_uno::hal::port::portb::PB3<arduino_uno::hal::port::mode::Input<Floating>>,
    pub timer: arduino_uno::atmega328p::TC1,
}

pub fn return_distance(sensor_unit: &mut SensorUnit) -> u16 {
    let mut delay = arduino_uno::Delay::new();

    sensor_unit.timer.tcnt1.write(|w| unsafe { w.bits(0) });

    // void_unwrap() --> set high could return an error
    // we are using a crate named void + unwrap
    // if not, there will be a warning on the fact that result is not used
    sensor_unit.trig.set_high().void_unwrap();
    delay.delay_us(TRIGGER_UP_TIME);
    sensor_unit.trig.set_low().void_unwrap();

    while sensor_unit.echo.is_low().void_unwrap() {
        // if more than 200 ms ( = 50000) we might have not detected anything and can continue.
        if sensor_unit.timer.tcnt1.read().bits() >= 65000 {
           // returning a huge value in case nothing in front
         // a better way is needed!!
            return 63500;
        }
    }

    // restarting the timer by writing 0 bits to it
    sensor_unit.timer.tcnt1.write(|w| unsafe { w.bits(0) });

    // waiting for the echo to get low again
    while sensor_unit.echo.is_high().void_unwrap() {}

    // Taking the time the echo was high, which is as long as the time the signal was out.
    // 1 timer count == 4 us so * 4 to get a value in microsecs
    // we divide by 58 to get the distance in cm, since (34000 cm/s * 1e-6 us time)/2 (back and forth measurement)
    // == 0.017 more or less 1/58
    let value = (sensor_unit.timer.tcnt1.read().bits() * 4) / 58;

    // !! AVR only natively supports 8 and 16 bit integers, so *do not* return bigger
    u16::from(value)

}

So returning a huge value when nothing was detected after 200 ms is not a good way to do things.

So instead I tried to do that
The difference is the Result return type, a MeaurmentError or a u16.

use arduino_uno::prelude::*;
use arduino_uno::hal::port::mode::{Floating};

const TRIGGER_UP_TIME: u16 = 10u16;

pub struct SensorUnit {
    pub trig: arduino_uno::hal::port::portb::PB4<arduino_uno::hal::port::mode::Output>,
    pub echo: arduino_uno::hal::port::portb::PB3<arduino_uno::hal::port::mode::Input<Floating>>,
    pub timer: arduino_uno::atmega328p::TC1,
}

pub struct MeasurementError;


pub fn return_distance(sensor_unit: &mut SensorUnit) -> Result<u16, MeasurementError> {
    let mut delay = arduino_uno::Delay::new();

    sensor_unit.timer.tcnt1.write(|w| unsafe { w.bits(0) });

    sensor_unit.trig.set_high().void_unwrap();
    delay.delay_us(TRIGGER_UP_TIME);
    sensor_unit.trig.set_low().void_unwrap();

    while sensor_unit.echo.is_low().void_unwrap() {
        // if more than 200 ms ( = 50000) we might have not detected anything and can continue.
        if sensor_unit.timer.tcnt1.read().bits() >= 65000 {
            return Err(MeasurementError)
        }
    }

    while sensor_unit.echo.is_high().void_unwrap() {}

    let value = (sensor_unit.timer.tcnt1.read().bits() * 4) / 58;


}

But what is returned is really crappy values/random numbers. Rahix says it can be a miscompilation error. Anyone who ran into something similar? Any way to make a bulletproof custom error?

Edit, misclicked! Sorry :slight_smile:

No familiarity with the problem domain but...
What is the value returned by this function used for?
It sounds like a large value is good enough to do whatever it is that the robot should do if it can't sense something quickly enough.

That other function would need to match the result returned by this one (that's probably fairly obvious)

It seems very weird that it is "returning crappy values / random numbers". I suppose it is possible that this is a compilation error issue.

1 Like

NP :)), Thank you for looking!

Yes the large value trick solves it somehow, but it is not looking very nice.

Yes it is probably that... maybe I should be satisfied, the robot is rolling normally...

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.