SHT3x driver - some minor changes
- lookup tables made const to be held in flash - crc8 computation changed to a non table lookup version - measurement duration is now given in ticks and can be used directly for vTaskDelay (documentation and examples changed accordingly)
This commit is contained in:
parent
5a0fc09989
commit
1525f61fe3
5 changed files with 55 additions and 73 deletions
|
|
@ -17,7 +17,7 @@
|
||||||
* +------------------------+ +----------+
|
* +------------------------+ +----------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #define SINGLE_SHOT_MODE
|
#define SINGLE_SHOT_MODE
|
||||||
|
|
||||||
#include "espressif/esp_common.h"
|
#include "espressif/esp_common.h"
|
||||||
#include "esp/uart.h"
|
#include "esp/uart.h"
|
||||||
|
|
@ -55,7 +55,7 @@ void user_task (void *pvParameters)
|
||||||
|
|
||||||
// passive waiting until measurement results are available
|
// passive waiting until measurement results are available
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
vTaskDelay (duration/portTICK_PERIOD_MS);
|
vTaskDelay (duration);
|
||||||
|
|
||||||
// retrieve the values and do something with them
|
// retrieve the values and do something with them
|
||||||
if (sht3x_get_results (sensor, &values))
|
if (sht3x_get_results (sensor, &values))
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
* | GPIO 12 (SDA) ------- SDA |
|
* | GPIO 12 (SDA) ------- SDA |
|
||||||
* +------------------------+ +----------+
|
* +------------------------+ +----------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "espressif/esp_common.h"
|
#include "espressif/esp_common.h"
|
||||||
#include "esp/uart.h"
|
#include "esp/uart.h"
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ void user_task_sensor1 (void *pvParameters)
|
||||||
|
|
||||||
// passive waiting until measurement results are available
|
// passive waiting until measurement results are available
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
vTaskDelay (duration/portTICK_PERIOD_MS);
|
vTaskDelay (duration);
|
||||||
|
|
||||||
// retrieve the values and do something with them
|
// retrieve the values and do something with them
|
||||||
if (sht3x_get_results (sensor1, &values))
|
if (sht3x_get_results (sensor1, &values))
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ void user_task (void *pvParameters)
|
||||||
|
|
||||||
// passive waiting until first measurement results are available
|
// passive waiting until first measurement results are available
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
vTaskDelay (duration/portTICK_PERIOD_MS);
|
vTaskDelay (duration);
|
||||||
|
|
||||||
// busy waiting until first measurement results are available
|
// busy waiting until first measurement results are available
|
||||||
// while (sht3x_is_measuring (sensor) > 0) ;
|
// while (sht3x_is_measuring (sensor) > 0) ;
|
||||||
|
|
@ -140,7 +140,7 @@ void user_task (void *pvParameters)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
At the beginning of the task, the periodic measurement is started by function **_sht3x_start_measurement_** with a rate of 1 measurement per second. Using the measurement duration returned from this function, the task is delayed using **_vTaskDelay_** to wait for first measurement results. The busy waiting alternative using function **_sht3x_is_measuring_** is shown in comments. Inside the task loop, the measurement results are fetched periodically using function **_sht3x_get_results_** with a rate of once per second.
|
At the beginning of the task, the periodic measurement is started by function **_sht3x_start_measurement_** with a rate of 1 measurement per second. Using the measurement duration in RTOS ticks returned from this function, the task is delayed using **_vTaskDelay_** to wait for first measurement results. The busy waiting alternative using function **_sht3x_is_measuring_** is shown in comments. Inside the task loop, the measurement results are fetched periodically using function **_sht3x_get_results_** with a rate of once per second.
|
||||||
|
|
||||||
In the **single shot mode**, the measurement has to be triggered
|
In the **single shot mode**, the measurement has to be triggered
|
||||||
in each cycle. Waiting for measurement results is also required in each cylce, before the results can be fetched.
|
in each cycle. Waiting for measurement results is also required in each cylce, before the results can be fetched.
|
||||||
|
|
@ -162,7 +162,7 @@ void user_task (void *pvParameters)
|
||||||
|
|
||||||
// passive waiting until measurement results are available
|
// passive waiting until measurement results are available
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
vTaskDelay (duration/portTICK_PERIOD_MS);
|
vTaskDelay (duration);
|
||||||
|
|
||||||
// busy waiting until first measurement results are available
|
// busy waiting until first measurement results are available
|
||||||
// while (sht3x_is_measuring (sensor) > 0) ;
|
// while (sht3x_is_measuring (sensor) > 0) ;
|
||||||
|
|
@ -233,7 +233,7 @@ static sht3x_sensor_t* sensor; // sensor device data structure
|
||||||
/*
|
/*
|
||||||
* User task that fetches latest measurement results of sensor every 2
|
* User task that fetches latest measurement results of sensor every 2
|
||||||
* seconds. It starts the SHT3x in periodic mode with 1 measurements per
|
* seconds. It starts the SHT3x in periodic mode with 1 measurements per
|
||||||
* second (*periodic_1mps*). It uses busy waiting for first measurement
|
* second (*periodic_1mps*). It uses passive waiting for first measurement
|
||||||
* results.
|
* results.
|
||||||
*/
|
*/
|
||||||
void user_task (void *pvParameters)
|
void user_task (void *pvParameters)
|
||||||
|
|
@ -242,9 +242,10 @@ void user_task (void *pvParameters)
|
||||||
|
|
||||||
// start periodic measurements with 1 measurement per second
|
// start periodic measurements with 1 measurement per second
|
||||||
sht3x_start_measurement (sensor, periodic_1mps);
|
sht3x_start_measurement (sensor, periodic_1mps);
|
||||||
|
|
||||||
|
// passive waiting until measurement results are available
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
vTaskDelay (duration/portTICK_PERIOD_MS);
|
vTaskDelay (duration);
|
||||||
|
|
||||||
TickType_t last_wakeup = xTaskGetTickCount();
|
TickType_t last_wakeup = xTaskGetTickCount();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,14 +61,14 @@
|
||||||
#define SHT3x_FETCH_DATA_CMD 0xE000
|
#define SHT3x_FETCH_DATA_CMD 0xE000
|
||||||
#define SHT3x_HEATER_OFF_CMD 0x3066
|
#define SHT3x_HEATER_OFF_CMD 0x3066
|
||||||
|
|
||||||
uint16_t SHT3x_MEASURE_CMD[6][3] = { {0x2c06,0x2c0d,0x2c10}, // [SINGLE_SHOT][H,M,L]
|
const uint16_t SHT3x_MEASURE_CMD[6][3] = { {0x2c06,0x2c0d,0x2c10}, // [SINGLE_SHOT][H,M,L]
|
||||||
{0x2032,0x2024,0x202f}, // [PERIODIC_05][H,M,L]
|
{0x2032,0x2024,0x202f}, // [PERIODIC_05][H,M,L]
|
||||||
{0x2130,0x2126,0x212d}, // [PERIODIC_05][H,M,L]
|
{0x2130,0x2126,0x212d}, // [PERIODIC_05][H,M,L]
|
||||||
{0x2236,0x2220,0x222b}, // [PERIODIC_05][H,M,L]
|
{0x2236,0x2220,0x222b}, // [PERIODIC_05][H,M,L]
|
||||||
{0x2234,0x2322,0x2329}, // [PERIODIC_05][H,M,L]
|
{0x2234,0x2322,0x2329}, // [PERIODIC_05][H,M,L]
|
||||||
{0x2737,0x2721,0x272a} }; // [PERIODIC_05][H,M,L]
|
{0x2737,0x2721,0x272a} }; // [PERIODIC_05][H,M,L]
|
||||||
|
|
||||||
int32_t SHT3x_MEASURE_DURATION[3] = {30,20,20}; // [High, Medium, Low]
|
const int32_t SHT3x_MEASURE_DURATION[3] = {3,2,2}; // tick counts [High, Medium, Low]
|
||||||
|
|
||||||
#ifdef SHT3x_DEBUG
|
#ifdef SHT3x_DEBUG
|
||||||
#define debug(s, f, ...) printf("%s %s: " s "\n", "SHT3x", f, ## __VA_ARGS__)
|
#define debug(s, f, ...) printf("%s %s: " s "\n", "SHT3x", f, ## __VA_ARGS__)
|
||||||
|
|
@ -111,7 +111,7 @@ sht3x_sensor_t* sht3x_init_sensor(uint8_t bus, uint8_t addr)
|
||||||
dev->mode = single_shot;
|
dev->mode = single_shot;
|
||||||
dev->repeatability = high;
|
dev->repeatability = high;
|
||||||
dev->meas_started = false;
|
dev->meas_started = false;
|
||||||
dev->meas_start_time = 0;
|
dev->meas_start_tick = 0;
|
||||||
|
|
||||||
dev->active = true;
|
dev->active = true;
|
||||||
|
|
||||||
|
|
@ -149,10 +149,10 @@ int32_t sht3x_start_measurement (sht3x_sensor_t* dev, sht3x_mode_t mode)
|
||||||
// start measurement according to selected mode and return an duration estimate
|
// start measurement according to selected mode and return an duration estimate
|
||||||
if (sht3x_send_command(dev, SHT3x_MEASURE_CMD[dev->mode][dev->repeatability]))
|
if (sht3x_send_command(dev, SHT3x_MEASURE_CMD[dev->mode][dev->repeatability]))
|
||||||
{
|
{
|
||||||
dev->meas_start_time = sdk_system_get_time ();
|
dev->meas_start_tick = xTaskGetTickCount ();
|
||||||
dev->meas_started = true;
|
dev->meas_started = true;
|
||||||
dev->meas_first = true;
|
dev->meas_first = true;
|
||||||
return SHT3x_MEASURE_DURATION[dev->repeatability]; // in ms
|
return SHT3x_MEASURE_DURATION[dev->repeatability]; // in RTOS ticks
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->error_code |= SHT3x_SEND_MEAS_CMD_FAILED;
|
dev->error_code |= SHT3x_SEND_MEAS_CMD_FAILED;
|
||||||
|
|
@ -181,7 +181,7 @@ int32_t sht3x_is_measuring (sht3x_sensor_t* dev)
|
||||||
|
|
||||||
uint32_t elapsed_time;
|
uint32_t elapsed_time;
|
||||||
|
|
||||||
elapsed_time = (sdk_system_get_time() - dev->meas_start_time) / 1000; // in ms
|
elapsed_time = (xTaskGetTickCount() - dev->meas_start_tick); // in RTOS ticks
|
||||||
|
|
||||||
if (elapsed_time >= SHT3x_MEASURE_DURATION[dev->repeatability])
|
if (elapsed_time >= SHT3x_MEASURE_DURATION[dev->repeatability])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -371,46 +371,24 @@ static bool sht3x_get_status (sht3x_sensor_t* dev, uint16_t* status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t g_polynom = 0x31;
|
||||||
static uint8_t crc8_table[256]; // lookup table with precomputed crc values
|
|
||||||
static bool crc8_first_time = true; // indicator whether table has still to be created
|
|
||||||
|
|
||||||
static void generate_crc8_table()
|
|
||||||
{
|
|
||||||
const uint8_t g_polynom = 0x31;
|
|
||||||
|
|
||||||
for (int i=0; i < 256; i++)
|
|
||||||
{
|
|
||||||
uint8_t value = (uint8_t)i;
|
|
||||||
for (uint8_t bit = 0; bit < 8; bit++)
|
|
||||||
{
|
|
||||||
bool xor = value & 0x80;
|
|
||||||
value = value << 1;
|
|
||||||
value = xor ? value ^ g_polynom : value;
|
|
||||||
}
|
|
||||||
crc8_table[i] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint8_t crc8 (uint8_t data[], int len)
|
static uint8_t crc8 (uint8_t data[], int len)
|
||||||
{
|
{
|
||||||
// generate crc lookup table first time it is called
|
|
||||||
if (crc8_first_time)
|
|
||||||
{
|
|
||||||
crc8_first_time = false;
|
|
||||||
generate_crc8_table ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialization value
|
// initialization value
|
||||||
uint8_t crc = 0xff;
|
uint8_t crc = 0xff;
|
||||||
|
|
||||||
// iterate over all bytes
|
// iterate over all bytes
|
||||||
for (int i=0; i < len; i++)
|
for (int i=0; i < len; i++)
|
||||||
{
|
{
|
||||||
uint8_t b = data[i];
|
crc ^= data[i];
|
||||||
uint8_t data = (uint8_t)(b ^ crc);
|
|
||||||
crc = (uint8_t)(crc8_table[data]);
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
bool xor = crc & 0x80;
|
||||||
|
crc = crc << 1;
|
||||||
|
crc = xor ? crc ^ g_polynom : crc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ typedef struct {
|
||||||
sht3x_repeat_t repeatability; // used repeatability
|
sht3x_repeat_t repeatability; // used repeatability
|
||||||
|
|
||||||
bool meas_started; // indicates whether measurement started
|
bool meas_started; // indicates whether measurement started
|
||||||
uint32_t meas_start_time; // measurement start time in microseconds
|
TickType_t meas_start_tick; // measurement start time in RTOS ticks
|
||||||
bool meas_first; // first measurement in periodic mode
|
bool meas_first; // first measurement in periodic mode
|
||||||
|
|
||||||
} sht3x_sensor_t;
|
} sht3x_sensor_t;
|
||||||
|
|
@ -161,28 +161,31 @@ sht3x_sensor_t* sht3x_init_sensor (uint8_t bus, uint8_t addr);
|
||||||
* @brief Start single shot or periodic measurements
|
* @brief Start single shot or periodic measurements
|
||||||
*
|
*
|
||||||
* The function starts the measurement either in *single shot mode*
|
* The function starts the measurement either in *single shot mode*
|
||||||
* (exactly one measurement) or *periodic mode* (periodic measurements).
|
* (exactly one measurement) or *periodic mode* (periodic measurements) and
|
||||||
|
* returns an estimated measurement duration given in RTOS ticks.
|
||||||
*
|
*
|
||||||
* In the *single shot mode*, this function has to be called for each
|
* In the *single shot mode*, this function has to be called for each
|
||||||
* measurement. The measurement duration returned by the function has to be
|
* measurement. The measurement duration returned by the function has to be
|
||||||
* waited every time before the results can be fetched.
|
* waited every time before the results can be fetched.
|
||||||
*
|
*
|
||||||
* In the *periodic mode*, this function has to be called only once. Also the
|
* In the *periodic mode*, this function has to be called only once. Also
|
||||||
* measurement duration must be waited only once until the first results are
|
* the measurement duration must be waited only once until the first
|
||||||
* available. After this first measurement, the sensor then automatically
|
* results are available. After this first measurement, the sensor then
|
||||||
* performs all subsequent measurements. The rate of periodic measurements can
|
* automatically performs all subsequent measurements. The rate of periodic
|
||||||
* be 10, 4, 2, 1 or 0.5 measurements per second (mps). The user task can
|
* measurements can be 10, 4, 2, 1 or 0.5 measurements per second (mps). Due
|
||||||
* fetch the results with the half or less rate. The rate of the periodic
|
* to inaccuracies in timing of the sensor, the user task should fetch the
|
||||||
* measurements is defined by the parameter *mode*.
|
* results at a lower rate. The rate of the periodic measurements is defined
|
||||||
|
* by the parameter *mode*.
|
||||||
*
|
*
|
||||||
* On success, the function returns an estimated measurement duration. This
|
* On success, the function returns an estimated measurement duration given
|
||||||
* defines the duration needed by the sensor before first results become
|
* in RTOS ticks. This defines the duration needed by the sensor before
|
||||||
* available. The user task has to wait this time before it can fetch the
|
* first results become available. The user task has to wait this time
|
||||||
* results using function *sht3x_get_results* or *sht3x_get_raw_data*.
|
* before it can fetch the results using function *sht3x_get_results* or
|
||||||
|
* *sht3x_get_raw_data*.
|
||||||
*
|
*
|
||||||
* @param dev pointer to sensor device data structure
|
* @param dev pointer to sensor device data structure
|
||||||
* @param mode measurement mode, see type *sht3x_mode_t*
|
* @param mode measurement mode, see type *sht3x_mode_t*
|
||||||
* @return true on success, false on error
|
* @return measurement duration in RTOS ticks or -1 on error
|
||||||
*/
|
*/
|
||||||
int32_t sht3x_start_measurement (sht3x_sensor_t* dev, sht3x_mode_t mode);
|
int32_t sht3x_start_measurement (sht3x_sensor_t* dev, sht3x_mode_t mode);
|
||||||
|
|
||||||
|
|
@ -190,9 +193,9 @@ int32_t sht3x_start_measurement (sht3x_sensor_t* dev, sht3x_mode_t mode);
|
||||||
/**
|
/**
|
||||||
* @brief Check whether measurement is still running
|
* @brief Check whether measurement is still running
|
||||||
*
|
*
|
||||||
* The function can be used to test whether a measurement has been started
|
* The function can be used to test whether a measurement has been
|
||||||
* at all and how long it still takes before measurement results become
|
* started and how long it still takes before measurement results
|
||||||
* available. The return value can be
|
* become available. The return value is given in RTOS ticks and can be
|
||||||
*
|
*
|
||||||
* >0 in case the measurement is is still running,
|
* >0 in case the measurement is is still running,
|
||||||
* 0 in case the measurement has been already finished, or
|
* 0 in case the measurement has been already finished, or
|
||||||
|
|
@ -201,8 +204,8 @@ int32_t sht3x_start_measurement (sht3x_sensor_t* dev, sht3x_mode_t mode);
|
||||||
* That is, a return value greater than 0 indicates that the measurement
|
* That is, a return value greater than 0 indicates that the measurement
|
||||||
* results are still not available and the user task has to wait that time.
|
* results are still not available and the user task has to wait that time.
|
||||||
*
|
*
|
||||||
* @param dev pointer to sensor device data structure
|
* @param dev pointer to sensor device data structure
|
||||||
* @return remaining measurement duration or -1 on error
|
* @return remaining measurement duration in RTOS ticks or -1 on error
|
||||||
*/
|
*/
|
||||||
int32_t sht3x_is_measuring (sht3x_sensor_t* dev);
|
int32_t sht3x_is_measuring (sht3x_sensor_t* dev);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue