sensors stuff, mqtt message docs

This commit is contained in:
Miro Zmrzli 2024-06-13 13:13:46 -07:00
parent 5a82edc423
commit 2344f6efd0
6 changed files with 230 additions and 44 deletions

80
main/SENSORDATA.md Normal file
View File

@ -0,0 +1,80 @@
# MQTT message structure
## MSG Header
Every message. Total len 18 bytes.
```mermaid
block-beta
T["<b>TIME</b><br>4 bytes<br>seconds"]:2
Tm["<b>TIME</b><br>4 bytes<br>useconds"]:2
MAC["WIFI MAC<br>6 bytes"]:3
GRP["Group id<br>4 bytes"]:2
```
# Block messages
## Radar message
Arrives every 10 seconds. Total len 49 + 18 = 67 bytes
```mermaid
block-beta
MSG_HEADER
B["0x10"]
C["14 uint16<br>motion energy"]
D["10 uint16<br>stationary energy"]
```
<br>
## Sensors message
Arrives every 10 seconds, when gas sensor data has been collected. Total len: 18 + 16 + 5 * number_data_pairs
```mermaid
block-beta
MSG_HEADER:1
B["0x11"]:1
C["Pressure<br>float"]:1
D["Temperature<br>float"]:1
E["light<br>2 bytes"]:1
F["humidity<br>float"]:1
G["Number of data pairs<br>byte"]:1
block:aa:3
H["index 1<br>byte"]
I["gas resistance 1<br>float"]
J["..."]
end
```
<br>
# Notification messages
## Pressure
Total len: 18 + 5 = 23 bytes
```mermaid
block-beta
MSG_HEADER
B["0x01"]
C["value<br>float"]
```
## Temperature
Total len: 18 + 5 = 23 bytes
```mermaid
block-beta
MSG_HEADER
B["0x02"]
C["value<br>float"]
```
## Humidity
Total len: 18 + 5 = 23 bytes
```mermaid
block-beta
MSG_HEADER
B["0x03"]
C["value<br>float"]
```
## Light
Total len: 18 + 3 = 21 bytes
```mermaid
block-beta
MSG_HEADER
B["0x04"]
C["value<br>2 bytes"]
```

View File

@ -1,12 +1,12 @@
/// © MiroZ 2024 /// © MiroZ 2024
#ifndef __SENSOR_DATA_H__ #ifndef __SENSOR_DATA_H__
#define __SENSOR_DATA_H__ #define __SENSOR_DATA_H__
#include <stdint.h> #include <stdint.h>
#pragma pack(push, 1) #pragma pack(push, 1)
struct MESSAGE_HEADER struct MESSAGE_HEADER // 19 bytes
{ {
uint8_t type; uint8_t type;
uint32_t sec; uint32_t sec;
@ -22,12 +22,38 @@ struct MESSAGE_TYPE_VAL_REASON
uint8_t reason; uint8_t reason;
}; };
struct RADAR struct RADAR // 49
{ {
uint8_t type; uint8_t type;
uint16_t vals[24]; uint16_t vals[24];
}; };
struct GAS_HEADER // 2 bytes
{
uint8_t type;
uint8_t num_measurements;
};
struct GAS_DATA //5 bytes
{
uint8_t index;
float gas_resistance;
};
struct OTHERS
{
float pressure;
float temp;
uint16_t light;
};
struct GAS // 6 + num_gas_data * 5
{
struct GAS_HEADER header;
float humidity;
struct GAS_DATA data[0];
};
#pragma pack(pop) #pragma pack(pop)
#define HEADER_MESSAGE(name_) \ #define HEADER_MESSAGE(name_) \
@ -98,14 +124,25 @@ struct RADAR
#define RADAR_MESSAGE_P(addr_) \ #define RADAR_MESSAGE_P(addr_) \
(addr_)->type = MESSAGE_TYPE_RADAR; (addr_)->type = MESSAGE_TYPE_RADAR;
#define GAS_MESSAGE(name_, num_vals_) \
struct GAS name_; \
name_.header.type = MESSAGE_TYPE_GAS; \
name_.header.num_measurements = num_vals_;
#define GAS_MESSAGE_P(addr_, num_vals_) \
(addr_)->header.type = MESSAGE_TYPE_GAS; \
(addr_)->header.num_measurements = num_vals_;
#define MESSAGE_TYPE_HEADER 0xa5 #define MESSAGE_TYPE_HEADER 0xa5
#define MESSAGE_TYPE_PRESSURE 0x04 #define MESSAGE_TYPE_PRESSURE 0x04
#define MESSAGE_TYPE_RADAR 0x37 #define MESSAGE_TYPE_RADAR 0x37
#define MESSAGE_TYPE_LIGHT 0x06 #define MESSAGE_TYPE_LIGHT 0x06
#define MESSAGE_TYPE_TEMP 0x07 #define MESSAGE_TYPE_TEMP 0x07
#define MESSAGE_TYPE_HUMIDITY 0x08 #define MESSAGE_TYPE_HUMIDITY 0x08
#define MESSAGE_TYPE_GAS_IX 0x09 #define MESSAGE_TYPE_GAS_IX 0x09 // deprecated
#define MESSAGE_TYPE_GAS_VAL 0x0a #define MESSAGE_TYPE_GAS_VAL 0x0a // deprecated
#define MESSAGE_TYPE_GAS 0x0b
#define MESSAGE_TYPE_SENSOR_BLOCK 0x0c
void createHeader(struct MESSAGE_HEADER * header); void createHeader(struct MESSAGE_HEADER * header);

