file/class refactoring and cleanup, sensor service development, added light sensor notification

This commit is contained in:
Miro Zmrzli 2024-06-12 15:02:23 -07:00
commit 5a82edc423
17 changed files with 175 additions and 124 deletions

View File

@ -82,16 +82,16 @@ void App::init()
m_led->setPulse(255, 0, 255);
m_mqtt = new Mqtt(*this);
m_mqtt->start();
m_mqtt_service = new MqttService(*this);
m_mqtt_service->start();
m_ble = new Ble(*this);
m_ble->start();
m_ble_service = new BleService(*this);
m_ble_service->start();
#endif
m_sensors = new Sensors(*this);
m_sensors->start();
m_sensor_service = new SensorService(*this);
m_sensor_service->start();
}
void App::otaCheck()

View File

@ -8,19 +8,19 @@
#include "Settings.h"
#include "Led.h"
#include "Wifi.h"
#include "Mqtt.h"
#include "Ble.h"
#include "MqttService.h"
#include "BleService.h"
#include "Buffers.h"
#include "sensors/Sensors.h"
#include "sensors/SensorService.h"
#include "AppIF.h"
class App : AppIF
{
protected:
Wifi * m_wifi = nullptr;
Mqtt * m_mqtt = nullptr;
Ble * m_ble = nullptr;
Sensors * m_sensors = nullptr;
MqttService * m_mqtt_service = nullptr;
BleService * m_ble_service = nullptr;
SensorService * m_sensor_service = nullptr;
CircBuffer m_circ_buffer;
Led * m_led = nullptr;

View File

@ -5,21 +5,21 @@
#include <WiFi.h>
#include "ReaderWriter.h"
#include "Ble.h"
#include "BleService.h"
static const char * TAG = "ble";
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
Ble::Ble(App & app) : m_app(app)
BleService::BleService(App & app) : m_app(app)
{
m_rw = new ReaderWriter(512);
}
void Ble::start()
void BleService::start()
{
ESP_LOGW(TAG, "Starting BLE...");
ESP_LOGW(TAG, "Starting ble service...");
uint8_t wifi_mac[8];
esp_read_mac(wifi_mac, ESP_MAC_WIFI_STA);
@ -27,14 +27,18 @@ void Ble::start()
sprintf(m_name, "WP_%u_%02x%02x%02x", SETTINGS.device.id, wifi_mac[3], wifi_mac[4], wifi_mac[5]);
NimBLEDevice::init(m_name);
NimBLEDevice::setMTU(512);
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
// NimBLEDevice::setSecurityAuth(BLE_SM_PAIR_AUTHREQ_SC);
m_server = NimBLEDevice::createServer();
m_server->setCallbacks(this);
m_service = m_server->createService(SERVICE_UUID);
m_characteristic = m_service->createCharacteristic(CHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY);
m_characteristic = m_service->createCharacteristic(CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::NOTIFY);
m_characteristic->setCallbacks(this);
// NimBLE2904 * desc = (NimBLE2904*)m_characteristic->createDescriptor("2904");
// desc->setFormat(NimBLE2904::FORMAT_UTF8);
@ -47,39 +51,33 @@ void Ble::start()
m_advertising->start();
}
void Ble::onConnect(NimBLEServer* pServer)
void BleService::onConnect(NimBLEServer* pServer)
{
// uint16_t id = pServer->getConnId();
// ESP_LOGI(TAG, "%d connected", id);
ESP_LOGI(TAG, "connected");
}
void Ble::onDisconnect(NimBLEServer* pServer)
void BleService::onDisconnect(NimBLEServer* pServer)
{
// uint16_t id = pServer->getConnId();
// ESP_LOGI(TAG, "%d disconnected", id);
ESP_LOGI(TAG, "disconnected");
NimBLEDevice::startAdvertising();
// m_advertising->start();
}
void Ble::onRead(NimBLECharacteristic* pCharacteristic)
void BleService::onRead(NimBLECharacteristic* pCharacteristic)
{
int a = 1234;
pCharacteristic->setValue(a);
ESP_LOGI(TAG, "onRead hello");
}
char buf[512];
void Ble::onWrite(NimBLECharacteristic* pCharacteristic)
void BleService::onWrite(NimBLECharacteristic* pCharacteristic)
{
uint32_t len = pCharacteristic->getDataLength();
memcpy(buf, pCharacteristic->getValue().c_str(), len);
buf[len] = 0;
memcpy(m_buffer, pCharacteristic->getValue().c_str(), len);
m_buffer[len] = 0;
ESP_LOGI(TAG, "'%s'", buf);
ESP_LOGI(TAG, "'%s'", m_buffer);
Parser p((char *)buf, "|");
Parser p((char *)m_buffer, "|");
char buffer[80];
p.getElementAt(0, buffer, sizeof(buffer));

View File

@ -9,12 +9,13 @@
class App;
class Ble : public NimBLEServerCallbacks, NimBLECharacteristicCallbacks
class BleService : public NimBLEServerCallbacks, NimBLECharacteristicCallbacks
{
protected:
App & m_app;
char m_name[32];
char m_buffer[512];
NimBLEServer * m_server = nullptr;
NimBLEService * m_service = nullptr;
@ -29,7 +30,7 @@ protected:
public:
Ble(App & app);
BleService(App & app);
void start();
};

View File

@ -34,16 +34,16 @@ public:
CountingSemaphore getSemaphore(){ return m_data_available_semaphore; }
bool put_block(uint8_t * data, uint8_t len)
bool putBlock(uint8_t * data, uint8_t len)
{
m_mutex.take();
bool ret_val = true;
if(m_total_size - size(false) >= len)
{
put_val(len);
putVal(len);
for(int n = 0; n < len; n++)
put_val(data[n]);
putVal(data[n]);
}
else
ret_val = false;
@ -56,16 +56,21 @@ public:
return ret_val;
}
bool get_block(uint8_t * data, uint8_t & len)
bool waitForDataAvailable(uint32_t ticks = portMAX_DELAY)
{
return m_data_available_semaphore.take(ticks);
}
bool getBlock(uint8_t * data, uint8_t & len)
{
m_mutex.take();
bool ret_val = true;
if(size(false) >= 2)
{
get_val(len);
getVal(len);
for(int n = 0; n < len; n++)
get_val(data[n]);
getVal(data[n]);
}
else
ret_val = false;
@ -75,13 +80,13 @@ public:
return ret_val;
}
bool peek_block_len(uint8_t & len)
bool peekBlockLen(uint8_t & len)
{
return peek_val(len);
return peekVal(len);
}
protected:
bool put_val(uint8_t item)
bool putVal(uint8_t item)
{
if (full_)
return false;
@ -96,7 +101,7 @@ protected:
return true;
}
bool get_val(uint8_t & val)
bool getVal(uint8_t & val)
{
if ((!full_ && (head_ == tail_)))
return false;
@ -110,7 +115,7 @@ protected:
return true;
}
bool peek_val(uint8_t & val)
bool peekVal(uint8_t & val)
{
if ((!full_ && (head_ == tail_)))
return false;

View File

@ -1,6 +1,6 @@
idf_component_register(SRCS main.cpp App.cpp Settings.cpp Led.cpp TaskMgr.cpp Wifi.cpp utilities.cpp
ProvisionSoftAP.cpp ReaderWriter.cpp Ota.cpp Mqtt.cpp Ble.cpp sensors/Bmp280.cpp
sensors/Bme68x.cpp sensors/Sensors.cpp sensors/LD2410.cpp Buffers.cpp SensorData.cpp
ProvisionSoftAP.cpp ReaderWriter.cpp Ota.cpp MqttService.cpp BleService.cpp sensors/Bmp280.cpp
sensors/Bme68x.cpp sensors/SensorService.cpp sensors/LD2410.cpp Buffers.cpp SensorData.cpp
INCLUDE_DIRS "."
EMBED_TXTFILES ../html/logo.png ../html/provision.html
EMBED_TXTFILES ../certs/eventgrid.azure.pem ../certs/client1-authn-ID.key ../certs/client1-authn-ID.pem ../certs/bigfoot-inc.pem

View File

@ -1,6 +1,6 @@
/// © MiroZ 2024
#include "Mqtt.h"
#include "MqttService.h"
#include <esp_log.h>
#include "TaskMgr.h"
@ -13,28 +13,29 @@ static const int mqtt_port = 8883;
static const char * TAG = "mqtts";
void Mqtt::callback(char* topic, uint8_t * payload, uint32_t length)
void MqttService::callback(char* topic, uint8_t * payload, uint32_t length)
{
ESP_LOGI(TAG, "Message arrived in topic: %s\n", topic);
payload[length] = 0;
ESP_LOGW(TAG, "%s", (char*)payload);
}
Mqtt::Mqtt(AppIF & app_if) : m_app_if(app_if)
MqttService::MqttService(AppIF & app_if) : m_app_if(app_if)
{
}
uint8_t buffer[256];
void Mqtt::task()
void MqttService::task()
{
while(true)
{
if(m_app_if.getBuffer()->getSemaphore().take(5000)) // wait for the data to become available
// if(m_app_if.getBuffer()->getSemaphore().take(5000)) // wait for the data to become available
if(m_app_if.getBuffer()->waitForDataAvailable(5000))
{
uint8_t len = 0;
if(m_app_if.getBuffer()->get_block(buffer, len))
if(m_app_if.getBuffer()->getBlock(buffer, len))
{
ESP_LOGI(TAG, "got data, len %d", len);
@ -76,9 +77,9 @@ void Mqtt::task()
}
}
void Mqtt::start()
void MqttService::start()
{
ESP_LOGW(TAG, "Starting mqtt...");
ESP_LOGW(TAG, "Starting mqtt service...");
m_esp_client = new WiFiClientSecure();
m_mqtt_client = new PubSubClient(*m_esp_client);
@ -88,9 +89,9 @@ void Mqtt::start()
m_esp_client->setPrivateKey((const char *)client_key); // for client verification
m_mqtt_client->setServer(mqtt_broker, mqtt_port);
m_mqtt_client->setCallback(std::bind(&Mqtt::callback, this, _1, _2, _3));
m_mqtt_client->setCallback(std::bind(&MqttService::callback, this, _1, _2, _3));
m_mqtt_client->setKeepAlive(30);
m_mqtt_client->setSocketTimeout(30);
m_task = TaskMgr::getInstance().createTask(std::bind(&Mqtt::task, this), MQTT_TASK_NAME, MQTT_TASK_STACK_SIZE, MQTT_TASK_PRIORITY, MQTT_TASK_CORE);
m_task = TaskMgr::getInstance().createTask(std::bind(&MqttService::task, this), MQTT_TASK_NAME, MQTT_TASK_STACK_SIZE, MQTT_TASK_PRIORITY, MQTT_TASK_CORE);
}

View File

@ -17,7 +17,7 @@ extern const uint8_t client_key[] asm("_binary_client1_authn_ID_key_start");
using namespace std::placeholders;
class Mqtt
class MqttService
{
protected:
WiFiClientSecure *m_esp_client;
@ -29,7 +29,7 @@ protected:
AppIF & m_app_if;
public:
Mqtt(AppIF & app_if);
MqttService(AppIF & app_if);
void start();
};

View File

@ -43,8 +43,8 @@ struct RADAR
name_.val = val_; name_.reason = reason_;
#define PRESSURE_MESSAGE_P(addr_, val_, reason_) \
addr->type = MESSAGE_TYPE_PRESSURE; \
addr->val = val_; addr->reason = reason_;
(addr)->type = MESSAGE_TYPE_PRESSURE; \
(addr)->val = val_; (addr)->reason = reason_;
#define LIGHT_MESSAGE(name_, val_, reason_) \
struct MESSAGE_TYPE_VAL_REASON name_; \
@ -52,8 +52,8 @@ struct RADAR
name_.val = val_; name_.reason = reason_;
#define LIGHT_MESSAGE_P(addr_, val_, reason_) \
addr_->type = MESSAGE_TYPE_LIGHT; \
addr_->val = val_; addr_->reason = reason_;
(addr_)->type = MESSAGE_TYPE_LIGHT; \
(addr_)->val = val_; (addr_)->reason = reason_;
#define TEMP_MESSAGE(name_, val_, reason_) \
struct MESSAGE_TYPE_VAL_REASON name_; \
@ -61,8 +61,8 @@ struct RADAR
name_.val = val_; name_.reason = reason_;
#define TEMP_MESSAGE_P(addr_, val_, reason_) \
addr_->type = MESSAGE_TYPE_TEMP; \
addr_->val = val_; addr_->reason = reason_;
(addr_)->type = MESSAGE_TYPE_TEMP; \
(addr_)->val = val_; (addr_)->reason = reason_;
#define HUM_MESSAGE(name_, val_, reason_) \
struct MESSAGE_TYPE_VAL_REASON name_; \
@ -70,8 +70,8 @@ struct RADAR
name_.val = val_; name_.reason = reason_;
#define HUM_MESSAGE_P(addr_, val_, reason_) \
addr_->type = MESSAGE_TYPE_HUMIDITY; \
addr_->val = val_; addr_->reason = reason_;
(addr_)->type = MESSAGE_TYPE_HUMIDITY; \
(addr_)->val = val_; (addr_)->reason = reason_;
#define GAS_IX_MESSAGE(name_, val_, reason_) \
struct MESSAGE_TYPE_VAL_REASON name_; \
@ -79,8 +79,8 @@ struct RADAR
name_.val = val_; name_.reason = reason_;
#define GAS_IX_MESSAGE_P(addr_, val_, reason_) \
addr_->type = MESSAGE_TYPE_GAS_IX; \
addr_->val = val_; addr_->reason = reason_;
(addr_)->type = MESSAGE_TYPE_GAS_IX; \
(addr_)->val = val_; (addr_)->reason = reason_;
#define GAS_VAL_MESSAGE(name_, val_, reason_) \
struct MESSAGE_TYPE_VAL_REASON name_; \
@ -88,8 +88,8 @@ struct RADAR
name_.val = val_; name_.reason = reason_;
#define GAS_VAL_MESSAGE_P(addr_, val_, reason_) \
addr_->type = MESSAGE_TYPE_GAS_VAL; \
addr_->val = val_; addr_->reason = reason_;
(addr_)->type = MESSAGE_TYPE_GAS_VAL; \
(addr_)->val = val_; (addr_)->reason = reason_;
#define RADAR_MESSAGE(name_) \
struct RADAR name_; \

View File

@ -28,19 +28,7 @@
#define TASKMGR_TASK_STACK_SIZE 2048
#define TASKMGR_TASK_PRIORITY 5
#define TASKMGR_TASK_CORE 1
#define TASKMGR_TASK_DELAY 15000 //was 60s
// i2cbus_1 task
#define I2C1_TASK_NAME "i2cbus_1"
#define I2C1_TASK_STACK_SIZE 3000
#define I2C1_TASK_PRIORITY 5
#define I2C1_TASK_CORE 0
// uart task
#define UART_TASK_NAME "uart"
#define UART_TASK_STACK_SIZE 3000
#define UART_TASK_PRIORITY 5
#define UART_TASK_CORE 1
#define TASKMGR_TASK_DELAY 30000 //was 60s
// i2cbus_1 task
#define I2C1_TASK_NAME "i2cbus_1"

View File

@ -27,8 +27,6 @@ bool Bme68x::init()
/* Shared heating duration in milliseconds */
uint16_t sharedHeatrDur = MEAS_DUR - (m_sensor->getMeasDur(BME68X_PARALLEL_MODE) / 1000);
// ESP_LOGI(TAG, "sharedHeatrDur:%d", sharedHeatrDur);
m_sensor->setHeaterProf(tempProf, mulProf, sharedHeatrDur, 10);
m_sensor->setOpMode(BME68X_PARALLEL_MODE);
@ -38,7 +36,7 @@ bool Bme68x::init()
}
void Bme68x::read()
void Bme68x::read(struct BME_DATA * data)
{
MyLibs::bme68xData bdata;
uint8_t left;
@ -51,10 +49,13 @@ void Bme68x::read()
if (bdata.status == NEW_GAS_MEAS)
{
ESP_LOGI(TAG, "temp: %f", bdata.temperature);
ESP_LOGI(TAG, " hum: %f", bdata.humidity);
ESP_LOGI(TAG, "gres: %f", bdata.gas_resistance);
ESP_LOGI(TAG, " ix: %d", bdata.gas_index);
int ix = _min(bdata.gas_index, 9);
if(ix == 0)
data->humidity = bdata.humidity;
data->measurement[ix].resistance = bdata.gas_resistance;
data->measurement[ix].temp = bdata.temperature;
}
} while(left > 0);
}

View File

@ -7,6 +7,18 @@
#include <Wire.h>
struct GAS_MEASUREMENT
{
float temp;
float resistance;
};
struct BME_DATA
{
float humidity;
struct GAS_MEASUREMENT measurement[10];
};
class Bme68x
{
protected:
@ -18,7 +30,7 @@ public:
Bme68x(TwoWire & bus);
bool init();
void read();
void read(struct BME_DATA * data);
};
#endif

View File

@ -25,21 +25,12 @@ bool Bmp280::init()
return m_operational;
}
bool Bmp280::read()
bool Bmp280::read(float & temp, float & pressure)
{
float temp, pressure;
if(m_sensor->getTempPres(temp, pressure))
{
char buffer[64];
static float prev = 1000;
prev = pressure*0.1+prev*0.9;
sprintf(buffer, "%0.3f,%0.3f\n", pressure, prev);
printf(buffer);
return true;
}
//ESP_LOGI(TAG, "temp: %0.3f, pressure: %0.3f", temp*1.8+32, pressure);
return true;
}

View File

@ -6,6 +6,13 @@
#include <Wire.h>
#include <BMP280_DEV.h>
struct BMP_DATA
{
float temp;
float pressure;
};
class Bmp280
{
protected:
@ -17,7 +24,7 @@ public:
Bmp280(TwoWire & bus);
bool init();
bool read();
bool read(float & temp, float & pressure);
};
#endif

View File

@ -2,26 +2,33 @@
#include "app_config.h"
#include "TaskMgr.h"
#include "Sensors.h"
#include "SensorService.h"
#include "Buffers.h"
#include "SensorData.h"
static const char *TAG = "sensors";
#define ms_to_us(ms) ((ms)*1000)
#define LIGHT_SENSOR_PIN 36
struct RADAR_MQTT_BLOCK
{
struct BMP_DATA m_bmp_data;
struct BME_DATA m_bme_data;
};
Sensors::Sensors(AppIF & app_if) : m_app_if(app_if)
SensorService::SensorService(AppIF & app_if) : m_app_if(app_if)
{
}
void Sensors::start()
void SensorService::start()
{
ESP_LOGW(TAG, "Starting sensor service...");
esp_log_level_set("gpio", ESP_LOG_WARN);
memset(&m_bmp_data, 0, sizeof(m_bmp_data));
memset(&m_bme_data, 0, sizeof(m_bme_data));
m_bmp280 = new Bmp280(Wire);
m_bme68x = new Bme68x(Wire);
m_ld2410 = new LD2410();
@ -35,26 +42,66 @@ void Sensors::start()
if(!m_ld2410->init())
ESP_LOGE(TAG, "ld2410 sensor error");
assert(m_i2c1_task = TaskMgr::getInstance().createTask(std::bind(&Sensors::run_i2c_1, this),
assert(m_i2c1_task = TaskMgr::getInstance().createTask(std::bind(&SensorService::run_i2c_1, this),
I2C1_TASK_NAME, I2C1_TASK_STACK_SIZE, I2C1_TASK_PRIORITY, I2C1_TASK_CORE));
assert(m_i2c2_task = TaskMgr::getInstance().createTask(std::bind(&Sensors::run_uart, this),
assert(m_i2c2_task = TaskMgr::getInstance().createTask(std::bind(&SensorService::run_uart, this),
UART_TASK_NAME, UART_TASK_STACK_SIZE, UART_TASK_PRIORITY, UART_TASK_CORE));
pinMode(LIGHT_SENSOR_PIN, INPUT);
}
// handles pressure and voc sensor
void Sensors::run_i2c_1()
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_bme68x->read();
m_bmp280->read(m_bmp_data.temp, m_bmp_data.pressure);
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
{
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;
}
delay(10);
}
}
// handles radar only
void Sensors::run_uart()
void SensorService::run_uart()
{
int64_t last_read = esp_timer_get_time();
@ -87,7 +134,7 @@ void Sensors::run_uart()
m.radar.vals[n] = m_ld2410->stationary_energy[n-14] > 0xffff ? 0xffff : (uint16_t)m_ld2410->stationary_energy[n-14];
}
m_app_if.getBuffer()->put_block((uint8_t*)&m, sizeof(m));
m_app_if.getBuffer()->putBlock((uint8_t*)&m, sizeof(m));
ESP_LOGI(TAG, "delta t: %lld", (now - last_read)/1000);
last_read = now;

View File

@ -13,7 +13,7 @@
#include "../AppIF.h"
class Sensors
class SensorService
{
protected:
TaskHandle_t m_i2c1_task = nullptr;
@ -29,7 +29,7 @@ protected:
AppIF & m_app_if;
public:
Sensors(AppIF & app_if);
SensorService(AppIF & app_if);
void start();
};