#include "Main.h" #include #include "classes/IoTDB.h" #include "utils/Statistic.h" #include "classes/IoTBench.h" #ifndef LIBRETINY #include #endif #include "DebugTrace.h" #if defined(ESP32) #include #endif #if defined(esp32s2_4mb) || defined(esp32s3_16mb) #include #endif IoTScenario iotScen; // объект управления сценарием String volStrForSave = ""; // unsigned long currentMillis; // это сдесь лишнее // unsigned long prevMillis; void elementsLoop() { // передаем управление каждому элементу конфигурации для выполнения своих функций for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { if (benchTaskItem) benchTaskItem->preTaskFunction((*it)->getID()); (*it)->loop(); if (benchTaskItem) benchTaskItem->postTaskFunction((*it)->getID()); // if ((*it)->iAmDead) { if (!((*it)->iAmLocal) && (*it)->getIntFromNet() == -1) { delete *it; IoTItems.erase(it); break; } } handleOrder(); handleEvent(); } #define SETUPBASE_ERRORMARKER 0 #define SETUPCONF_ERRORMARKER 1 #define SETUPSCEN_ERRORMARKER 2 #define SETUPINET_ERRORMARKER 3 #define SETUPLAST_ERRORMARKER 4 #define TICKER_ERRORMARKER 5 #define HTTP_ERRORMARKER 6 #define SOCKETS_ERRORMARKER 7 #define MQTT_ERRORMARKER 8 #define MODULES_ERRORMARKER 9 #define COUNTER_ERRORMARKER 4 // количество шагов счетчика #define STEPPER_ERRORMARKER 100000 // размер шага счетчика интервала доверия выполнения блока кода мкс #if defined(esp32_4mb) || defined(esp32_4mb3f) || defined(esp32_16mb) || defined(esp32cam_4mb) static int IRAM_ATTR initErrorMarkerId = 0; // ИД маркера static int IRAM_ATTR errorMarkerId = 0; static int IRAM_ATTR errorMarkerCounter = 0; hw_timer_t *My_timer = NULL; void IRAM_ATTR onTimer() { if (errorMarkerCounter >= 0) { if (errorMarkerCounter >= COUNTER_ERRORMARKER) { errorMarkerId = initErrorMarkerId; errorMarkerCounter = -1; } else errorMarkerCounter++; } } #endif void initErrorMarker(int id) { #if defined(esp32_4mb) || defined(esp32_4mb3f) || defined(esp32_16mb) || defined(esp32cam_4mb) initErrorMarkerId = id; errorMarkerCounter = 0; #endif } void stopErrorMarker(int id) { #if defined(esp32_4mb) || defined(esp32_4mb3f) || defined(esp32_16mb) || defined(esp32cam_4mb) errorMarkerCounter = -1; if (errorMarkerId) SerialPrint("I", "WARNING!", "A lazy (freezing loop more than " + (String)(COUNTER_ERRORMARKER * STEPPER_ERRORMARKER / 1000) + " ms) section has been found! With ID=" + (String)errorMarkerId); errorMarkerId = 0; initErrorMarkerId = 0; #endif } void setup() { #if defined(esp32s2_4mb) || defined(esp32s3_16mb) USB.begin(); #endif #if defined(esp32_4mb) || defined(esp32_4mb3f) || defined(esp32_16mb) || defined(esp32cam_4mb) My_timer = timerBegin(0, 80, true); timerAttachInterrupt(My_timer, &onTimer, true); timerAlarmWrite(My_timer, STEPPER_ERRORMARKER, true); timerAlarmEnable(My_timer); // timerAlarmDisable(My_timer); initErrorMarker(SETUPBASE_ERRORMARKER); #endif Serial.begin(115200); Serial.flush(); //----------- Отладка EXCEPTION (функции с заглушками для отключения) --------- #if defined(RESTART_DEBUG_INFO) //Привязка коллбэк функции для вызова при перезагрузке esp_register_shutdown_handler(debugUpdate); #endif // RESTART_DEBUG_INFO // Печать или оправка отладочной информации printDebugTrace(); startWatchDog(); Serial.println(); Serial.println(F("--------------started----------------")); // создание экземпляров классов // myNotAsyncActions = new NotAsync(do_LAST); // инициализация файловой системы fileSystemInit(); Serial.println(F("------------------------")); Serial.println("FIRMWARE NAME " + String(FIRMWARE_NAME)); Serial.println("FIRMWARE VERSION " + String(FIRMWARE_VERSION)); Serial.println("WEB VERSION " + getWebVersion()); const String buildTime = String(BUILD_DAY) + "." + String(BUILD_MONTH) + "." + String(BUILD_YEAR) + " " + String(BUILD_HOUR) + ":" + String(BUILD_MIN) + ":" + String(BUILD_SEC); Serial.println("BUILD TIME " + buildTime); jsonWriteStr_(errorsHeapJson, F("bt"), buildTime); Serial.println(F("------------------------")); // получение chip id setChipId(); verifyFirmware(); // синхронизация глобальных переменных с flash globalVarsSync(); stopErrorMarker(SETUPBASE_ERRORMARKER); initErrorMarker(SETUPCONF_ERRORMARKER); // настраиваем i2c шину int i2c, pinSCL, pinSDA, i2cFreq; jsonRead(settingsFlashJson, "pinSCL", pinSCL, false); jsonRead(settingsFlashJson, "pinSDA", pinSDA, false); jsonRead(settingsFlashJson, "i2cFreq", i2cFreq, false); jsonRead(settingsFlashJson, "i2c", i2c, false); if (i2c != 0) { #ifdef ESP32 Wire.end(); Wire.begin(pinSDA, pinSCL, (uint32_t)i2cFreq); #elif defined(ESP8266) Wire.begin(pinSDA, pinSCL); Wire.setClock(i2cFreq); #endif SerialPrint("i", "i2c", F("i2c pins overriding done")); } #if defined(RESTART_DEBUG_INFO) esp_reset_reason_t esp_reason = esp_reset_reason(); if (esp_reason == ESP_RST_UNKNOWN || esp_reason == ESP_RST_POWERON) bootloop_panic_count = 0; /* else if (bootloop_panic_count == 3 || bootloop_panic_count == 0 ) bootloop_panic_count = 1; else if (bootloop_panic_count == 2) bootloop_panic_count = 3; else if (bootloop_panic_count == 1) bootloop_panic_count = 2; else bootloop_panic_count = 0; */ Serial.println("bootloop_panic_count " + String(bootloop_panic_count)); if (bootloop_panic_count >3 ) { //resetSettingsFlashByPanic(); bootloop_panic_count = 0; } if (bootloop_panic_count >= 3) { resetSettingsFlashByPanic(); bootloop_panic_count = -1; } if (bootloop_panic_count == -1) { SerialPrint("E", "CORE", F("CONFIG and SCENARIO reset !!!")); bootloop_panic_count = 0; ESP.restart(); } #endif // RESTART_DEBUG_INFO // настраиваем микроконтроллер configure("/config.json"); stopErrorMarker(SETUPCONF_ERRORMARKER); initErrorMarker(SETUPSCEN_ERRORMARKER); // подготавливаем сценарии iotScen.loadScenario("/scenario.txt"); // создаем событие завершения инициализации основных моментов для возможности выполнения блока кода при загрузке createItemFromNet("onInit", "1", 1); // elementsLoop(); //Для работы MQTT Брокера перенес ниже, иначе брокер падает если вызван до routerConnect(); stopErrorMarker(SETUPSCEN_ERRORMARKER); initErrorMarker(SETUPINET_ERRORMARKER); // подключаемся к роутеру #ifdef ESP8266 routerConnect(); #else WiFiUtilsItit(); #endif // инициализация асинхронного веб сервера и веб сокетов #ifdef ASYNC_WEB_SERVER asyncWebServerInit(); #endif #ifdef ASYNC_WEB_SOCKETS asyncWebSocketsInit(); #endif // инициализация стандартного веб сервера и веб сокетов #ifdef STANDARD_WEB_SERVER standWebServerInit(); #endif #ifdef STANDARD_WEB_SOCKETS standWebSocketsInit(); #endif stopErrorMarker(SETUPINET_ERRORMARKER); bool postMsgTelegram; if (!jsonRead(settingsFlashJson, "debugTraceMsgTlgrm", postMsgTelegram, false)) postMsgTelegram = 1; sendDebugTraceAndFreeMemory(postMsgTelegram); initErrorMarker(SETUPLAST_ERRORMARKER); elementsLoop(); // NTP ntpInit(); // инициализация задач переодического выполнения periodicTasksInit(); // запуск работы udp addThisDeviceToList(); #ifdef UDP_ENABLED udpListningInit(); udpBroadcastInit(); #endif // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке createItemFromNet("onStart", "1", 1); stInit(); // настраиваем секундные обслуживания системы ts.add( TIMES, 1000, [&](void *) { // сброс WDT #if defined(ESP32) //SerialPrint("i", "Task", "reset wdt"); #if !defined(esp32c6_4mb) && !defined(esp32c6_8mb) //TODO esp32-c6 переписать esp_task_wdt_init esp_task_wdt_reset(); #endif #endif // сохраняем значения IoTItems в файл каждую секунду, если были изменения (установлены маркеры на сохранение) if (needSaveValues) { syncValuesFlashJson(); needSaveValues = false; } // проверяем все элементы на тухлость for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { (*it)->checkIntFromNet(); // Serial.printf("[ITEM] size: %d, id: %s, int: %d, intnet: %d\n", sizeof(**it), (*it)->getID(), (*it)->getInterval(), (*it)->getIntFromNet()); } }, nullptr, true); // ловим пинги от WS (5сек) и дисконнектим если их нет (20сек) ts.add( PiWS, 6000, [&](void*) { if (isNetworkActive()) { for (size_t i = 0; i < WEBSOCKETS_CLIENT_MAX; i++) { if (ws_clients[i] == 0) { disconnectWSClient(i); ws_clients[i]=-1; } if (ws_clients[i] > 0) { ws_clients[i]=0; } } } }, nullptr, true); // test //Serial.println("-------test start--------"); //Serial.println("--------test end---------"); stopErrorMarker(SETUPLAST_ERRORMARKER); #if defined(RESTART_DEBUG_INFO) bootloop_panic_count = 0; #endif // RESTART_DEBUG_INFO } void loop() { #ifdef LOOP_DEBUG unsigned long st = millis(); #endif if (benchLoadItem) benchLoadItem->preLoadFunction(); if (benchTaskItem) benchTaskItem->preTaskFunction("TickerScheduler"); initErrorMarker(TICKER_ERRORMARKER); ts.update(); stopErrorMarker(TICKER_ERRORMARKER); if (benchTaskItem) benchTaskItem->postTaskFunction("TickerScheduler"); if (benchTaskItem) benchTaskItem->preTaskFunction("webServer"); #ifdef STANDARD_WEB_SERVER initErrorMarker(HTTP_ERRORMARKER); HTTP.handleClient(); stopErrorMarker(HTTP_ERRORMARKER); #endif if (benchTaskItem) benchTaskItem->postTaskFunction("webServer"); if (benchTaskItem) benchTaskItem->preTaskFunction("webSocket"); #ifdef STANDARD_WEB_SOCKETS initErrorMarker(SOCKETS_ERRORMARKER); standWebSocket.loop(); stopErrorMarker(SOCKETS_ERRORMARKER); #endif if (benchTaskItem) benchTaskItem->postTaskFunction("webSocket"); if (benchTaskItem) benchTaskItem->preTaskFunction("mqtt"); initErrorMarker(MQTT_ERRORMARKER); mqttLoop(); stopErrorMarker(MQTT_ERRORMARKER); if (benchTaskItem) benchTaskItem->postTaskFunction("mqtt"); initErrorMarker(MODULES_ERRORMARKER); elementsLoop(); stopErrorMarker(MODULES_ERRORMARKER); if (benchLoadItem) benchLoadItem->postLoadFunction(); // #ifdef LOOP_DEBUG // loopPeriod = millis() - st; // if (loopPeriod > 2) Serial.println(loopPeriod); // #endif } // отправка json // #ifdef QUEUE_FROM_STR // if (sendJsonFiles) sendJsonFiles->loop(); // #endif // if(millis()%2000==0){ // //watch->settimeUnix(time(&iotTimeNow)); // Serial.println(watch->gettime("d-m-Y, H:i:s, M")); // delay(1); // } // File dir = FileFS.open("/", "r"); // String out; // printDirectory(dir, out); // Serial.println(out); //=======проверка очереди из структур================= // myDB = new IoTDB; // QueueItems myItem; // myItem.myword = "word1"; // myDB->push(myItem); // myItem.myword = "word2"; // myDB->push(myItem); // myItem.myword = "word3"; // myDB->push(myItem); // Serial.println(myDB->front().myword); // Serial.println(myDB->front().myword); // Serial.println(myDB->front().myword); // Serial.println(FileList("lg"));