eldruin / lsm303agr-rs

Platform agnostic Rust driver for the LSM303AGR ultra-compact high-performance eCompass module: ultra-low-power 3D accelerometer and 3D magnetometer
Apache License 2.0
18 stars 14 forks source link

Proper way to read from fifo? #32

Open akda5id opened 2 months ago

akda5id commented 2 months ago

I'm poking around, and trying to understand how the fifo is set up. EDIT: Skip the rest of this comment, I have resolved most of my confusion in the second comment in the thread.

From the datasheet it seems you have to set fifo mode to bypass to clear the fifo after you read it, which seems to be sorta working, but I am not sure if this is how the reading is intended, I seem to always get "dead" data for the first sensor.acceleration() read. Is there a better way to read a chunk from the buffer? Is there a way to see how much is in the buffer? In my bogus test code below, I am intentionally reading too far, and just get duplicated data for the last item(s).

sensor.set_accel_mode_and_odr(
            &mut delay,
            lsm303agr::AccelMode::LowPower,
            lsm303agr::AccelOutputDataRate::Hz10,
        )
        .unwrap();

    let _ = sensor.acc_set_fifo_mode(lsm303agr::FifoMode::Fifo, 31);

    loop {
        for _ in 0..12 {
            let data = sensor.acceleration().unwrap();
            rprintln!(
                "x {} y {} z {}",
                data.x_mg(),
                data.y_mg(),
                data.z_mg()
            );
        }
        rprintln!(" ");
        let _ = sensor.acc_set_fifo_mode(lsm303agr::FifoMode::Bypass, 0);
        let _ = sensor.acc_set_fifo_mode(lsm303agr::FifoMode::Fifo, 31);

        delay.delay_ms(1000_u32);

     }
akda5id commented 2 months ago

Ok, a bit more poking around, and more careful reading of the datasheet, and turns out what I wanted was "Stream" mode not fifo. Now reading .acceleration() gets me the most recent data, and I can burst reads until the queue is empty, after which I get the same data as the last read. And not reseting the queue with Bypass anymore, of course.

I still wonder if there is a way to see the depth of the queue, I was thinking checking for .accel_status().unwrap().xyz_new_data() might be it, but looks like that flag gets cleared on the first read, and doesn't get reset until new data is written, which, yeah, is correct. I just have to know how deep I want to read I guess?