#include #include #include #include #include #include #include #include #include #include #include #define NTP_PORT 2392 #define MAX_WAIT_TIME 550 #define EEPROM_SIZE 512 // NTP-Client IPAddress timeServerIP; const char* ntpServerName = "time.nist.gov"; const int NTP_PACKET_SIZE = 48; byte ntpPacketBuffer[NTP_PACKET_SIZE]; WiFiUDP ntp; unsigned long timestamp = 0; unsigned long timeReceived = 0; unsigned long lastStorageTime = 0; byte storeAtBoot = 1; unsigned long lastNTP = 0; SHT21 SHT21; ESP8266WebServer server(80); WiFiServer serverSocket(2391); WebSocketServer webSocketServer; #define DEFAULT_SSID "ESP-Weather" #define DEFAULT_PASS "testtest" IPAddress broadcastIP; struct __attribute__((__packed__)) Measurement { float temperature; float humidity; }; struct __attribute__((__packed__)) Header { uint16_t count; uint16_t checksum; }; #define MAX_STORAGE (EEPROM_SIZE - sizeof(Header)) / sizeof(Measurement) struct __attribute__((__packed__)) PersistentStorage { Measurement data[MAX_STORAGE]; Header header; }; PersistentStorage storage; void writeMemory(PersistentStorage &s) { Serial.println("write Memory"); unsigned char* r = (unsigned char*) &s; uint16_t a = 0, b = 0; for(int i = 0; i < sizeof(PersistentStorage) - 2; i++) { a = (a + r[i]) % 255; b = (b + a) % 255; } s.header.checksum = (b << 8) | a; for(int i = 0; i < sizeof(PersistentStorage); i++) { EEPROM.write(i, r[i]); } EEPROM.commit(); } PersistentStorage readMemory() { PersistentStorage s; unsigned char* r = (unsigned char*) &s; for(int i = 0; i < sizeof(PersistentStorage); i++) { r[i] = EEPROM.read(i); } uint16_t a = 0, b = 0; for(int i = 0; i < sizeof(PersistentStorage) - 2; i++) { a = (a + r[i]) % 255; b = (b + a) % 255; } if(s.header.checksum != ((b << 8) | a)) { Serial.print("Checksum error "); Serial.print(s.header.checksum); Serial.print(" "); Serial.println((b << 8) | a); s.header.count = 0; } else { Serial.println("Checksum ok"); } return s; } std::vector vecClients; // UDP-Config unsigned int localPort = 2390; char packetBuffer[255]; char pingBuffer[] = "pingESP8266v0.1"; char echoBuffer[] = "echoESP8266v0.1"; WiFiUDP Udp; unsigned long lastTime; bool waitingForReplies = false; const char* htmlBegin = "\ \ Sysadmin\ \ \ \ \ \ \ \ \ \ "; // root-URL void handleRoot() { // send a reply, to the IP address and port that sent us the packet we received Udp.beginPacket(broadcastIP, 2390); Udp.write(pingBuffer); Udp.endPacket(); // Timer starten lastTime = millis(); waitingForReplies = true; Serial.println("Sending UDP Broadcast..."); } // URL nicht vorhanden void handleNotFound(){ String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET)?"GET":"POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i=0; i 2000)) { Serial.println("NTP packet retry..."); WiFi.hostByName(ntpServerName, timeServerIP); lastNTP = millis(); sendNTPpacket(timeServerIP); } // NTP Paket vom Server erhalten if (ntp.parsePacket() >= NTP_PACKET_SIZE) { ntp.read(ntpPacketBuffer, NTP_PACKET_SIZE); unsigned long highWord = word(ntpPacketBuffer[40], ntpPacketBuffer[41]); unsigned long lowWord = word(ntpPacketBuffer[42], ntpPacketBuffer[43]); unsigned long secsSince1900 = highWord << 16 | lowWord; const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears; timestamp = epoch; timeReceived = millis(); Serial.print("Got NTP time: "); Serial.println(epoch); } // EEPROM-Schreiben jede Stunde if ((((((millis() - timeReceived) / 1000) + timestamp) % 3600) == 0) && (timestamp != 0) && (((millis() - lastStorageTime) > 100000) || storeAtBoot) ) { Serial.println("Storing new data packet..."); lastStorageTime = millis(); storeAtBoot = 0; if (storage.header.count < MAX_STORAGE) { storage.header.count++; } else { for(int i = 0; i < MAX_STORAGE - 1; i++) { storage.data[i] = storage.data[i+1]; } } storage.data[storage.header.count-1].temperature = SHT21.getTemperature(); storage.data[storage.header.count-1].humidity = SHT21.getHumidity(); writeMemory(storage); } // UDP int packetSize = Udp.parsePacket(); if (packetSize) { IPAddress remoteIp = Udp.remoteIP(); // read the packet into packetBufffer int len = Udp.read(packetBuffer, 255); if (len > 0) { packetBuffer[len] = 0; } Serial.print("Got UDP packet: "); Serial.println(packetBuffer); if (strcmp(packetBuffer, pingBuffer) == 0) { Serial.println("Broadcast"); Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); Udp.print(echoBuffer); Udp.endPacket(); } else if((strcmp(packetBuffer, echoBuffer) == 0) && (waitingForReplies == true)) { vecClients.push_back(Udp.remoteIP()); } } if (((millis() - lastTime) >= MAX_WAIT_TIME) && (waitingForReplies == true)) { Serial.println("Timeout, sending response..."); waitingForReplies = false; String message = htmlBegin; message += "var clients = Array("; message += "\"" + WiFi.localIP().toString() + "\""; if(vecClients.size() > 0) { message += ", "; } for(int i = 0; i < vecClients.size(); i++) { message += "\"" + vecClients[i].toString() + "\""; if(i < (vecClients.size() - 1)) { message += ", "; } } message += ");"; message += htmlEnd; vecClients.clear(); server.send(200, "text/html", message); } } void sendNTPpacket(IPAddress& address) { Serial.println("Sending NTP packet..."); memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE); ntpPacketBuffer[0] = 0b11100011; // LI, Version, Mode ntpPacketBuffer[1] = 0; ntpPacketBuffer[2] = 6; ntpPacketBuffer[3] = 0xEC; ntpPacketBuffer[12] = 49; ntpPacketBuffer[13] = 0x4E; ntpPacketBuffer[14] = 49; ntpPacketBuffer[15] = 52; ntp.beginPacket(address, 123); ntp.write(ntpPacketBuffer, NTP_PACKET_SIZE); ntp.endPacket(); }