// Anregungen: Film-Werk56 https://www.youtube.com/watch?v=IUkMOGQ0ZQs // https://randomnerdtutorials.com/esp32-web-server-arduino-ide/ // ESP32: AZDelivery ESP32S Dev Kit C V4 NodeMCU WLAN WiFi // Board: ESP32 Wrover Kit (all Versions) // IDE 2.2.1 // Zweirichtungszähler mMe4.0 #include #include #include const char* ssid = "meinNetz"; const char* password = "meineIP"; #define RX18 18 // Serieller Input optische Info-/MSB-Schnittstelle #define TX19 19 // Serieller Output int Led1 = 26; unsigned char inByte = 0; // Ir Data unsigned char Data[300]; // Ir Data 16 Bit unsigned char Value[5] = { 0x30, 0x30, 0x30, 0x30, 0x00 }; // Vorbelegung unsigned char Z; // fuer Umrechnung Hex/Dez char Val[9]; // 8 Bytes + NULL // Current time unsigned long currentTime = millis(); // Previous time unsigned long previousTime = 0; // Define timeout time in milliseconds (example: 2000ms = 2s) const long timeoutTime = 2000; int Ph1; // Phase1 int Ph2; // Phase2 int Ph3; // Phase3 int Ph4; // Phase int Power; // aktueller Verbrauch EGG float VBZ; // Verbrauchszähler float V18; // Verbrauchszähler float EBZ; // Einspeisung float V28; // Einspeisung int V180; // Export TX19 int V280; // Export TX19 volatile int Counter = 0; // Pointer Ir Data Array int SML = 0; // SML Anzahl Startbytes byte Start = 0; // Warte auf Daten WiFiServer server(80); // Variable to store the HTTP request String header; void setup() { Serial.begin(115200); Serial1.begin(9600, SERIAL_8N1, RX18, TX19); // RX18 IR-Lesekopf Eingang, TX19 Output WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); } // Print local IP address and start web server Serial.println(""); Serial.println("WiFi connected."); Serial.print("IP address: "); Serial.println(WiFi.localIP()); Serial.print("MAC: "); Serial.println(WiFi.macAddress()); server.begin(); pinMode(Led1, OUTPUT); // Aktivitaets LED digitalWrite(Led1, HIGH); // LED an Serial.println(""); Serial.print("Version: "); // Daten werden gespeichert Serial.print(strrchr(__FILE__, '\\') + 1); // File-Name der .ino Serial.print(" "); Serial.print(__DATE__); // Datum des Ladens auf den ESP Serial.print(" "); (__TIME__); // Zeit des Ladens auf den ESP delay(1000); } // Convert Hex Byte to ASCII Character char HexToChar(unsigned char ZZ) { if (ZZ == 00) return '0'; if (ZZ == 01) return '1'; if (ZZ == 02) return '2'; if (ZZ == 03) return '3'; if (ZZ == 04) return '4'; if (ZZ == 05) return '5'; if (ZZ == 06) return '6'; if (ZZ == 07) return '7'; if (ZZ == 0x8) return '8'; if (ZZ == 0x9) return '9'; if (ZZ == 0xA) return 'A'; if (ZZ == 0xB) return 'B'; if (ZZ == 0xC) return 'C'; if (ZZ == 0xD) return 'D'; if (ZZ == 0xE) return 'E'; if (ZZ == 0xF) return 'F'; } // Converting from Hex to Decimal long int16_t hex2int(const char* hex) { uint16_t value; // unsigned to avoid signed overflow for (value = 0; *hex; hex++) { value <<= 4; if (*hex >= '0' && *hex <= '9') value |= *hex - '0'; else if (*hex >= 'A' && *hex <= 'F') value |= *hex - 'A' + 10; else if (*hex >= 'a' && *hex <= 'f') value |= *hex - 'a' + 10; else break; // stop at first non-hex digit } return value; } void loop() { WiFiClient client = server.available(); // Listen for incoming clients if (client) { // If a new client connects, currentTime = millis(); previousTime = currentTime; //Serial.println("New Client."); // print a message out in the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected currentTime = millis(); if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then //Serial.write(c); // print it out the serial monitor header += c; if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println("Refresh: 3\r\n"); // refresh the page automatically every 3 sec client.println(); client.println(""); client.println("Zählerstände"); client.println(""); client.println(""); //client.println(""); client.println(""); client.println(""); client.println("

Energiezähler

"); client.println("
"); client.println("
"); // Tabelle client.println(""); client.println(""); client.println(""); // Hier geht es weiter client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println(""); client.println("
"); client.println(""); client.println("Verbrauch"); client.println(""); client.println("
L1:"); client.println(Ph1); client.println("Watt
L2:"); client.println(Ph2); client.println("Watt
L3:"); client.println(Ph3); client.println("Watt
Summe:"); client.println(Ph1 + Ph2 + Ph3); client.println("Watt
"); client.println(""); client.println("Zählerstände"); client.println(""); client.println(""); client.println("
Verbrauch:"); client.println(V18); client.println("kWh
Einspeisung:"); client.println(V28); client.println("kWh
"); client.println("
"); client.println("
"); client.println("
"); client.println(""); // The HTTP response ends with another blank line client.println(); // Break out of the while loop break; } else { // if you got a newline, then clear currentLine currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } } } // Clear the header variable header = ""; // Close the connection client.stop(); //Serial.println("Client disconnected."); //Serial.println(""); } // Einlesen der Daten if (Serial1.available()) //IR Daten { digitalWrite(Led1, LOW); inByte = Serial1.read(); if (inByte == 27) SML++; else SML = 0; // Hex 1B 1B 1B 1B, SML Nachricht Start und Ende Sequenz } if (SML == 4) // SML Data { while (Counter < 300) { if (Serial1.available()) { inByte = Serial1.read(); Data[Counter++] = inByte; // SML Datensatz einlesen } } Counter = 0; } if (SML == 4) // Datensatz empfangen { SML = 0; // Reset SML Data Block Flag for (int x = 0; x < 300; x++) { // Phase1 ---------------------------------------------------------------------- if (Data[x] == 36 && Data[x + 1] == 7 && Data[x + 2] == 00 && Data[x + 3] == 255) { Value[0] = Data[x + 18]; Value[1] = Data[x + 19]; Value[2] = Data[x + 20]; Value[3] = Data[x + 21]; Z = Value[0] & 240; Z = Z >> 4; Val[0] = HexToChar(Z); Z = Value[0] & 15; Val[1] = HexToChar(Z); Z = Value[1] & 240; Z = Z >> 4; Val[2] = HexToChar(Z); Z = Value[1] & 15; Val[3] = HexToChar(Z); Z = Value[2] & 240; Z = Z >> 4; Val[4] = HexToChar(Z); Z = Value[2] & 15; Val[5] = HexToChar(Z); Z = Value[3] & 240; Z = Z >> 4; Val[6] = HexToChar(Z); Z = Value[3] & 15; Val[7] = HexToChar(Z); Val[8] = '\0'; Ph1 = (hex2int(Val)); } // Phase2 if (Data[x] == 56 && Data[x + 1] == 7 && Data[x + 2] == 00 && Data[x + 3] == 255) { Value[0] = Data[x + 18]; Value[1] = Data[x + 19]; Value[2] = Data[x + 20]; Value[3] = Data[x + 21]; Z = Value[0] & 240; Z = Z >> 4; Val[0] = HexToChar(Z); Z = Value[0] & 15; Val[1] = HexToChar(Z); Z = Value[1] & 240; Z = Z >> 4; Val[2] = HexToChar(Z); Z = Value[1] & 15; Val[3] = HexToChar(Z); Z = Value[2] & 240; Z = Z >> 4; Val[4] = HexToChar(Z); Z = Value[2] & 15; Val[5] = HexToChar(Z); Z = Value[3] & 240; Z = Z >> 4; Val[6] = HexToChar(Z); Z = Value[3] & 15; Val[7] = HexToChar(Z); Val[8] = '\0'; Ph2 = (hex2int(Val)); } // Phase3 if (Data[x] == 76 && Data[x + 1] == 7 && Data[x + 2] == 00 && Data[x + 3] == 255) { Value[0] = Data[x + 18]; Value[1] = Data[x + 19]; Value[2] = Data[x + 20]; Value[3] = Data[x + 21]; Z = Value[0] & 240; Z = Z >> 4; Val[0] = HexToChar(Z); Z = Value[0] & 15; Val[1] = HexToChar(Z); Z = Value[1] & 240; Z = Z >> 4; Val[2] = HexToChar(Z); Z = Value[1] & 15; Val[3] = HexToChar(Z); Z = Value[2] & 240; Z = Z >> 4; Val[4] = HexToChar(Z); Z = Value[2] & 15; Val[5] = HexToChar(Z); Z = Value[3] & 240; Z = Z >> 4; Val[6] = HexToChar(Z); Z = Value[3] & 15; Val[7] = HexToChar(Z); Val[8] = '\0'; Ph3 = (hex2int(Val)); } // Verbrauchszähler -------------------------------------------------------------- if (Data[x] == 1 && Data[x + 1] == 8 && Data[x + 2] == 00 && Data[x + 3] == 255) { Value[0] = Data[x + 25]; Value[1] = Data[x + 26]; Value[2] = Data[x + 27]; Value[3] = Data[x + 28]; Z = Value[0] & 240; Z = Z >> 4; Val[0] = HexToChar(Z); Z = Value[0] & 15; Val[1] = HexToChar(Z); Z = Value[1] & 240; Z = Z >> 4; Val[2] = HexToChar(Z); Z = Value[1] & 15; Val[3] = HexToChar(Z); Z = Value[2] & 240; Z = Z >> 4; Val[4] = HexToChar(Z); Z = Value[2] & 15; Val[5] = HexToChar(Z); Z = Value[3] & 240; Z = Z >> 4; Val[6] = HexToChar(Z); Z = Value[3] & 15; Val[7] = HexToChar(Z); Val[8] = '\0'; VBZ = (strtol(Val, NULL, 16)); // // Wert Verbrauchszähler } // Einspeisung ------------------------------------------------------------------- if (Data[x] == 2 && Data[x + 1] == 8 && Data[x + 2] == 00 && Data[x + 3] == 255) { Value[0] = Data[x + 22]; Value[1] = Data[x + 23]; Value[2] = Data[x + 24]; Value[3] = Data[x + 25]; Z = Value[0] & 240; Z = Z >> 4; Val[0] = HexToChar(Z); Z = Value[0] & 15; Val[1] = HexToChar(Z); Z = Value[1] & 240; Z = Z >> 4; Val[2] = HexToChar(Z); Z = Value[1] & 15; Val[3] = HexToChar(Z); Z = Value[2] & 240; Z = Z >> 4; Val[4] = HexToChar(Z); Z = Value[2] & 15; Val[5] = HexToChar(Z); Z = Value[3] & 240; Z = Z >> 4; Val[6] = HexToChar(Z); Z = Value[3] & 15; Val[7] = HexToChar(Z); Val[8] = '\0'; EBZ = (strtol(Val, NULL, 16)); // Wert Einspeisezähler } V18 = VBZ / 10000; V28 = EBZ / 10000; } Serial.print("Ph1 "); Serial.print(Ph1); Serial.print(" Ph2 "); Serial.print(Ph2); Serial.print(" Ph3 "); Serial.print(Ph3); Serial.print(" VBZ "); Serial.print(V18); // Verbrauchszähler Serial.print(" EBZ "); Serial.println(V28); // Einspeisezähler // Serial1 an TX19 char buffer[9]; sprintf(buffer, "%05d", int(Ph1)); Serial1.print(buffer); Serial1.print(";"); sprintf(buffer, "%05d", int(Ph2)); Serial1.print(buffer); Serial1.print(";"); sprintf(buffer, "%05d", int(Ph3)); Serial1.print(buffer); Serial1.print(";"); V180 = round(VBZ / 100); V280 = round(EBZ / 100); sprintf(buffer, "%08d", int(V180)); Serial1.print(buffer); Serial1.print(";"); sprintf(buffer, "%08d", int(V280)); Serial1.println(buffer); } digitalWrite(Led1, HIGH); }