diff --git a/main/SENSORDATA.md b/main/SENSORDATA.md new file mode 100644 index 0000000..8bb43bf --- /dev/null +++ b/main/SENSORDATA.md @@ -0,0 +1,80 @@ +# MQTT message structure +## MSG Header +Every message. Total len 18 bytes. +```mermaid +block-beta + T["TIME
4 bytes
seconds"]:2 + Tm["TIME
4 bytes
useconds"]:2 + MAC["WIFI MAC
6 bytes"]:3 + GRP["Group id
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
motion energy"] + D["10 uint16
stationary energy"] +``` +
+ +## 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
float"]:1 + D["Temperature
float"]:1 + E["light
2 bytes"]:1 + F["humidity
float"]:1 + G["Number of data pairs
byte"]:1 + block:aa:3 + H["index 1
byte"] + I["gas resistance 1
float"] + J["..."] + end +``` + +
+ +# Notification messages + +## Pressure +Total len: 18 + 5 = 23 bytes +```mermaid +block-beta + MSG_HEADER + B["0x01"] + C["value
float"] +``` + +## Temperature +Total len: 18 + 5 = 23 bytes +```mermaid +block-beta + MSG_HEADER + B["0x02"] + C["value
float"] +``` + +## Humidity +Total len: 18 + 5 = 23 bytes +```mermaid +block-beta + MSG_HEADER + B["0x03"] + C["value
float"] +``` + +## Light +Total len: 18 + 3 = 21 bytes +```mermaid +block-beta + MSG_HEADER + B["0x04"] + C["value
2 bytes"] +``` diff --git a/main/SensorData.h b/main/SensorData.h index 64a7b56..4782632 100644 --- a/main/SensorData.h +++ b/main/SensorData.h @@ -1,12 +1,12 @@ /// © MiroZ 2024 #ifndef __SENSOR_DATA_H__ #define __SENSOR_DATA_H__ - #include + #pragma pack(push, 1) -struct MESSAGE_HEADER +struct MESSAGE_HEADER // 19 bytes { uint8_t type; uint32_t sec; @@ -22,12 +22,38 @@ struct MESSAGE_TYPE_VAL_REASON uint8_t reason; }; -struct RADAR +struct RADAR // 49 { uint8_t type; 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) #define HEADER_MESSAGE(name_) \ @@ -98,14 +124,25 @@ struct RADAR #define RADAR_MESSAGE_P(addr_) \ (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_PRESSURE 0x04 #define MESSAGE_TYPE_RADAR 0x37 #define MESSAGE_TYPE_LIGHT 0x06 #define MESSAGE_TYPE_TEMP 0x07 #define MESSAGE_TYPE_HUMIDITY 0x08 -#define MESSAGE_TYPE_GAS_IX 0x09 -#define MESSAGE_TYPE_GAS_VAL 0x0a +#define MESSAGE_TYPE_GAS_IX 0x09 // deprecated +#define MESSAGE_TYPE_GAS_VAL 0x0a // deprecated +#define MESSAGE_TYPE_GAS 0x0b +#define MESSAGE_TYPE_SENSOR_BLOCK 0x0c void createHeader(struct MESSAGE_HEADER * header); diff --git a/main/sensors/Bme68x.cpp b/main/sensors/Bme68x.cpp index 52a7bd4..aa16f1c 100644 --- a/main/sensors/Bme68x.cpp +++ b/main/sensors/Bme68x.cpp @@ -35,12 +35,16 @@ bool Bme68x::init() return m_operational; } - -void Bme68x::read(struct BME_DATA * data) +/// @brief +/// @param data +/// @return returns true when index 9 is read +bool Bme68x::read(struct BME_DATA * data) { MyLibs::bme68xData bdata; uint8_t left; + bool ret_val = false; + if(m_sensor->fetchData() > 0) { do @@ -50,13 +54,19 @@ void Bme68x::read(struct BME_DATA * data) if (bdata.status == NEW_GAS_MEAS) { int ix = _min(bdata.gas_index, 9); + + ESP_LOGW(TAG, "index: %d", ix); + + data->measurement_bitmask |= (1 << ix); if(ix == 0) data->humidity = bdata.humidity; + else if(ix == 9) + ret_val = true; data->measurement[ix].resistance = bdata.gas_resistance; - data->measurement[ix].temp = bdata.temperature; } } while(left > 0); } + return ret_val; } \ No newline at end of file diff --git a/main/sensors/Bme68x.h b/main/sensors/Bme68x.h index 5dbc06f..3db7ea1 100644 --- a/main/sensors/Bme68x.h +++ b/main/sensors/Bme68x.h @@ -9,13 +9,13 @@ struct GAS_MEASUREMENT { - float temp; float resistance; }; struct BME_DATA { float humidity; + uint16_t measurement_bitmask; struct GAS_MEASUREMENT measurement[10]; }; @@ -30,7 +30,7 @@ public: Bme68x(TwoWire & bus); bool init(); - void read(struct BME_DATA * data); + bool read(struct BME_DATA * data); }; #endif \ No newline at end of file diff --git a/main/sensors/SensorService.cpp b/main/sensors/SensorService.cpp index bca5864..77ad793 100644 --- a/main/sensors/SensorService.cpp +++ b/main/sensors/SensorService.cpp @@ -51,51 +51,105 @@ void SensorService::start() pinMode(LIGHT_SENSOR_PIN, INPUT); } +void SensorService::postBme68xData(float pressure, float temp) +{ + struct msg + { + struct MESSAGE_HEADER header; + struct OTHERS others; + struct GAS gas; + }; + + 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++) + { + if(m_bme_data.measurement_bitmask & (1 << n)) + { + 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 + if(light_value < min_light_val) + min_light_val = light_value; + + now = esp_timer_get_time(); + + if(now - last_time >= 2000000) // >= 2s + { + ESP_LOGI(TAG, "light: %d", min_light_val); + if(last_light_val >= 0) + { + if(abs(min_light_val - last_light_val) > 4096*5/100) + { + ESP_LOGI(TAG, "light tripped"); + struct msg + { + struct MESSAGE_HEADER header; + struct MESSAGE_TYPE_VAL_REASON light; + }; + + struct msg m; + HEADER_MESSAGE_P(&m.header); + LIGHT_MESSAGE_P(&m.light, min_light_val, 1); + m_app_if.getBuffer()->putBlock((uint8_t*)&m, sizeof(m)); + } + } + last_light_val = min_light_val; + m_light_value = min_light_val; + min_light_val = 0xffff; + last_time = now; + } +} + // handles pressure and voc sensor void SensorService::run_i2c_1() { - uint16_t light_val = 0xffff; - int last_light_val = -1; - uint64_t last_time = esp_timer_get_time(), now; - while(true) { m_bmp280->read(m_bmp_data.temp, m_bmp_data.pressure); - m_bme68x->read(&m_bme_data); + bool bme_cycle_finished = m_bme68x->read(&m_bme_data); uint16_t read_light_val = analogRead(LIGHT_SENSOR_PIN); - // handle light sensor - if(read_light_val < light_val) - light_val = read_light_val; - - now = esp_timer_get_time(); - - if(now - last_time >= 2000000) // >= 2s + if(bme_cycle_finished) { - ESP_LOGI(TAG, "light: %d", light_val); - if(last_light_val >= 0) - { - if(abs(light_val - last_light_val) > 4096*5/100) - { - ESP_LOGI(TAG, "light tripped"); - struct msg - { - struct MESSAGE_HEADER header; - struct MESSAGE_TYPE_VAL_REASON light; - }; - - struct msg m; - HEADER_MESSAGE_P(&m.header); - LIGHT_MESSAGE_P(&m.light, light_val, 1); - m_app_if.getBuffer()->putBlock((uint8_t*)&m, sizeof(m)); - } - } - last_light_val = light_val; - light_val = 0xffff; - last_time = now; + postBme68xData(m_bmp_data.pressure, m_bmp_data.temp); } - + processLight(read_light_val); + delay(10); } } diff --git a/main/sensors/SensorService.h b/main/sensors/SensorService.h index f7cad4e..3e7cc2a 100644 --- a/main/sensors/SensorService.h +++ b/main/sensors/SensorService.h @@ -28,6 +28,11 @@ protected: 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: SensorService(AppIF & app_if); void start();