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();