gpio handler work

This commit is contained in:
Zwer2k
2021-07-10 12:36:13 +02:00
parent 749fc6699c
commit a44e0d81cc
4 changed files with 116 additions and 33 deletions

View File

@@ -7,6 +7,8 @@
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_event.h"
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#include "esp_log.h"
//#include "errno.h"
@@ -51,7 +53,7 @@ static void IRAM_ATTR gpio_isr_handler(void* arg)
{
GpioResult gpioResult;
gpioResult.gpio = *(gpio_num_t*) arg;
gpioResult.value = gpio_get_level(gpioResult.gpio) == 1;
gpioResult.value = gpio_get_level(gpioResult.gpio);
BaseType_t ContextSwitchRequest = pdFALSE;
xQueueSendToBackFromISR(gpio_queue_handle,(void*)&gpioResult,&ContextSwitchRequest);
@@ -61,7 +63,8 @@ static void IRAM_ATTR gpio_isr_handler(void* arg)
}
}
static void gpioInterruptTask(void *arg) {
static void gpioHandlerTask(void *arg) {
ESP_LOGD(TAG_SERVERGPIO,"start interrupt task");
while(1){
if(uxQueueMessagesWaiting(gpio_queue_handle)){
while(uxQueueMessagesWaiting(gpio_queue_handle)){
@@ -71,15 +74,18 @@ static void gpioInterruptTask(void *arg) {
((GpioHandler*)arg)->gpioInterrupt(&gpioResult);
}
}
((GpioHandler*)arg)->taskHandler();
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void GpioPin::gpioInterrupt(bool value) {
void GpioPin::gpioInterrupt(int value) {
if (_mqttTopic != "") {
ESP_LOGD(TAG_SERVERGPIO, "gpioInterrupt %s %d", _mqttTopic.c_str(), value);
MQTTPublish(_mqttTopic, value ? "true" : "false");
currentState = value;
}
}
@@ -101,6 +107,7 @@ void GpioPin::init()
if (_interruptType != GPIO_INTR_DISABLE) {
//hook isr handler for specific gpio pin
ESP_LOGD(TAG_SERVERGPIO, "GpioPin::init add isr handler for GPIO %d\r\n", _gpio);
gpio_isr_handler_add(_gpio, gpio_isr_handler, (void*)&_gpio);
}
@@ -134,6 +141,15 @@ void GpioPin::setValue(bool value, gpio_set_source setSource, std::string* error
}
}
void GpioPin::publishState() {
int newState = gpio_get_level(_gpio);
if (newState != currentState) {
ESP_LOGD(TAG_SERVERGPIO,"publish state of GPIO %d new state %d", _gpio, newState);
MQTTPublish(_mqttTopic, newState ? "true" : "false");
currentState = newState;
}
}
bool GpioPin::handleMQTT(std::string, char* data, int data_len) {
ESP_LOGD(TAG_SERVERGPIO, "GpioPin::handleMQTT data %.*s\r\n", data_len, data);
@@ -179,8 +195,6 @@ GpioHandler::GpioHandler(std::string configFile, httpd_handle_t httpServer)
ESP_LOGI(TAG_SERVERGPIO, "register GPIO Uri");
registerGpioUri();
//xTaskCreate((TaskFunction_t)&taskGpioHandler, "taskGpioHandler", configMINIMAL_STACK_SIZE * 64, this, tskIDLE_PRIORITY+1, &xHandletaskGpioHandler);
}
GpioHandler::~GpioHandler() {
@@ -207,18 +221,51 @@ void GpioHandler::init()
for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
it->second->init();
}
if ((it->second->getInterruptType() != GPIO_INTR_DISABLE) && (gpio_queue_handle == NULL)) {
std::function<void()> f = std::bind(&GpioHandler::handleMQTTconnect, this);
MQTTregisterConnectFunction("gpio-handler", f);
if (xHandleTaskGpio == NULL) {
gpio_queue_handle = xQueueCreate(10,sizeof(GpioResult));
xTaskCreate(gpioInterruptTask, "GPIO Task", configMINIMAL_STACK_SIZE * 64, (void *)this, 10, NULL);
BaseType_t xReturned = xTaskCreate(&gpioHandlerTask, "gpio_int", configMINIMAL_STACK_SIZE * 8, (void *)this, tskIDLE_PRIORITY + 2, &xHandleTaskGpio);
if(xReturned == pdPASS ) {
ESP_LOGD(TAG_SERVERGPIO, "xHandletaskGpioHandler started");
} else {
ESP_LOGD(TAG_SERVERGPIO, "xHandletaskGpioHandler not started %d ", (int)xHandleTaskGpio);
}
}
ESP_LOGI(TAG_SERVERGPIO, "GPIO init comleted");
}
void GpioHandler::taskHandler() {
if (gpioMap != NULL) {
for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
if ((it->second->getInterruptType() == GPIO_INTR_DISABLE))
it->second->publishState();
}
}
}
void GpioHandler::handleMQTTconnect()
{
if (gpioMap != NULL) {
for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
if ((it->second->getMode() == GPIO_PIN_MODE_INPUT) || (it->second->getMode() == GPIO_PIN_MODE_INPUT_PULLDOWN) || (it->second->getMode() == GPIO_PIN_MODE_INPUT_PULLUP))
it->second->publishState();
}
}
}
void GpioHandler::deinit() {
MQTTunregisterConnectFunction("gpio-handler");
clear();
if (xHandleTaskGpio != NULL) {
vTaskDelete(xHandleTaskGpio);
xHandleTaskGpio = NULL;
}
}
void GpioHandler::gpioInterrupt(GpioResult* gpioResult) {

View File

@@ -23,7 +23,7 @@ typedef enum {
struct GpioResult {
gpio_num_t gpio;
bool value;
int value;
};
typedef enum {
@@ -37,11 +37,12 @@ public:
GpioPin(gpio_num_t gpio, const char* name, gpio_pin_mode_t mode, gpio_int_type_t interruptType, uint8_t dutyResolution, std::string mqttTopic, bool httpEnable);
~GpioPin();
void init();
bool getValue(std::string* errorText);
void setValue(bool value, gpio_set_source setSource, std::string* errorText);
void init();
bool handleMQTT(std::string, char* data, int data_len);
void gpioInterrupt(bool value);
void publishState();
void gpioInterrupt(int value);
gpio_int_type_t getInterruptType() { return _interruptType; }
gpio_pin_mode_t getMode() { return _mode; }
@@ -51,6 +52,7 @@ private:
gpio_pin_mode_t _mode;
gpio_int_type_t _interruptType;
std::string _mqttTopic;
int currentState = -1;
};
esp_err_t callHandleHttpRequest(httpd_req_t *req);
@@ -65,15 +67,17 @@ public:
void deinit();
void registerGpioUri();
esp_err_t handleHttpRequest(httpd_req_t *req);
void taskHandler();
void gpioInterrupt(GpioResult* gpioResult);
void flashLightEnable(bool value);
bool isEnabled() { return _isEnabled; }
void handleMQTTconnect();
private:
std::string _configFile;
httpd_handle_t _httpServer;
std::map<gpio_num_t, GpioPin*> *gpioMap = NULL;
TaskHandle_t xHandletaskGpioHandler = NULL;
TaskHandle_t xHandleTaskGpio = NULL;
bool _isEnabled = false;
bool readConfig();

View File

@@ -1,12 +1,13 @@
#include "interface_mqtt.h"
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#include "esp_log.h"
#include "mqtt_client.h"
#include "ClassLogFile.h"
static const char *TAG_INTERFACEMQTT = "interface_mqtt";
std::map<std::string, std::function<void()>>* connectFunktionMap = NULL;
std::map<std::string, std::function<bool(std::string, char*, int)>>* subscribeFunktionMap = NULL;
bool debugdetail = true;
@@ -24,10 +25,10 @@ void MQTTPublish(std::string _key, std::string _content, int retained_flag){
msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
zw = "sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content;
if (debugdetail) LogFile.WriteToFile(zw);
ESP_LOGI(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
ESP_LOGD(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
}
else {
ESP_LOGI(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
}
}
@@ -38,12 +39,12 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
std::string topic = "";
switch (event->event_id) {
case MQTT_EVENT_BEFORE_CONNECT:
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_CONNECTED");
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_BEFORE_CONNECT");
break;
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_CONNECTED");
mqtt_connected = true;
MQTTsubscribeFunctions();
MQTTconnected();
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_DISCONNECTED");
@@ -61,19 +62,16 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
ESP_LOGI(TAG_INTERFACEMQTT, "TOPIC=%.*s\r\n", event->topic_len, event->topic);
ESP_LOGI(TAG_INTERFACEMQTT, "DATA=%.*s\r\n", event->data_len, event->data);
topic.assign(event->topic, event->topic_len);
if (subscribeFunktionMap != NULL) {
for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
printf("compare %s %s\r\n", it->first.c_str(), topic.c_str());
}
if (subscribeFunktionMap->find(topic) != subscribeFunktionMap->end()) {
printf("call handler function\r\n");
ESP_LOGD(TAG_INTERFACEMQTT, "call handler function\r\n");
(*subscribeFunktionMap)[topic](topic, event->data, event->data_len);
}
} else {
printf("no handler available\r\n");
ESP_LOGW(TAG_INTERFACEMQTT, "no handler available\r\n");
}
break;
case MQTT_EVENT_ERROR:
@@ -109,7 +107,7 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
if (_user.length() && _password.length()){
mqtt_cfg.username = _user.c_str();
mqtt_cfg.password = _password.c_str();
printf("Connect to MQTT: %s, %s", mqtt_cfg.username, mqtt_cfg.password);
ESP_LOGI(TAG_INTERFACEMQTT, "Connect to MQTT: %s, %s", mqtt_cfg.username, mqtt_cfg.password);
};
client = esp_mqtt_client_init(&mqtt_cfg);
@@ -130,8 +128,33 @@ bool MQTTisConnected() {
return mqtt_connected;
}
void MQTTregisterConnectFunction(std::string name, std::function<void()> func){
ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisteronnectFunction %s\r\n", name.c_str());
if (connectFunktionMap == NULL) {
connectFunktionMap = new std::map<std::string, std::function<void()>>();
}
if ((*connectFunktionMap)[name] != NULL) {
ESP_LOGW(TAG_INTERFACEMQTT, "connect function %s already registred", name.c_str());
return;
}
(*connectFunktionMap)[name] = func;
if (mqtt_connected) {
func();
}
}
void MQTTunregisterConnectFunction(std::string name){
ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisteronnectFunction %s\r\n", name.c_str());
if ((connectFunktionMap != NULL) && (connectFunktionMap->find(name) != connectFunktionMap->end())) {
connectFunktionMap->erase(name);
}
}
void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::string, char*, int)> func){
printf("MQTTregisterSubscribeFunction %s\r\n", topic.c_str());
ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisterSubscribeFunction %s\r\n", topic.c_str());
if (subscribeFunktionMap == NULL) {
subscribeFunktionMap = new std::map<std::string, std::function<bool(std::string, char*, int)>>();
}
@@ -145,16 +168,23 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::st
if (mqtt_connected) {
int msg_id = esp_mqtt_client_subscribe(client, topic.c_str(), 0);
ESP_LOGI(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", topic.c_str(), msg_id);
ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", topic.c_str(), msg_id);
}
}
void MQTTsubscribeFunctions(){
if (subscribeFunktionMap != NULL) {
void MQTTconnected(){
if (mqtt_connected) {
if (connectFunktionMap != NULL) {
for(std::map<std::string, std::function<void()>>::iterator it = connectFunktionMap->begin(); it != connectFunktionMap->end(); ++it) {
it->second();
ESP_LOGD(TAG_INTERFACEMQTT, "call connect function %s", it->first.c_str());
}
}
if (subscribeFunktionMap != NULL) {
for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
int msg_id = esp_mqtt_client_subscribe(client, it->first.c_str(), 0);
ESP_LOGI(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id);
ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id);
}
}
}

View File

@@ -14,8 +14,10 @@ void MQTTPublish(std::string _key, std::string _content, int retained_flag = 0);
bool MQTTisConnected();
void MQTTregisterConnectFunction(std::string name, std::function<void()> func);
void MQTTunregisterConnectFunction(std::string name);
void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::string, char*, int)> func);
void MQTTdestroySubscribeFunction();
void MQTTsubscribeFunctions();
void MQTTconnected();
#endif //INTERFACE_MQTT_H