/* ESP32 Receiver (ESP-NOW + Web Server) Complete project details at https://RandomNerdTutorials.com/esp32-esp-now-wi-fi-web-server/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. */ //08:3A:F2:A7:80:6C //esp32 желтые ноги //08:3A:F2:66:31:30 //esp32 lilygo2,3 //08:3A:F2: //esp32 lilygo4,7 #define SD_MISO 12 #define SD_MOSI 13 #define SD_SCLK 14 #define SD_CS 15 #include #define WDT_TIMEOUT 10 #include #include "ESPAsyncWebSrv.h" #include #include #include #include "FS.h" #include "SD.h" #include "SPI.h" #include #include "NTPClient.h" #include "WiFiUdp.h" #include UnixTime stamp(0); // указать GMT (3 для Москвы) // Define deep sleep options String dataMessage; // Define NTP Client to get time WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP); #include "nRF24L01.h" #include "RF24.h" char msg[16]; //RF24 radio(12, 14, 26, 25, 27); //RF24 radio(27, 26, 32, 33, 25);//server (ce,csn,sck,miso,mosi)esp32 RF24 radio(17, 16, 32, 33, 25);//server (ce,csn,sck,miso,mosi)esp32 const uint64_t pip = 0x02E423E4E2LL; SPIClass sdSPI(HSPI); File myFile; String jsonString;//"{\"id\":2,\"temperature\":9.6733450317382812,\"humidity\":50.41815185546875,\"readingId\":\"2\"}"; String jsonString1; String jsonString2;//="{\"tkom1\":\"20.0\",\"hkom1\":\"30.0\",\"batkom1\":\"0.00\",\"timekom1\":\"00:00\",\"tkom2\":\"\",\"hkom2\":\"\",\"batkom2\":\"\",\"timekom2\":\"\",\"tkor\":\"\",\"hkor\":\"\",\"batkor\":\"\",\"timekor\":\"\",\"tbal\":\"\",\"hbal\":\"\",\"batbal\":\"\",\"timebal\":\"\"}" ; // Replace with your network credentials (STATION) const char* ssid = "VOVA-47"; const char* password = "vovak26102003"; char *time_buf; const char* PARAM_INPUT_1 = "output"; const char* PARAM_INPUT_2 = "state"; // Structure example to receive data // Must match the sender structure typedef struct struct_message { int id=0; float temp=0; float hum=0; unsigned int readingId=0; } struct_message; struct_message incomingReadings; JSONVar board; JSONVar board1; JSONVar board2; AsyncWebServer server(80); AsyncEventSource events("/events"); //************************************************************************************************* char* strd[] = {"01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"}; char* strm[] = {"январь","февраль","март","апрель","май","июнь","июль","август","сентябрь","октябрь","ноябрь","декабрь"}; char* strweek[] = {"воскресенье","понедельник","вторник","среда","четверг","пятница","суббота","воскресенье"}; int nt=0;//номер термометра int nti=0;//номер термометра для сайта int temperature1=10; double ts; double hs; String t1; String h1; String t10;//время работы сервера String tim3;// время от нтп сервера при приходе данных с NOW String tim2;//время получ от устройства NOW String munthserv;//месяц String weekserv;//день недели String tkom1;//температура String hkom1;//влажность String batkom1; String timekom1;//время прихода данных комната1 String tkom2; String hkom2; String batkom2; String timekom2; String tkor; String hkor; String batkor; String timekor; String tbal; String hbal; String batbal; String timebal; String timeul1; String tul1; String hul1; String osv1; int ct1=0;//счетчик пропуска данные каждые 3 минуты записываем каждые 20 те 7 пропусков int time17=0; int hour1=10; int min1=7; int sek=0; int hk=0;//часы для исключения повтора записи данных int mk=0;//минуты int hb=0;//часы для исключения повтора записи данных int mb=0;//минуты int hkr=0;//часы для исключения повтора записи данных int mkr=0;//минуты int timev=0;//для пропуска 20 минут //String timev1;//для записи на флэш при сбросе boolean fdata=0;//флаг обновления данных темп и влажн int fobnov=1;//флаг обновления данных темп и влажн String timeserv;//время сервера String dataserv;//дата int v=0; int v1=0; long EpochTime=0; int ind=0; String strdat;//накопленые в памяти данные по темп и влажность передаваемые клиенту String tempdat;// int ftdata=0;//флаг запроса данных темп и влажн int fping=0;// флаг для задержки отр данных на страницу inform int wright=0; bool flread=0; char* strden[] = {"/01","/02","/03","/04","/05","/06","/07","/08","/09","/10","/11","/12","/13","/14","/15","/16","/17","/18","/19","/20","/21","/22","/23","/24","/25","/26","/27","/28","/29","/30","/31"}; char* strmen[] = {"/JAN","/FEBR","/MARCH","/APRIL","/MAY","/JUNE","/JULY","/AUG","/SEPT","/OCT","/NOV","/DEC"}; char* stryen[] = {"/2014","/2015","/2016","/2017","/D-2018","/D-2019","/D-2020","/D-2021","/D-2022","/D-2023","/D-2024","/D-2025","/D-2026","/D-2027","/D-2028","/D-2029","/D-2030","/D-2031","/D-2032","D-2033","/D-2034","/D-2035"}; char* strdaten[] = {"/T1.txt","/T2.txt","/T3.txt","/T4.txt","/T5.txt","/T6.txt","/T7.txt","/T8.txt","/T9.txt","/T10.txt"}; //************************************************************ hw_timer_t * timer = NULL; volatile SemaphoreHandle_t timerSemaphore; portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; volatile uint32_t isrCounter = 0; volatile uint32_t lastIsrAt = 0; //************************************************************************************************** // ntp String formattedDate; String formattedTime; String dayStamp; String timeStamp; //***************************************************************************** //**************************************************************************** String outputState(int output){ if(digitalRead(output)){ return "checked"; } else { return ""; } } String processor(const String& var){ //Serial.println(var); if(var == "BUTTONPLACEHOLDER1"){ String buttons = ""; // buttons += "

