... | ... | @@ -9,13 +9,13 @@ Here we will only consider reading the temperature data. |
|
|
|
|
|
## 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 only-read 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).
|
|
|
- _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.
|
|
|
- _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
|
|
|
#pragma once
|
... | ... | @@ -40,30 +40,31 @@ private: |
|
|
uint8_t odr;
|
|
|
uint8_t bdu;
|
|
|
|
|
|
const uint8_t WHO_AM_I_DEFAULT_VALUE = 63;
|
|
|
const uint8_t TEMPERATURE_REF = 25;
|
|
|
const uint8_t WHO_AM_I_VALUE = 63;
|
|
|
const uint8_t TEMPERATURE_REF = 25;
|
|
|
};
|
|
|
```
|
|
|
In order to configure the *ODR* and *BDU* values we can define two `enum` that contain all the possible values for those two variables. All these values can be found in the sensor's datasheet.
|
|
|
In order to configure the _ODR_ and _BDU_ values we can define two `enum` that contain all the possible values for those two variables. All these values can be found in the sensor's datasheet.
|
|
|
Since the default value of _ODR_ is `ODR_POWER_DOWN` we have to set a different value in order for the sensor to work.
|
|
|
|
|
|
```cpp
|
|
|
enum OutputDataRate : uint8_t
|
|
|
{
|
|
|
ODR_POWER_DOWN = 0, // 0000
|
|
|
ODR_3_125_HZ = 1, // 0001, 3.125 Hz
|
|
|
ODR_6_25_HZ = 2, // 0010, 6.25 Hz
|
|
|
ODR_12_5_HZ = 3, // 0011, 12.5 Hz
|
|
|
ODR_25_HZ = 4, // 0100
|
|
|
ODR_50_HZ = 5, // 0101
|
|
|
ODR_100_HZ = 6, // 0110, default value
|
|
|
ODR_400_HZ = 7, // 0111
|
|
|
ODR_800_HZ = 8, // 1000
|
|
|
ODR_1600_HZ = 9 // 1001
|
|
|
ODRPOWER_DOWN = 0, // default value
|
|
|
ODR_3_125_HZ = 1,
|
|
|
ODR_6_25_HZ = 2,
|
|
|
ODR_12_5_HZ = 3,
|
|
|
ODR_25_HZ = 4,
|
|
|
ODR_50_HZ = 5,
|
|
|
ODR_100_HZ = 6,
|
|
|
ODR_400_HZ = 7,
|
|
|
ODR_800_HZ = 8,
|
|
|
ODR_1600_HZ = 9
|
|
|
};
|
|
|
|
|
|
enum BlockDataUpdate : uint8_t
|
|
|
{
|
|
|
CONTINUOUS_UPDATE_MODE = 0, // continuous update of accelerometer data
|
|
|
CONTINUOUS_UPDATE_MODE = 0,
|
|
|
UPDATE_AFTER_READ_MODE = 1 // values updated only when MSB and LSB are read
|
|
|
};
|
|
|
```
|
... | ... | @@ -72,7 +73,7 @@ Finally in order to read the data from the sensor and to configure it we need so |
|
|
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 `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
|
... | ... | @@ -85,7 +86,7 @@ enum Registers : uint8_t |
|
|
```
|
|
|
|
|
|
## Cpp file
|
|
|
Import the header file and in the constructor simply initialized the *odr* and *bdu* members:
|
|
|
Import the header file and in the constructor simply initialize the *odr* and *bdu* members:
|
|
|
```cpp
|
|
|
#pragma once
|
|
|
|
... | ... | @@ -103,7 +104,7 @@ bool TempSensor::checkWhoAmI() |
|
|
{
|
|
|
uint8_t who_am_i = spi_driver.read(WHO_AM_I_REG);
|
|
|
|
|
|
if (who_am_i == WHO_AM_I_DEFAULT_VALUE)
|
|
|
if (who_am_i == WHO_AM_I_VALUE)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
... | ... | @@ -113,16 +114,16 @@ 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.
|
|
|
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.
|
|
|
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 |
|
|
|
|----------|----------|----------|----------|----------|------|------|------|
|
|
|
|
|
|
As we can se we have to shift the *BDU* value by 3 positions to the left and the *ODR* value by 4 position to the left. We can achieve this result through a *bitwise OR*.
|
|
|
|
|
|
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.
|
|
|
|
|
|
```cpp
|
... | ... | @@ -141,7 +142,7 @@ bool TempSensor::init() |
|
|
}
|
|
|
```
|
|
|
|
|
|
#### Read temperature
|
|
|
#### 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
|
|
|
int8_t TempSensor::getTemperature()
|
... | ... | @@ -154,8 +155,8 @@ int8_t TempSensor::getTemperature() |
|
|
```
|
|
|
|
|
|
## Create your entrypoint
|
|
|
In `src/entrypoints` add a file called `test-tempsensor.cpp`
|
|
|
|
|
|
In `src/entrypoints` add a file called `test-tempsensor.cpp`.
|
|
|
|
|
|
A simple entrypoint creates a `TempSensor` object and periodically reads the temperature value:
|
|
|
```cpp
|
|
|
#include <Common.h>
|
... | ... | |