Table of content
What is this
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
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