From f24c40d780baaa2a7b14f79416a7043119200838 Mon Sep 17 00:00:00 2001 From: Zwer2k Date: Sun, 13 Jun 2021 01:24:02 +0200 Subject: [PATCH] work on GPIO handling --- .../jomjol_configfile/CMakeLists.txt | 7 + .../jomjol_configfile/configFile.cpp | 91 +++++++++ .../components/jomjol_configfile/configFile.h | 19 ++ .../jomjol_controlGPIO/CMakeLists.txt | 2 +- .../jomjol_controlGPIO/server_GPIO.cpp | 193 +++++++++++++----- .../jomjol_controlGPIO/server_GPIO.h | 42 +++- .../jomjol_flowcontroll/ClassFlowDigit.cpp | 6 +- .../jomjol_tfliteclass/CTfLiteClass.cpp | 7 +- .../jomjol_tfliteclass/CTfLiteClass.h | 2 +- .../jomjol_tfliteclass/server_tflite.cpp | 4 +- code/main/defines.h | 6 + code/main/main.cpp | 5 +- code/platformio.ini | 4 +- 13 files changed, 330 insertions(+), 58 deletions(-) create mode 100644 code/components/jomjol_configfile/CMakeLists.txt create mode 100644 code/components/jomjol_configfile/configFile.cpp create mode 100644 code/components/jomjol_configfile/configFile.h create mode 100644 code/main/defines.h diff --git a/code/components/jomjol_configfile/CMakeLists.txt b/code/components/jomjol_configfile/CMakeLists.txt new file mode 100644 index 00000000..dc5e71d5 --- /dev/null +++ b/code/components/jomjol_configfile/CMakeLists.txt @@ -0,0 +1,7 @@ +FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*) + +idf_component_register(SRCS ${app_sources} + INCLUDE_DIRS "." + REQUIRES jomjol_logfile) + + diff --git a/code/components/jomjol_configfile/configFile.cpp b/code/components/jomjol_configfile/configFile.cpp new file mode 100644 index 00000000..f2f532fc --- /dev/null +++ b/code/components/jomjol_configfile/configFile.cpp @@ -0,0 +1,91 @@ +#include +#include "Helper.h" +#include "configFile.h" + +ConfigFile::ConfigFile(std::string filePath) +{ + std::string config = FormatFileName(filePath); + pFile = OpenFileAndWait(config.c_str(), "r"); +} + +ConfigFile::~ConfigFile() +{ + fclose(pFile); +} + +bool ConfigFile::isNewParagraph(std::string input) +{ + if ((input[0] == '[') || ((input[0] == ';') && (input[1] == '['))) + { + return true; + } + return false; +} + +bool ConfigFile::GetNextParagraph(std::string& aktparamgraph, bool &disabled, bool &eof) +{ + while (getNextLine(&aktparamgraph, disabled, eof) && !isNewParagraph(aktparamgraph)); + + if (isNewParagraph(aktparamgraph)) + return true; + return false; +} + +bool ConfigFile::getNextLine(std::string *rt, bool &disabled, bool &eof) +{ + eof = false; + char zw[1024]; + if (pFile == NULL) + { + *rt = ""; + return false; + } + fgets(zw, 1024, pFile); + printf("%s", zw); + if ((strlen(zw) == 0) && feof(pFile)) + { + *rt = ""; + eof = true; + return false; + } + *rt = zw; + *rt = trim(*rt); + while ((zw[0] == ';' || zw[0] == '#' || (rt->size() == 0)) && !(zw[1] == '[')) // Kommentarzeilen (; oder #) und Leerzeilen überspringen, es sei denn es ist ein neuer auskommentierter Paragraph + { + fgets(zw, 1024, pFile); + printf("%s", zw); + if (feof(pFile)) + { + *rt = ""; + eof = true; + return false; + } + *rt = zw; + *rt = trim(*rt); + } + + disabled = ((*rt)[0] == ';'); + return true; +} + +std::vector ConfigFile::ZerlegeZeile(std::string input, std::string delimiter) +{ + std::vector Output; +// std::string delimiter = " =,"; + + input = trim(input, delimiter); + size_t pos = findDelimiterPos(input, delimiter); + std::string token; + while (pos != std::string::npos) { + token = input.substr(0, pos); + token = trim(token, delimiter); + Output.push_back(token); + input.erase(0, pos + 1); + input = trim(input, delimiter); + pos = findDelimiterPos(input, delimiter); + } + Output.push_back(input); + + return Output; + +} diff --git a/code/components/jomjol_configfile/configFile.h b/code/components/jomjol_configfile/configFile.h new file mode 100644 index 00000000..f5121d63 --- /dev/null +++ b/code/components/jomjol_configfile/configFile.h @@ -0,0 +1,19 @@ +#include +#include + +static const char *TAGCONFIGFILE = "configFile"; + + +class ConfigFile { +public: + ConfigFile(std::string filePath); + ~ConfigFile(); + + bool isNewParagraph(std::string input); + bool GetNextParagraph(std::string& aktparamgraph, bool &disabled, bool &eof); + bool getNextLine(std::string* rt, bool &disabled, bool &eof); + std::vector ZerlegeZeile(std::string input, std::string delimiter = " =, \t"); + +private: + FILE* pFile; +}; \ No newline at end of file diff --git a/code/components/jomjol_controlGPIO/CMakeLists.txt b/code/components/jomjol_controlGPIO/CMakeLists.txt index c5ad1e71..dee91f14 100644 --- a/code/components/jomjol_controlGPIO/CMakeLists.txt +++ b/code/components/jomjol_controlGPIO/CMakeLists.txt @@ -4,6 +4,6 @@ list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/proto idf_component_register(SRCS ${app_sources} INCLUDE_DIRS "." - REQUIRES esp_http_server jomjol_logfile) + REQUIRES esp_http_server jomjol_logfile jomjol_configfile) diff --git a/code/components/jomjol_controlGPIO/server_GPIO.cpp b/code/components/jomjol_controlGPIO/server_GPIO.cpp index fb06e694..aac8c9c0 100644 --- a/code/components/jomjol_controlGPIO/server_GPIO.cpp +++ b/code/components/jomjol_controlGPIO/server_GPIO.cpp @@ -11,16 +11,114 @@ //#include "errno.h" #include +#include +//#include #include "server_GPIO.h" #include "ClassLogFile.h" - +#include "configFile.h" #include "Helper.h" // #define DEBUG_DETAIL_ON -esp_err_t handler_switch_GPIO(httpd_req_t *req) +GpioPin::GpioPin(gpio_num_t gpio, const char* name, gpio_pin_mode_t mode, gpio_int_type_t interruptType) +{ + _gpio = gpio; + _name = name; + _mode = mode; + _interruptType = interruptType; + + initGPIO(); +} + +void GpioPin::initGPIO() +{ + gpio_config_t io_conf; + //disable interrupt + io_conf.intr_type = _interruptType; + //set as output mode + io_conf.mode = _mode == gpio_pin_mode_t::GPIO_PIN_MODE_OUTPUT ? gpio_mode_t::GPIO_MODE_OUTPUT : gpio_mode_t::GPIO_MODE_INPUT; + //bit mask of the pins that you want to set,e.g.GPIO18/19 + io_conf.pin_bit_mask = (1ULL << _gpio); + //disable pull-down mode + io_conf.pull_down_en = _mode == gpio_pin_mode_t::GPIO_PIN_MODE_INPUT_PULLDOWN ? gpio_pulldown_t::GPIO_PULLDOWN_ENABLE : gpio_pulldown_t::GPIO_PULLDOWN_DISABLE; + //disable pull-up mode + io_conf.pull_up_en = _mode == gpio_pin_mode_t::GPIO_PIN_MODE_INPUT_PULLDOWN ? gpio_pullup_t::GPIO_PULLUP_ENABLE : gpio_pullup_t::GPIO_PULLUP_DISABLE; + //configure GPIO with the given settings + gpio_config(&io_conf); +} + +void GpioPin::setValue(bool value) +{ + gpio_set_level(_gpio, value); +} + +esp_err_t callHandleHttpRequest(httpd_req_t *req) +{ + return ((GpioHandler*)req->user_ctx)->handleHttpRequest(req); +} + +GpioHandler::GpioHandler(std::string configFile, httpd_handle_t server) +{ + _configFile = configFile; + + gpioMap = new std::map(); + + readConfig(); + registerGpioUri(server); +} + +bool GpioHandler::readConfig() +{ + ConfigFile configFile(_configFile); + std::vector zerlegt; + + std::string line = ""; + bool disabledLine = false; + bool eof = false; + + while ((!configFile.GetNextParagraph(line, disabledLine, eof) || (line.compare("[GPIO]") != 0)) && !disabledLine && !eof) {} + + if (eof) + return false; + + + while (configFile.getNextLine(&line, disabledLine, eof) && !configFile.isNewParagraph(line)) + { + zerlegt = configFile.ZerlegeZeile(line); + // const std::regex pieces_regex("IO([0-9]{1,2})"); + // std::smatch pieces_match; + // if (std::regex_match(zerlegt[0], pieces_match, pieces_regex) && (pieces_match.size() == 2)) + // { + // std::string gpioStr = pieces_match[1]; + if (zerlegt[0].rfind("IO", 0) == 0) + { + std::string gpioStr = zerlegt[0].substr(2, 2); + gpio_num_t gpioNr = (gpio_num_t)atoi(gpioStr.c_str()); + gpio_pin_mode_t pinMode = resolvePinMode(zerlegt[1]); + gpio_int_type_t intType = resolveIntType(zerlegt[2]); + (*gpioMap)[gpio_num_t::GPIO_NUM_16] = new GpioPin(gpioNr, zerlegt[3].c_str(), pinMode, intType); + + } + } + + return true; +} + + +void GpioHandler::registerGpioUri(httpd_handle_t server) { + ESP_LOGI(TAGPARTGPIO, "server_GPIO - Registering URI handlers"); + + httpd_uri_t camuri = { }; + camuri.method = HTTP_GET; + camuri.uri = "/GPIO"; + camuri.handler = callHandleHttpRequest; + camuri.user_ctx = (void*) this; + httpd_register_uri_handler(server, &camuri); +} + +IRAM_ATTR esp_err_t GpioHandler::handleHttpRequest(httpd_req_t *req) { #ifdef DEBUG_DETAIL_ON LogFile.WriteHeapInfo("handler_switch_GPIO - Start"); @@ -31,9 +129,7 @@ esp_err_t handler_switch_GPIO(httpd_req_t *req) char _valueGPIO[30]; char _valueStatus[30]; std::string gpio, status, zw; - int gpionum = 0; - gpio_num_t gpio_num; - + if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK) { printf("Query: "); printf(_query); printf("\n"); @@ -59,29 +155,19 @@ esp_err_t handler_switch_GPIO(httpd_req_t *req) return ESP_OK; } - gpionum = stoi(gpio); + int gpionum = stoi(gpio); // frei: 16; 12-15; 2; 4 // nur 12 und 13 funktionieren 2: reboot, 4: BlitzLED, 14/15: DMA für SDKarte ??? - - switch (gpionum) { - case 12: - gpio_num = GPIO_NUM_12; - break; - case 13: - gpio_num = GPIO_NUM_13; - break; - default: - zw = "GPIO" + std::to_string(gpionum) + " not support - only 12 & 13 free"; + gpio_num_t gpio_num = resolvePinNr(gpionum); + if (gpio_num == GPIO_NUM_NC) + { + zw = "GPIO" + std::to_string(gpionum) + " not support - only 12 & 13 free"; httpd_resp_sendstr_chunk(req, zw.c_str()); httpd_resp_sendstr_chunk(req, NULL); - return ESP_OK; + return ESP_OK; } - if (status == "HIGH") - gpio_set_level(gpio_num, 1); - else - gpio_set_level(gpio_num, 0); - + (*gpioMap)[gpio_num]->setValue((status == "HIGH") || (status == "TRUE") || (status == "1")); zw = "GPIO" + std::to_string(gpionum) + " switched to " + status; httpd_resp_sendstr_chunk(req, zw.c_str()); @@ -89,36 +175,45 @@ esp_err_t handler_switch_GPIO(httpd_req_t *req) return ESP_OK; }; -void initGPIO() +gpio_num_t GpioHandler::resolvePinNr(uint8_t pinNr) { - gpio_config_t io_conf; - //disable interrupt - io_conf.intr_type = GPIO_INTR_DISABLE; - //set as output mode - io_conf.mode = GPIO_MODE_OUTPUT; - //bit mask of the pins that you want to set,e.g.GPIO18/19 -// io_conf.pin_bit_mask = ((1ULL< #include +#include //#include "ClassControllCamera.h" static const char *TAGPARTGPIO = "server_GPIO"; -void register_server_GPIO_uri(httpd_handle_t server); +typedef enum { + GPIO_PIN_MODE_DISABLED = 0x0, + GPIO_PIN_MODE_INPUT = 0x1, + GPIO_PIN_MODE_INPUT_PULLUP = 0x2, + GPIO_PIN_MODE_INPUT_PULLDOWN = 0x3, + GPIO_PIN_MODE_OUTPUT = 0x4, + GPIO_PIN_MODE_OUTPUT_PWM = 0x5, +} gpio_pin_mode_t; +class GpioPin { +public: + GpioPin(gpio_num_t gpio, const char* name, gpio_pin_mode_t mode, gpio_int_type_t interruptType); + void setValue(bool value); + +private: + gpio_num_t _gpio; + const char* _name; + gpio_pin_mode_t _mode; + gpio_int_type_t _interruptType; + + void initGPIO(); +}; + +esp_err_t callHandleHttpRequest(httpd_req_t *req); + +class GpioHandler { +public: + GpioHandler(std::string configFile, httpd_handle_t server); + + void registerGpioUri(httpd_handle_t server); + esp_err_t handleHttpRequest(httpd_req_t *req); + +private: + std::string _configFile; + std::map *gpioMap = NULL; + + bool readConfig(); + gpio_num_t resolvePinNr(uint8_t pinNr); + gpio_pin_mode_t resolvePinMode(std::string input); + gpio_int_type_t resolveIntType(std::string input); +}; \ No newline at end of file diff --git a/code/components/jomjol_flowcontroll/ClassFlowDigit.cpp b/code/components/jomjol_flowcontroll/ClassFlowDigit.cpp index 6e37cc0b..97671362 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowDigit.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowDigit.cpp @@ -241,7 +241,11 @@ bool ClassFlowDigit::doNeuralNetwork(string time) CTfLiteClass *tflite = new CTfLiteClass; string zwcnn = FormatFileName("/sdcard" + cnnmodelfile); printf(zwcnn.c_str());printf("\n"); - tflite->LoadModel(zwcnn); + if (!tflite->LoadModel(zwcnn)) { + printf("Can't read model file /sdcard%s\n", cnnmodelfile.c_str()); + return false; + } + tflite->MakeAllocate(); #endif diff --git a/code/components/jomjol_tfliteclass/CTfLiteClass.cpp b/code/components/jomjol_tfliteclass/CTfLiteClass.cpp index d0a529f5..504ea71c 100644 --- a/code/components/jomjol_tfliteclass/CTfLiteClass.cpp +++ b/code/components/jomjol_tfliteclass/CTfLiteClass.cpp @@ -208,7 +208,7 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn) return result; } -void CTfLiteClass::LoadModel(std::string _fn){ +bool CTfLiteClass::LoadModel(std::string _fn){ #ifdef SUPRESS_TFLITE_ERRORS this->error_reporter = new tflite::OwnMicroErrorReporter; @@ -219,9 +219,14 @@ void CTfLiteClass::LoadModel(std::string _fn){ unsigned char *rd; rd = ReadFileToCharArray(_fn.c_str()); + if (rd == NULL) + return false; + this->model = tflite::GetModel(rd); free(rd); TFLITE_MINIMAL_CHECK(model != nullptr); + + return true; } diff --git a/code/components/jomjol_tfliteclass/CTfLiteClass.h b/code/components/jomjol_tfliteclass/CTfLiteClass.h index 07279f14..4c6ed8f7 100644 --- a/code/components/jomjol_tfliteclass/CTfLiteClass.h +++ b/code/components/jomjol_tfliteclass/CTfLiteClass.h @@ -56,7 +56,7 @@ class CTfLiteClass public: CTfLiteClass(); ~CTfLiteClass(); - void LoadModel(std::string _fn); + bool LoadModel(std::string _fn); void MakeAllocate(); void GetInputTensorSize(); bool LoadInputImageBasis(CImageBasis *rs); diff --git a/code/components/jomjol_tfliteclass/server_tflite.cpp b/code/components/jomjol_tfliteclass/server_tflite.cpp index f29e384c..0d0b70b4 100644 --- a/code/components/jomjol_tfliteclass/server_tflite.cpp +++ b/code/components/jomjol_tfliteclass/server_tflite.cpp @@ -8,6 +8,7 @@ #include #include +#include "../../main/defines.h" #include "Helper.h" #include "esp_camera.h" @@ -87,11 +88,10 @@ void KillTFliteTasks() void doInit(void) { - string config = "/sdcard/config/config.ini"; #ifdef DEBUG_DETAIL_ON printf("Start tfliteflow.InitFlow(config);\n"); #endif - tfliteflow.InitFlow(config); + tfliteflow.InitFlow(CONFIG_FILE); #ifdef DEBUG_DETAIL_ON printf("Finished tfliteflow.InitFlow(config);\n"); #endif diff --git a/code/main/defines.h b/code/main/defines.h new file mode 100644 index 00000000..436b0baa --- /dev/null +++ b/code/main/defines.h @@ -0,0 +1,6 @@ +#ifndef defines_h +#define defines_h + +#define CONFIG_FILE "/sdcard/config/config.ini" + +#endif // ifndef defines_h \ No newline at end of file diff --git a/code/main/main.cpp b/code/main/main.cpp index fd94cfbe..0f82c69d 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -3,6 +3,7 @@ #include "freertos/task.h" #include "freertos/event_groups.h" +#include "defines.h" #include "driver/gpio.h" #include "sdkconfig.h" @@ -41,6 +42,8 @@ static const char *TAGMAIN = "connect_wlan_main"; #define FLASH_GPIO GPIO_NUM_4 +GpioHandler *gpioHandler = NULL; + bool Init_NVS_SDCard() { esp_err_t ret = nvs_flash_init(); @@ -201,7 +204,7 @@ extern "C" void app_main(void) register_server_ota_sdcard_uri(server); #ifdef __SD_USE_ONE_LINE_MODE__ - register_server_GPIO_uri(server); + gpioHandler = new GpioHandler(CONFIG_FILE, server); #endif printf("vor reg server main\n"); diff --git a/code/platformio.ini b/code/platformio.ini index 50bf0706..7e57078e 100644 --- a/code/platformio.ini +++ b/code/platformio.ini @@ -22,7 +22,8 @@ framework = espidf ;board_build.partitions = partitions_singleapp.csv board_build.partitions = partitions.csv -lib_deps = +lib_deps = + jomjol_configfile jomjol_helper jomjol_wlan jomjol_image_proc @@ -36,6 +37,7 @@ lib_deps = jomjol_mqtt jomjol_controlGPIO + monitor_speed = 115200 debug_tool = esp-prog