Output - GPIO 12

"; buttons += "

Output - GPIO 13

"; // buttons += "

Output - GPIO 14

"; return buttons; } return String(); } /* if(var == "HOLDERT1"){ String buttons = ""; buttons +="

"+t1+" °C

"; String hour11=String(hour1, DEC); String min11=String(min1, DEC); if(min1<10){min11="0"+min11;} buttons +="

"+hour11+":"+min11+"

"; return buttons; } if(var == "HOLDERH1"){ String buttons = ""; buttons +="

"+h1+" %

"; String hour11=String(hour1, DEC); String min11=String(min1, DEC); if(min1<10){min11="0"+min11;} buttons +="

"+hour11+":"+min11+"

"; return buttons; } */ /*if(var == "HOLDER2"){ String buttons = ""; buttons +="

"+t10+"

"; return buttons; }*/ //************************************************ //*********************************************************** void vrem(); void handle_OnConnect(); void ntp(); void ntphome(); void IRAM_ATTR onTimer(); void event(); void WiFisetup(); void savedata(); void JSstringU(); void JSstringK(); void Sdreaddata(); void Nrfsetup(); void nrf(); void parsmsg(); void settimer(); void readdata(); //void ansv(); //*********************************************************** void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) { // Copies the sender mac address to a string char macStr[18]; Serial.print("Packet received from: "); snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); Serial.println(macStr); memcpy(&incomingReadings, incomingData, sizeof(incomingReadings)); Serial.printf("Board ID %u: %u bytes\n", incomingReadings.id, len); Serial.printf("t value: %4.2f \n", incomingReadings.temp); t1 = incomingReadings.temp; Serial.printf("h value: %4.2f \n", incomingReadings.hum); h1=incomingReadings.hum; Serial.printf("readingID value: %d \n", incomingReadings.readingId); int tim11 =incomingReadings.readingId; hour1=tim11/100; min1=tim11%100; //JSONстрока формирование ntphome(); tim3=timeserv; JSstringU(); events.send(jsonString.c_str(), "new_readings", millis());//обновление веба // fdata=1; // fdata=0; savedata(); }//OnDataRecv //**************************************************************************** void configureEvents() { events.onConnect([](AsyncEventSourceClient *client){ if(client->lastId()){ Serial.printf("Client connections. Id: %u\n", client->lastId()); } // and set reconnect delay to 1 second client->send("hello from ESP32",NULL,millis(),1000); }); }// configureEvents //********************************************************************************************************* void setup() { // Initialize Serial Monitor pinMode(13, OUTPUT); digitalWrite(13, LOW); Serial.begin(115200); if(!SPIFFS.begin()){ Serial.println("An Error has occurred while mounting SPIFFS"); return; } sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS); if (!SD.begin(SD_CS, sdSPI)) { // if(!SD.begin()){ Serial.println("Mounting card mount failed"); // return; } uint8_t cardType = SD.cardType(); if(cardType == CARD_NONE){ Serial.println("No SD card attached"); //return; } uint64_t cardSize = SD.cardSize() / (1024 * 1024); Serial.printf("SD Card Size: %lluMB\n", cardSize); Sdreaddata(); Nrfsetup(); settimer(); WiFisetup(); // Initialize a NTPClient to get time timeClient.begin(); // Set offset time in seconds to adjust for your timezone, for example: // GMT +1 = 3600 // GMT +8 = 28800 // GMT -1 = -3600 // GMT 0 = 0 timeClient.setTimeOffset(10800); // Once ESPNow is successfully Init, we will register for recv CB to // get recv packer info esp_now_register_recv_cb(OnDataRecv); ntp();//NTP init server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/index.html", String(), false, processor); fobnov=1; }); server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/index.html", String(), false, processor); fobnov=1; }); // Route to load style.css file server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/style.css", "text/css"); }); server.on("/fon.jpg", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/fon.jpg"); }); server.on("/upravlenie.html", HTTP_GET, [](AsyncWebServerRequest *request){ fobnov=1; request->send(SPIFFS, "/upravlenie.html", String(), false, processor); }); server.on("/setting.html", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/setting.html"); }); server.on("/inform.html", HTTP_GET, [](AsyncWebServerRequest *request){ ftdata=1; fping=0; // Serial.println ("ftdata==1"); request->send(SPIFFS, "/inform.html"); }); server.on("/inform1.html", HTTP_GET, [](AsyncWebServerRequest *request){ ftdata=2; fping=0; // Serial.println ("ftdata==1"); request->send(SPIFFS, "/inform1.html"); }); server.on("/inform2.html", HTTP_GET, [](AsyncWebServerRequest *request){ ftdata=4; fping=0; // Serial.println ("ftdata==1"); request->send(SPIFFS, "/inform2.html"); }); server.on("/inform3.html", HTTP_GET, [](AsyncWebServerRequest *request){ ftdata=7; fping=0; // Serial.println ("ftdata==1"); request->send(SPIFFS, "/inform3.html"); }); server.on("/inform4.html", HTTP_GET, [](AsyncWebServerRequest *request){ ftdata=3; fping=0; // Serial.println ("ftdata==1"); request->send(SPIFFS, "/inform4.html"); }); server.on("/inform5.html", HTTP_GET, [](AsyncWebServerRequest *request){ ftdata=5; fping=0; // Serial.println ("ftdata==1"); request->send(SPIFFS, "/inform5.html"); }); server.on("/inform6.html", HTTP_GET, [](AsyncWebServerRequest *request){ ftdata=6; fping=0; // Serial.println ("ftdata==1"); request->send(SPIFFS, "/inform6.html"); }); server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/favicon.ico"); }); server.on("/favicon-32x32.png", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/favicon-32x32.png"); }); server.on("/favicon-16x16.png", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/favicon-32x32.png"); }); // Send a GET request to /update?output=&state= принимаем get сообщение от клиента при нажати кнопки // принимаем номер контакта и его состояние // GET http://192.168.1.100/update?output=13&state=1 server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) { String inputMessage1; String inputMessage2; // GET input1 value on /update?output=&state= if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2)) { inputMessage1 = request->getParam(PARAM_INPUT_1)->value(); inputMessage2 = request->getParam(PARAM_INPUT_2)->value(); digitalWrite(inputMessage1.toInt(), inputMessage2.toInt()); } else { inputMessage1 = "No message sent"; inputMessage2 = "No message sent"; } Serial.print("GPIO: "); Serial.print(inputMessage1); Serial.print(" - Set to: "); Serial.println(inputMessage2); request->send(200, "text/plain", "OK"); }); JSstringU(); JSstringK(); configureEvents(); server.addHandler(&events); server.begin(); esp_task_wdt_init(WDT_TIMEOUT, true); //включить панику, чтобы ESP32 перезапустился esp_task_wdt_add(NULL); //добавить текущий поток в WDT watch } //*********************************************************************************************************** //*********************************************************************************************************** //*********************************************************************************************************** void loop() { static unsigned long lastEventTime = millis(); static const unsigned long EVENT_INTERVAL_MS = 5000; if (v>3) {//20sek ntphome();//считываем время v=0;//обнуляем счетчик 4*5=20с } if (v1>240) {//20min ntp();//считываем время v1=0;//обнуляем счетчик 240*5=1200с } // digitalWrite(13, HIGH); // светодиод горит // digitalWrite(13, LOW); // светодиод погашен if ((millis() - lastEventTime) > EVENT_INTERVAL_MS) { events.send("ping",NULL,millis()); lastEventTime = millis(); v++; v1++; vrem();//время работы сайта events.send(t10.c_str(), "t10", millis());//время работы сайта обн каждые 5сек events.send(timeserv.c_str(), "timeserv", millis());//время обн каждые 5сек fping++;//задержка отправки данных на стр до готовности стр принять их if(fping>1000){fping=0;} nrf(); //проверяем не приш ли данные на NRF wright++;//сч времени для записи на флеш Serial.println (wright); Serial.print ("ftdata="); Serial.println (ftdata); Serial.print ("fobnov="); Serial.println (fobnov); if( ftdata==0) { if (fobnov>0) {//2,5sek fobnov++; if(fobnov>3){fobnov=0;} events.send(jsonString.c_str(), "new_readings", millis());//обновление веба текущая температура events.send(jsonString2.c_str(), "new_datatemp", millis());//обновление веба Serial.println("/index"); } } //***************************************************************************************** //******************************************************************************************* //********************************************************************************************* //********************************************************************************************** if (ftdata==2)//пришел запрос табл данных /inform ЗАПАД {// tim3=formattedTime; if(fping>2){fping=0;} if(fping==1){ events.send(jsonString2.c_str(), "new_datatemp", millis());//обновление веба } if(fping>1){ ftdata=0; fping=0; nti=1; readdata(); // Serial.println("data1"); events.send(strdat.c_str(), "readings", millis());//отправка данных из памяти в таблицу на стр inform } } //*************************************************************************************************** if (ftdata==1)//пришел запрос табл данных /inform ВОСТОК {// tim3=formattedTime; if(fping>2){fping=0;} if(fping==1){ // events.send(jsonString2.c_str(), "new_datatemp", millis());//обновление веба events.send(jsonString.c_str(), "new_readings", millis());//обновление данных ЗАПАД } if(fping>1){ ftdata=0; fping=0; nti=0; readdata(); events.send(strdat.c_str(), "readings", millis());//отправка данных из памяти в таблицу на стр inform // fobnov=1; } } //*************************************************************************************************** if (ftdata==3)//пришел запрос табл данных /inform коридор {// tim3=formattedTime; if(fping>2){fping=0;} if(fping==1){ events.send(jsonString2.c_str(), "new_datatemp", millis());//обновление данных Т Н ВАТ все кроме запад } if(fping>1){ ftdata=0; fping=0; nti=5; readdata(); events.send(strdat.c_str(), "readings", millis());//отправка данных из памяти в таблицу на стр inform } } //*************************************************************************************************** if (ftdata==5)//пришел запрос табл данных /inform балкон {// tim3=formattedTime; if(fping>2){fping=0;} if(fping==1){ events.send(jsonString2.c_str(), "new_datatemp", millis());//обновление данных Т Н ВАТ все кроме запад } if(fping>1){ ftdata=0; fping=0; nti=2; readdata(); events.send(strdat.c_str(), "readings", millis());//отправка данных из памяти в таблицу на стр inform } } //****************************************************************************************************** if (ftdata==4)//пришел запрос табл данных /inform К1 {// tim3=formattedTime; if(fping>2){fping=0;} if(fping==1){ events.send(jsonString2.c_str(), "new_datatemp", millis());//обновление данных Т Н ВАТ все кроме запад } if(fping>1){ ftdata=0; fping=0; nti=4; readdata(); events.send(strdat.c_str(), "readings", millis());//отправка данных из памяти в таблицу на стр inform } } //****************************************************************************************************** if (ftdata==7)//пришел запрос табл данных /inform К2 {// tim3=formattedTime; if(fping>2){fping=0;} if(fping==1){ events.send(jsonString2.c_str(), "new_datatemp", millis());//обновление данных Т Н ВАТ все кроме запад } if(fping>1){ ftdata=0; fping=0; nti=3; readdata(); events.send(strdat.c_str(), "readings", millis());//отправка данных из памяти в таблицу на стр inform } } //********************************************************************************************************* if (ftdata==6)//пришел запрос табл данных /inform {// tim3=formattedTime; if(fping>2){fping=0;} if(fping==1){ events.send(jsonString2.c_str(), "new_datatemp", millis());//обновление веба } if(fping>1){ ftdata=0; fping=0; nti=1; readdata(); Serial.println("data1"); events.send(strdat.c_str(), "readings", millis());//отправка данных из памяти в таблицу на стр inform } } } }