View File

@ -35,12 +35,16 @@ bool Bme68x::init()
return m_operational; return m_operational;
} }
/// @brief
void Bme68x::read(struct BME_DATA * data) /// @param data
/// @return returns true when index 9 is read
bool Bme68x::read(struct BME_DATA * data)
{ {
MyLibs::bme68xData bdata; MyLibs::bme68xData bdata;
uint8_t left; uint8_t left;
bool ret_val = false;
if(m_sensor->fetchData() > 0) if(m_sensor->fetchData() > 0)
{ {
do do
@ -51,12 +55,18 @@ void Bme68x::read(struct BME_DATA * data)
{ {
int ix = _min(bdata.gas_index, 9); int ix = _min(bdata.gas_index, 9);
ESP_LOGW(TAG, "index: %d", ix);
data->measurement_bitmask |= (1 << ix);
if(ix == 0) if(ix == 0)
data->humidity = bdata.humidity; data->humidity = bdata.humidity;
else if(ix == 9)
ret_val = true;
data->measurement[ix].resistance = bdata.gas_resistance; data->measurement[ix].resistance = bdata.gas_resistance;
data->measurement[ix].temp = bdata.temperature;
} }
} while(left > 0); } while(left > 0);
} }
return ret_val;
} }

View File

@ -9,13 +9,13 @@
struct GAS_MEASUREMENT struct GAS_MEASUREMENT
{ {
float temp;
float resistance; float resistance;
}; };
struct BME_DATA struct BME_DATA
{ {
float humidity; float humidity;
uint16_t measurement_bitmask;
struct GAS_MEASUREMENT measurement[10]; struct GAS_MEASUREMENT measurement[10];
}; };
@ -30,7 +30,7 @@ public:
Bme68x(TwoWire & bus); Bme68x(TwoWire & bus);
bool init(); bool init();
void read(struct BME_DATA * data); bool read(struct BME_DATA * data);
}; };
#endif #endif

View File

