Table of content

What is this :grey_question:

The rules of the game are explained in my original.

59th Challenge

Challenge

Build on yesterday’s example and actually read the temperature and the humidity from the sensor

Solution :white_check_mark:

Lets start from a template again, same folder as yesterday.

    cargo generate \
    --git https://github.com/stm32-rs/stm32wlxx-hal\
    --name stm32
    

The template, looks like this, when running tree -L 3

    .
    ├── CHANGELOG.md
    ├── Cargo.lock
    ├── Cargo.toml
    ├── LICENSE-APACHE
    ├── LICENSE-MIT
    ├── README.md
    ├── examples
    │   ├── Cargo.toml
    │   ├── examples
    │   └── src
    ├── hal
    │   ├── Cargo.toml
    │   └── src
    ├── lora-e5-bsp
    │   ├── Cargo.toml
    │   ├── README.md
    │   └── src
    ├── memory.x
    ├── nucleo-wl55jc-bsp
    │   ├── Cargo.toml
    │   ├── README.md
    │   └── src
    ├── rustfmt.toml
    └── testsuite
        ├── Cargo.toml
        ├── README.md
        ├── runall.py
        └── src
    

Lets revisit the commands. Yesterday we sucesfully read out the id of the sensor. Today we want to get some tempeperature readings.

| Command         | Value   |
| --------        | ------- |
| Sleep           | 0xB098  |
| Wakeup          | 0x3517  |
| measurement cmd | 0x7866  |
| readout id      | 0xEFC8  |

I actually used the measurement command with clock stretching that reads the rh value first. The formula for calculating the temp and humidity was taken from the datasheet.

    #![no_std]
    #![no_main]

    use defmt::unwrap;
    use defmt_rtt as _; // global logger
    use nucleo_wl55jc_bsp::hal::{
        cortex_m::{self, delay::Delay},
        embedded_hal::blocking::i2c::{WriteRead,Write,Read},
        gpio::{pins, Output, PinState,PortB,PortA},
        i2c::{I2c1},
        pac::{self},
        rcc,
        util::new_delay,
    };
    use panic_probe as _;

    const I2C_FREQUENCY: u32 = 100_000;

    #[defmt_test::tests]
    mod tests {
        use super::*;

        struct TestArgs {
            i2c: I2c1<(pins::A9, pins::A10)>,
            delay: Delay,
        }

        #[init]
        fn init() -> TestArgs {
            cortex_m::interrupt::free(|cs| {
                let mut dp: pac::Peripherals = unwrap!(pac::Peripherals::take());
                let cp: pac::CorePeripherals = defmt::unwrap!(pac::CorePeripherals::take());

                unsafe { rcc::set_sysclk_msi_max(&mut dp.FLASH, &mut dp.PWR, &mut dp.RCC, cs) };
                let gpioa: PortA = PortA::split(dp.GPIOA, &mut dp.RCC);
                let gpiob: PortB = PortB::split(dp.GPIOB, &mut dp.RCC);
     
                let mut sensor_power_enable: Output<pins::B12> =
                    cortex_m::interrupt::free(|cs| Output::default(gpiob.b12, cs));


                // Power the sensor
                sensor_power_enable.set_level(PinState::High);

                // wait for the sensor to be powered up
                let mut delay: Delay = new_delay(cp.SYST, &dp.RCC);
                delay.delay_us(240);

                let i2c = I2c1::new(
                    dp.I2C1,
                    (gpioa.a9, gpioa.a10),
                    I2C_FREQUENCY,
                    &mut dp.RCC,
                    false,
                    cs,
                    );

                TestArgs{
                    i2c,
                    delay
                }

            })
        }


        #[test]
        fn shtc3_measurement(ta: &mut TestArgs) {
            defmt::warn!("A SHTC3 sensor must be connected to the board on pins A9 (SCL) & A10 (SDA) for this test to work");

            let mut response: [u8; 6] = [0; 6];

            // send wake up command
            let result = ta.i2c.write(0x70, &[0x35, 0x17]);

            match result {
                Ok(()) => defmt::info!("SHTC3 was woken up"),
                Err(e) => defmt::error!("I2C error: {}", e),
            }

            // get sensor ID
            let result = ta.i2c.write_read(0x70, &[0xEF, 0xC8], &mut response);

            match result {
                Ok(()) => defmt::info!("SHTC3 ID = {:x} ",response),
                Err(e) => defmt::error!("I2C error: {}", e),
            }

            for _ in 1..10 {
                // get measurement read relative humditiy first and enable clock stretching
                let result = ta.i2c.write_read(0x70, &[0x5C, 0x24],&mut response);

                match result {
                    Ok(()) => {
                        defmt::info!("response:{:x}",response);
                        let relative_humidity = 100.0*((response[1] as u16 + ((response[0] as u16) << 8)) as f32)/65535.0;
                        let temperature = ((response[4] as u16 + ((response[3] as u16) << 8)) as f32)*175.0/65535.0 - 45.0;
                        defmt::info!("rh {}%", relative_humidity);
                        defmt::info!("temp {}°C", temperature);
                    },
                    Err(e) => defmt::error!("I2C error: {}", e),
                }
                ta.delay.delay_ms(100);
            }
        }

    }
    

When compiling and running DEFMT_LOG=info cargo test -p testsuite --target thumbv7em-none-eabi --bin gn_i2c we get the temperature and the humidity! yay, the crc I left untouched for now.

    ───────────────────────────────────────────────────────────────────────────────
    (1/1) running `shtc3_measurement`...
    └─ gn_i2c::tests::__defmt_test_entry @ src/gn_i2c.rs:68
    WARN  A SHTC3 sensor must be connected to the board on pins A9 (SCL) & A10 (SDA) for this test to work
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:69
    INFO  SHTC3 was woken up
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:77
    INFO  SHTC3 ID = [8, 87, 5b, ff, ff, ff] 
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:85
    INFO  response:[7d, 36, 99, 67, 9c, 3e]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.91127%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.827805°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    INFO  response:[7d, 41, f6, 67, a7, 11]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.928055%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.857178°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    INFO  response:[7d, 3b, d5, 67, 94, 87]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.9189%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.806442°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    INFO  response:[7d, 36, 99, 67, a1, b7]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.91127%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.841156°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    INFO  response:[7d, 37, a8, 67, a2, e4]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.912796%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.843826°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    INFO  response:[7d, 44, 3, 67, 99, cb]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.932632%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.819794°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    INFO  response:[7d, 31, e, 67, 9f, 6d]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.90364%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.835815°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    INFO  response:[7d, 42, a5, 67, af, a8]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.92958%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.87854°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    INFO  response:[7d, 2e, 63, 67, a2, e4]
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:95
    INFO  rh 48.899063%
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:98
    INFO  temp 25.843826°C
    └─ gn_i2c::tests::shtc3_measurement @ src/gn_i2c.rs:99
    all tests passed!
    └─ gn_i2c::tests::__defmt_test_entry @ src/gn_i2c.rs:19