Accelerometer as Puncho-o-meter | The “stm32-Discovery Board Sensor”- Part 2

Reading Time: 4 minutes

Hi everyone, I hope you all are doing fine. So what’s in today’s blog? In today’s blog, we are going to take our findings further. We are going to get the readings of the Accelerometer Sensor in a variable and then we are going to print them on the itm console using ITM.

As we are working with the Embedded Systems they make our task fast and reliable. Also, they are much smaller in size compared to traditional computers, which makes them compact and portable, and useful for mass production. Management of Embedded Systems is pretty easy, as elements used in their creation are cheap & long-lasting. Embedded Systems are also cost-effective.

How to Check Signal Drive Strength in SystemVerilog

I hope you have already read the previous blog that is PART 1 of this series. In that part, we have successfully accessed the peripherals of the hardware, the clocks of the Discovery Board, the i2c peripheral, and at last the lsm303dlhc package. The package will help us in accessing the Accelerometer Sensor and other sensors of the Discovery Board. Now this initialization of the code will return the itm, delay, and Lsm303dlhc.

THE CODE

///! Initialization code

#![no_std]

#[allow(unused_extern_crates)] // NOTE(allow) bug rust-lang/rust#53964
extern crate panic_itm; // panic handler

pub use cortex_m::{asm::bkpt, iprint, iprintln, peripheral::ITM};
pub use cortex_m_rt::entry;
pub use stm32f3_discovery::{
    lsm303dlhc::{self, I16x3, Sensitivity},
    stm32f3xx_hal::{delay::Delay, prelude, time::MonoTimer},
};

use stm32f3_discovery::stm32f3xx_hal::{
    gpio::gpiob::{PB6, PB7},
    gpio::AF4,
    i2c::I2c,
    prelude::*,
    stm32::{self, I2C1},
};

pub type Lsm303dlhc = lsm303dlhc::Lsm303dlhc<I2c<I2C1, (PB6<AF4>, PB7<AF4>)>>;
/// This program is going to provide the initialization to get and print the sensor readings with
/// some delay.
/// #Argument
/// None
///
/// #Return
/// This program is going to return a tuple of lsm-package, delay and itm.
/// Lsm303dlhc -> a package to access the accelerometer sensor to get the readings.
/// Delay -> a time delay to pause the running program for few seconds.
/// ITM -> a tool to print the sensor data on the itm console.
pub fn initialization() -> (Lsm303dlhc, Delay, ITM) {
    let cp = cortex_m::Peripherals::take().unwrap();
    let dp = stm32::Peripherals::take().unwrap();

    let mut flash = dp.FLASH.constrain();
    let mut rcc = dp.RCC.constrain();

    let clocks = rcc.cfgr.freeze(&mut flash.acr);

    let mut gpioe = dp.GPIOE.split(&mut rcc.ahb);
    let mut nss = gpioe
        .pe3
        .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper);
    nss.set_high().unwrap();

    let mut gpiob = dp.GPIOB.split(&mut rcc.ahb);
    let scl = gpiob.pb6.into_af4(&mut gpiob.moder, &mut gpiob.afrl);
    let sda = gpiob.pb7.into_af4(&mut gpiob.moder, &mut gpiob.afrl);

    let i2c = I2c::new(dp.I2C1, (scl, sda), 400.khz(), clocks, &mut rcc.apb1);

    let lsm303dlhc = Lsm303dlhc::new(i2c).expect("Cannot setup i2c in lsm303 package");

    let delay = Delay::new(cp.SYST, clocks);

    (lsm303dlhc, delay, cp.ITM)
}

Now it’s time to move ahead and get those readings with some delay on our itm console.

Binary with no_main and no_std

4 Ways to Fix “Windows Cannot Identify this Hardware” Code 9 Error

The architecture we work on in embedded development is different from the normal system. Therefore we don’t use the standard library here instead of that we use the core library which is a subset of the standard library.