@ -51,31 +51,68 @@ void SensorService::start()
pinMode(LIGHT_SENSOR_PIN, INPUT); pinMode(LIGHT_SENSOR_PIN, INPUT);
} }
// handles pressure and voc sensor void SensorService::postBme68xData(float pressure, float temp)
void SensorService::run_i2c_1()
{ {
uint16_t light_val = 0xffff; struct msg
int last_light_val = -1; {
uint64_t last_time = esp_timer_get_time(), now; struct MESSAGE_HEADER header;
struct OTHERS others;
struct GAS gas;
};
while(true) uint8_t msg_buffer[100];
struct msg *data_to_send = (struct msg *)msg_buffer;
HEADER_MESSAGE_P(&data_to_send->header);
GAS_MESSAGE_P(&data_to_send->gas, 0);
data_to_send->others.light = m_light_value;
data_to_send->others.pressure = pressure;
data_to_send->others.temp = temp;
int num_total = 0;
struct GAS_DATA * p = data_to_send->gas.data;
for(int n = 0; n < 10; n++)
{ {
m_bmp280->read(m_bmp_data.temp, m_bmp_data.pressure); if(m_bme_data.measurement_bitmask & (1 << n))
m_bme68x->read(&m_bme_data); {
uint16_t read_light_val = analogRead(LIGHT_SENSOR_PIN); p[num_total].gas_resistance = m_bme_data.measurement[n].resistance;
p[num_total++].index = n;
}
}
data_to_send->gas.header.num_measurements = num_total;
data_to_send->gas.humidity = m_bme_data.humidity;
m_app_if.getBuffer()->putBlock((uint8_t*)&data_to_send, sizeof(*data_to_send) + num_total * sizeof(struct GAS_DATA));
// clear the blackboard
memset(&m_bme_data, 0, sizeof(m_bme_data));
}
/// @brief Actual light value is minimum in 2s window
/// @param light_value
void SensorService::processLight(int light_value)
{
static uint16_t min_light_val = 0xffff;
static int last_light_val = -1;
static uint64_t last_time = esp_timer_get_time();
uint64_t now;
// handle light sensor // handle light sensor
if(read_light_val < light_val) if(light_value < min_light_val)
light_val = read_light_val; min_light_val = light_value;
now = esp_timer_get_time(); now = esp_timer_get_time();
if(now - last_time >= 2000000) // >= 2s if(now - last_time >= 2000000) // >= 2s
{ {
ESP_LOGI(TAG, "light: %d", light_val); ESP_LOGI(TAG, "light: %d", min_light_val);
if(last_light_val >= 0) if(last_light_val >= 0)
{ {
if(abs(light_val - last_light_val) > 4096*5/100) if(abs(min_light_val - last_light_val) > 4096*5/100)
{ {
ESP_LOGI(TAG, "light tripped"); ESP_LOGI(TAG, "light tripped");
struct msg struct msg
@ -86,15 +123,32 @@ void SensorService::run_i2c_1()
struct msg m; struct msg m;
HEADER_MESSAGE_P(&m.header); HEADER_MESSAGE_P(&m.header);
LIGHT_MESSAGE_P(&m.light, light_val, 1); LIGHT_MESSAGE_P(&m.light, min_light_val, 1);
m_app_if.getBuffer()->putBlock((uint8_t*)&m, sizeof(m)); m_app_if.getBuffer()->putBlock((uint8_t*)&m, sizeof(m));
} }
} }
last_light_val = light_val; last_light_val = min_light_val;
light_val = 0xffff; m_light_value = min_light_val;
min_light_val = 0xffff;
last_time = now; last_time = now;
} }
}
// handles pressure and voc sensor
void SensorService::run_i2c_1()
{
while(true)
{
m_bmp280->read(m_bmp_data.temp, m_bmp_data.pressure);
bool bme_cycle_finished = m_bme68x->read(&m_bme_data);
uint16_t read_light_val = analogRead(LIGHT_SENSOR_PIN);
if(bme_cycle_finished)
{
postBme68xData(m_bmp_data.pressure, m_bmp_data.temp);
}
processLight(read_light_val);
delay(10); delay(10);
} }

View File

@ -28,6 +28,11 @@ protected:
AppIF & m_app_if; AppIF & m_app_if;
void postBme68xData(float pressure, float temp);
void processLight(int light_value);
void processHumidity(float humidity);
uint16_t m_light_value = 0;
public: public:
SensorService(AppIF & app_if); SensorService(AppIF & app_if);
void start(); void start();