sensors stuff, mqtt message docs
This commit is contained in:
parent
5a82edc423
commit
2344f6efd0
80
main/SENSORDATA.md
Normal file
80
main/SENSORDATA.md
Normal 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"]
|
||||
```
|
||||
@ -1,12 +1,12 @@
|
||||
/// © MiroZ 2024
|
||||
#ifndef __SENSOR_DATA_H__
|
||||
#define __SENSOR_DATA_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user