|
|
It's time to try out the SPI driver that we wrote in the previous tutorial.
|
|
|
|
|
|
This example uses the _LIS3DSH_ accelerometer and temperature sensor that is present on the STM32F407VG discovery board.
|
|
|
You can find an implementation for the accelerometer and the temperature sensor in `src/shared/sensors/LIS3DSH/LIS3DSH.h`.
|
|
|
It's time to try out the SPI driver that we wrote in the previous tutorial.
|
|
|
|
|
|
This example uses the _LIS3DSH_ accelerometer and temperature sensor that is present on the STM32F407VG discovery board.\
|
|
|
You can find an implementation for the accelerometer and the temperature sensor in `src/shared/sensors/LIS3DSH/LIS3DSH.h`.\
|
|
|
Here we will only consider reading the temperature data.
|
|
|
|
|
|
|
|
|
> :information_source: **Suggestion: keep the sensor's datasheet with you while following the tutorial and try to find in it all the things that here are mentioned. This datasheet is pretty simple and it's useful to start dealing with this type of documents.**
|
|
|
|
|
|
## Header file
|
|
|
|
|
|
We define the methods that we will be implemented in the `cpp` file:
|
|
|
|
|
|
- _init_: configure sensor driver. It returns a boolean indicating if the initialization was successful.
|
|
|
- _checkWhoAmI_: every sensor has a special read_only register that contains a number called `who_am_i`. This method checks that the `who_am_i` value is equal to the default one specified in the sensor's datasheet (which in this case is `63`). It returns a boolean indicating if the `who_am_i` value is correct.
|
|
|
- _getTemperature_: read the temperature from the sensor and return it. As described in the datasheet the temperature is an 8-bit 2-complement (`int8_t`) value with a resolution of 1 LSB/deg. It means that is can only output integer temperature values. Finally it is also told that reading zero from the sensor corresponds to 25 celsius degrees (so `TEMPERATURE_REF` is set to 25).
|
|
|
|
|
|
We also need two other memebers:
|
|
|
|
|
|
- _ODR_: it indicates the _output data rate_ of the sensor.
|
|
|
- _BDU_: it indicates the _block data update_ mode. This can be set to continuous mode (i.e. the sensor continuously produces samples) or we can configure the sensor so that it outputs a new sample only after the previous one has been read.
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
/* Copyright (c) <YEAR_HERE> Skyward Experimental Rocketry
|
|
|
* Author: <YOUR_NAME_HERE>
|
... | ... | @@ -98,12 +100,13 @@ enum BlockDataUpdate : uint8_t |
|
|
};
|
|
|
```
|
|
|
|
|
|
Finally in order to read the data from the sensor and to configure it we need some variables that indicate the sensor's registers addresses.
|
|
|
Finally in order to read the data from the sensor and to configure it we need some variables that indicate the sensor's registers addresses.\
|
|
|
The registers that we need are:
|
|
|
|
|
|
- The register that contains the `who_am_i` value.
|
|
|
- The register from which we can read the temperature values.
|
|
|
- The `CTRL_REG4` which is needed in order to configure the _ODR_ and _BDU_ values.
|
|
|
|
|
|
|
|
|
The registers addresses, of course, are specified in the sensor's datasheet.
|
|
|
|
|
|
```cpp
|
... | ... | @@ -117,7 +120,7 @@ enum Registers : uint8_t |
|
|
|
|
|
## Cpp file
|
|
|
|
|
|
Import the header file and in the constructor simply initialize the *odr* and *bdu* members:
|
|
|
Import the header file and in the constructor simply initialize the _odr_ and _bdu_ members:
|
|
|
|
|
|
```cpp
|
|
|
/* Copyright (c) <YEAR_HERE> Skyward Experimental Rocketry
|
... | ... | @@ -142,8 +145,6 @@ Import the header file and in the constructor simply initialize the *odr* and *b |
|
|
* THE SOFTWARE.
|
|
|
*/
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
#include "TempSensor.h"
|
|
|
|
|
|
namespace Boardcore
|
... | ... | @@ -156,6 +157,7 @@ TempSensor::TempSensor(uint8_t odr, uint8_t bdu) |
|
|
```
|
|
|
|
|
|
#### Check WHO_AM_I value
|
|
|
|
|
|
In order to check the `who_am_i` value we can simply ask the SPI driver to read the `WHO_AM_I` register. If the returned value is the correct one, than we can return `true` (otherwise `false`).
|
|
|
|
|
|
```cpp
|
... | ... | @@ -173,15 +175,41 @@ bool TempSensor::checkWhoAmI() |
|
|
```
|
|
|
|
|
|
#### Configure the sensor
|
|
|
|
|
|
During sensor's initialization, if the _checkWhoAmI_ method returns `false`, then the initialization fails.
|
|
|
|
|
|
To configure the _ODR_ and _BDU_ we have to set their values in the `CTRL_REG4` register of the sensor. We have to compute the value to be written to the register's address.
|
|
|
To configure the _ODR_ and _BDU_ we have to set their values in the `CTRL_REG4` register of the sensor. We have to compute the value to be written to the register's address.\
|
|
|
The `CTRL_REG4` register has the following 8-bits structure (LSB on the right and MSB on the left):
|
|
|
|
|
|
| **ODR3** | **ODR2** | **ODR1** | **ODR0** | **BDU** | Zen | Yen | Xen |
|
|
|
|----------|----------|----------|----------|----------|------|------|------|
|
|
|
<table>
|
|
|
<tr>
|
|
|
<th>
|
|
|
|
|
|
**ODR3**
|
|
|
</th>
|
|
|
<th>
|
|
|
|
|
|
**ODR2**
|
|
|
</th>
|
|
|
<th>
|
|
|
|
|
|
**ODR1**
|
|
|
</th>
|
|
|
<th>
|
|
|
|
|
|
As we can se we have to shift the *BDU* value by 3 positions to the left and the *ODR* value by 4 positions to the left. We can achieve this result through a *bitwise OR*.
|
|
|
**ODR0**
|
|
|
</th>
|
|
|
<th>
|
|
|
|
|
|
**BDU**
|
|
|
</th>
|
|
|
<th>Zen</th>
|
|
|
<th>Yen</th>
|
|
|
<th>Xen</th>
|
|
|
</tr>
|
|
|
</table>
|
|
|
|
|
|
As we can se we have to shift the _BDU_ value by 3 positions to the left and the _ODR_ value by 4 positions to the left. We can achieve this result through a _bitwise OR_.
|
|
|
|
|
|
Finally we can write the resulting value to the `CTRL_REG4` register's address using the SPI driver.
|
|
|
|
... | ... | @@ -202,6 +230,7 @@ bool TempSensor::init() |
|
|
```
|
|
|
|
|
|
#### Read the temperature
|
|
|
|
|
|
In order to read the temperature sample the only things we need is to read the `OUT_T` register through the SPI driver, rembering to add the `TEMPERATURE_REF` value to all the samples:
|
|
|
|
|
|
```cpp
|
... | ... | @@ -294,12 +323,11 @@ sbs_target(test-tempsensor stm32f407vg_stm32f4discovery) |
|
|
|
|
|
Same as before: you can use the SBS script to build with debug enabled and [flash](Flashing-on-a-Target-Board) the entrypoint:
|
|
|
|
|
|
```sh
|
|
|
```shell
|
|
|
./sbs -d -f test-tempsensor
|
|
|
```
|
|
|
|
|
|
## References
|
|
|
|
|
|
* [LIS3DSH datasheet](https://eu.mouser.com/datasheet/2/389/lis3dsh-954955.pdf)
|
|
|
|
|
|
* [LIS3DSH datasheet](https://eu.mouser.com/datasheet/2/389/lis3dsh-954955.pdf)
|
|
|
* [LIS3DSH Application Note](https://www.st.com/resource/en/application_note/dm00026768-lis3dsh-3axis-digital-output-accelerometer-stmicroelectronics.pdf) |
|
|
\ No newline at end of file |