Before moving to the reading we have to set the sensitivity of the accelerometer we can do it like this:

  let (mut lsm303dlhc, delay, mut itm) = initialization();
    match lsm303dlhc.set_accel_sensitivity(Sensitivity::G12) {
        Ok(senstivity) => senstivity,
        Err(err) => panic!("Can't set accelerometer senstivity {:?}", err),
    }

Now inside the loop we are going to get the readings in a struct I16x3 { x, y, z }

 const SENSITIVITY: f32 = 12. / (1 << 14) as f32;

        let I16x3 { x, y, z } = match lsm303dlhc.accel() {
            Ok(values) => values,
            Err(error) => panic!("Cannot get sensor readings {:?}", error),
        };

After this we need to calculate the readings of each of the axis(x, y, z) with the sensitivity using this:


        let x_axis = x as f32 * SENSITIVITY;
        let y_axis = y as f32 * SENSITIVITY;
        let z_axis = z as f32 * SENSITIVITY;

What’s left

Now we are done with the fetching game of the readings from the Microcontroller and now we just need to print these readings on the itm console using itm code.


        iprintln!(
            &mut itm.stim[0],
            "Accelerometer Readings \n x= {:?} y= {:?} z= {:?}",
            x_axis,
            y_axis,
            z_axis
        );

At last, we need to provide the delay to the fetching process so that we can collect those readings with some time gap.

     delay.delay_ms(1_000_u16);

This is going to provide the delay of 1 second to the whole (fetching and printing the data on console) process.

The Final Code

#![no_main]
#![no_std]

use cortex_m::asm;
use stm32f3_Accelerometer::config::initialization::*;
/// This program is going to print the Accelerometer sensor readings(x, y, z-axis) on the itm-dump console with
/// 9.26 sec of delay.
///
/// #Arguments
/// None
///
/// #Return
/// This is a no_std no_main code which will neither return nor stop.
#[entry]
fn main() -> ! {
    let (mut lsm303dlhc, delay, mut itm) = initialization();
    match lsm303dlhc.set_accel_sensitivity(Sensitivity::G12) {
        Ok(senstivity) => senstivity,
        Err(err) => panic!("Can't set accelerometer senstivity {:?}", err),
    }
    loop {
        const SENSITIVITY: f32 = 12. / (1 << 14) as f32;

        let I16x3 { x, y, z } = match lsm303dlhc.accel() {
            Ok(values) => values,
            Err(error) => panic!("Cannot get sensor readings {:?}", error),
        };

        let x_axis = x as f32 * SENSITIVITY;
        let y_axis = y as f32 * SENSITIVITY;
        let z_axis = z as f32 * SENSITIVITY;

        iprintln!(
            &mut itm.stim[0],
            "Accelerometer Readings \n x= {:?} y= {:?} z= {:?}",
            x_axis,
            y_axis,
            z_axis
        );

       delay.delay_ms(1_000_u16);
    }
}

We are done with the fetching of the Accelerometer Sensor’s readings. I hope you liked this part of the series. The template of these two parts is here, you can go through this if you face any problem anywhere. In the next blog, we will work towards our main goal that is to implement a Puncho-o-meter. Keep readings…

If you want to read more content like this?  Subscribe to Rust Times Newsletter and receive insights and latest updates, bi-weekly, straight into your inbox. Subscribe to Rust Times Newsletter: https://bit.ly/2Vdlld7.

rust-times

Knoldus-blog-footer-image

Written by 

Nitin is a Software Consultant, with experience of more than 7 months. He works on Rust Programming Language and Embedded Development using Rust. He is also fond of Java Programming & Artificial Intelligence. Apart from that, his hobbies are Watching Netflix, Reading, Singing & Writing.

1 thought on “Accelerometer as Puncho-o-meter | The “stm32-Discovery Board Sensor”- Part 26 min read

Comments are closed.