Hallo, dies ist mein erster Post im Forum.
Seit Tagen versuche ich, Daten vom SML Smartmeter (Iskra MT175) über den Hichi-Lesekopf zu lesen. Es kommt zwar etwas an, aber nicht die erwarteten Daten vom Smartmeter.
Deshalb habe ich zunächst einen Sketch geschrieben, der nur die seriallen Roh-Daten einlesen und als Hex-Daten ausgeben soll.
Die Ausgabe erfolgt über WebSerial auf einer Web-Seite, da Zähler und Computer weit auseinander sind.
Was ich bisher versucht habe:
-
Um sicher zu stellen, dass es kein HW-Problem ist (Lesekopf oder ESP8266) habe ich Tasmota mit dem SML-script auf dem ESP8266 installiert. Damit bekomme ich korrekte Werte angezeigt.
-
Im eigenen Sketch habe ich die "Standard" SoftwareSerial library verwendet, um über Pin D1 die Daten zu lesen, aber da kommen wie gesagt nur unsinnige Daten . Wenn ich allerdings die Pins D1 und D2 verbinde, und einen Text eintippe (siehe Sketch), erhalte ich die korrekten Hex-Codes.
-
Da das nicht richtig funktionierte habe ich die TasmotaSerial library eingebunden (mit Tasmota funktionierte es ja). Hier bekomme ich auch unsinnige Daten, allerdings andere (und mehr) als mit der SoftwareSerial lib. Hier funktioniert das Schreiben von Pin D2 auf D1 allerdings nicht.
Hier nun der Sketch. Ich habe ihn mit PlatformIO entwickelt. Die "Bedienung" ist im Code erläutert.
/******************************************
* This is a demo program to test Serial libratries on the ESP8266.
* Used libraries are standard "SoftwareSerial" amd "TasotaSerial"
*
* using this program:
* first fill in the values for ssid, password, STATIC_IP, GATEWAY, SUBNET, and DNS for the ESP8266
* UPload to a ESP8266 (e. g. wemos d1 mini)
* In a browser open the given STATIC_IP
* Click the link to "Console"
*
* In the input-box of the console you can now enter a 't' for the TasmotaSerial-lib,
* or an 's' for the SoftwareSerial-lib
*
* Now there are 2 scenarios:
* 1. connect D1 of the Wemos with the output of a Hichi Smartmeter IR-adapter
* 2. connect D1 of the Wemos with D2
*
* Use case 1:
* With either TasmotaSerial or SoftwareSerial the same data coming from the SML meter should
* shown in the console
*
* Use case 2:
* Type a text in the input-window of the console that does not start with 't' or 's'.
* The hex-codes of the chars should be displayed in the console
*
*****/
#include <SoftwareSerial.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>
#include <WebSerialLite.h>
#include <TasmotaSerial.h>
const char* ssid = "<ENTER SSID OF YOUR WIFI HERE>";
const char* password = "<ENTER PASSWORD OF YOUR WIFI HERE>";
IPAddress STATIC_IP(192,168,0,100); // <- enter the IP-address your ESP8266 should get
// !!! note that the numbers are separated with commas,
// not points !!
IPAddress GATEWAY(192, 168, 0, 1); // <- enter the gateway of your network here
IPAddress SUBNET(255, 255, 255, 0); // <- enter the subnet mask here
IPAddress DNS(8, 8, 8, 8); // <- enter the ip of the DNS-server here
AsyncWebServer server(80);
bool useTasmota = true; // allow to use either the standard SoftwareSerial lib, or the serial-lib from Tasmota
SoftwareSerial *ssSerial = useTasmota ? NULL : new SoftwareSerial(D1, D2);
TasmotaSerial *tsSerial = useTasmota ? new TasmotaSerial(D1, D2) : NULL;
// receive message from WebSerial (Web-console)
// can be used to switch between standard Serial and Tasmota serial
void recvMsg(uint8_t* data, size_t len) {
String d = "";
for (unsigned int i = 0; i < len; i++) {
d += char(data[i]);
}
if (d.startsWith("t")) {
useTasmota = true;
if (ssSerial != NULL) {
delete ssSerial;
ssSerial = NULL;
}
if (tsSerial == NULL) {
tsSerial = new TasmotaSerial(D1, D2);
tsSerial->begin(9600, SWSERIAL_8N1);
}
} else if (d.startsWith("s")) {
useTasmota = false;
if (tsSerial != NULL) {
delete tsSerial;
tsSerial = NULL;
}
if (ssSerial == NULL) {
ssSerial = new SoftwareSerial(D1, D2);
ssSerial->begin(9600, SWSERIAL_8N1);
}
} else if (d.length() > 0){
if(useTasmota) {
if (tsSerial != NULL) {
for (int i = 0; i < d.length(); ++i) {
tsSerial->write(d[i]);
}
}
} else {
if (ssSerial != NULL) {
for(int i = 0; i < d.length(); ++i) {
ssSerial->write(d[i]);
}
}
}
}
WebSerial.printf("\nUsing %s for serial communication\n", (useTasmota ? "TasmotaSerial" : "SoftwareSerial"));
}
void setup() {
if (useTasmota) {
tsSerial->begin(9600, SWSERIAL_8N1);
} else {
ssSerial->begin(9600, SWSERIAL_8N1);
}
Serial.begin(115200); // baud serial
WiFi.mode(WIFI_STA);
WiFi.config(STATIC_IP, GATEWAY, SUBNET, DNS);
while(WiFi.status() != WL_CONNECTED){
delay(400);
Serial.print(".");
}
Serial.println("IP Address: ");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(200, "text/html", "<html><body><h2>Webserver running...</h2>"
"<a href=\"/webserial\" target=\"_blank\">Console</a><p>"
"<a href=\"/update\" target=\"_blank\">Update</a></body></html>");
});
AsyncElegantOTA.begin(&server);
WebSerial.begin(&server);
WebSerial.onMessage(recvMsg);
server.begin();
}
byte values[500];
char prtbuf[1540];
bool serialAvailable() {
return useTasmota ? tsSerial->available() != 0 : ssSerial->available() != 0;
}
byte serialRead(){
return useTasmota ? tsSerial->read() : ssSerial->read();
}
// wait for a pause in serial-stream of at least ms milliseconds
void waitForPause(unsigned long ms){
long start = millis();
while (millis() - start < ms) {
yield();
while(serialAvailable()) {
serialRead(); // flush the data
yield();
start = millis();
}
}
}
void waitForData() {
while(!serialAvailable()) {
yield();
}
}
// read serial data in the buffer. Allow max maxTime or maxCount bytes (whatever comes first)
int readData(byte *buf, int maxCount, unsigned long maxTime){
unsigned long start = millis();
byte *ptr = buf;
while (ptr - buf < maxCount-1 && millis() - start < maxTime ){
while(ptr - buf < maxCount-1 && millis() - start < maxTime && serialAvailable()){
*(ptr++) = serialRead();
}
yield();
}
return ptr - buf;
}
void bytesToString(char *strbuf, byte *valbuf, int count){
char *sPtr = strbuf;
byte *vPtr = valbuf;
const static char nibble[] = "0123456789ABCDEF";
for (int i = 0; i < count; ++i) {
*(sPtr++) = nibble[*vPtr >> 4];
*(sPtr++) = nibble[*vPtr & 0x0F];
*(sPtr++) = ' ';
*sPtr = 0;
++vPtr;
}
}
void loop() {
waitForPause(200);
waitForData();
int count = readData(values, 500, 400);
bytesToString(prtbuf, values, count);
WebSerial.printf("\n%s\n", prtbuf);
// delay(3000);
}
... und die platformio.ini sieht so aus:
[common]
platform = espressif8266@^2.4.2
monitor_speed=115200
lib_deps =
git+https://github.com/volkszaehler/libsml
; EspSoftwareSerial
; MicroDebug
; ArduinoJson
ESPAsyncTCP
ESP Async WebServer
WebSerialLite
AsyncElegantOTA
lib_ldf_mode = deep+
[env:wemos_d1_mini_lite]
platform = ${common.platform}
board = d1_mini
framework = arduino
lib_deps = ${common.lib_deps}
monitor_speed = ${common.monitor_speed}
lib_ldf_mode = ${common.lib_ldf_mode}
Die Ausgabe des Programms in der Console sieht etwa so aus (Zeilenumbrüche sind angepasst):
[WebSerial] Connecting...
[WebSerial] Connected...
Using SoftwareSerial for serial communication
64 80 77 20 12 BC 64 76 20 FE FF 60 C8 80 00 00 86 00 FE FE
20 FE 00 FE 40 EE 60 FE FE 00 FE FE FE FE 00 0C 76 FE FE 00
2C 76 FE FE FE 02 00 00 86 00 FE 02 F0 20 90 CE 70 C4 28 00
C2 81 98 B0 60 00 F2 00 20 80 1C 0E 60 02 02 70 00
80 70 20 00 00 19 01 20 FE FF C8 81 70 76 86 00 FE FE 20 76
FE 00 FE 00 CE FE 40 FE 00 CE 60 76 FE FE 66 FE FE 00 0C FE
FE 00 0C FE FE 76 FE 12 76 00 00 86 00 FE 02 F0 20 90 EE C0
38 C4 00 C2 09 70 72 D8 30 00 F2 00 20 60 80 1C E6 60 40 60
E6 92
Using SoftwareSerial for serial communication
60 80 60 76 20 40 40 FE FF C8 86 00 FE FE 20 76 FE 00 FE 00
EE 60 FE 40 FE 00 CE FE FE 76 FE FE 00 2C 76 FE FE 00 86 FE
FE FE 18 00 87 00 FE 02 F0 20 90 EE 70 C4 00 C2 80 72 D8 70
F2 00 20 80 1C 42 C2 09 64 60 60 00 20
Using TasmotaSerial for serial communication
13 12 12 12 00 00 00 00 04 00 00 02 00 00 00 00 00 00 00 08
00 00 04 00 00 00 04 02 00 10 08 00 00 00 08 00 00 00 04 00
00 00 00 02 08 00 00 04 00 00 02 00 00 00 00 00 00 00 08 18
00 06 00 02 00 00 00 08 00 00 00 04 00 00 18 00 00 00 00 1E
1E 00 00 00 00 00 10 08 00 10 18 18 00 00 06 00 02 1E 00 00
00 00 00 00 08 00 00 06 18 00 00 00 00 00 1E 00 00 00 00 02
00 00 00 08 00 00 00 04 00 00 00 06 18 00 00 00 00 00 1E 00
00 00 00 00 00 00 10 00 00 10 00 00 00 00 00 00 0E 04 00 06
18 00 00 00 00 00 1E 00 00 00 10 00 00 10 00 00 00 00 00 00
0E 04 00 06 18 00 00 00 00 00 1E 00 00 00 10 00 00 10 00 00
00 00 00 00 00 00 00 06 18 00 00 00 00 00 1E 00 00 00 10 00
00 10 00 00 00 00 10 00 06 0C 00 06 18 00 00 00 00 00 1E 00
00 00 10 00 00 10 00 00 00 00 10 00 06 0C 00 06 18 00 00 00
00 00 1E 00 00 00 10 00 00 10 00 00 00 00 00 00 00 00 00 06
18 00 00 00 06 00 1E 00 00 00 08 00 00 00 00 00 00 00 00 06
18 00 00 06 00 00 1E 00 00 00 00 02 00 00 08 00 00 00 1E 02
06 00 00 00 0E 02 02 04 18 00 00 1C 00 02 08 18 00 06 00 00
00 10 10 08 18 10 18 00 02 00 02 00 12 00 00 02 02 00 06 00
00 06 1C 00 00 00 02 18 04 00 04 00 00 02 00 10 00 00 00 00
00 08 00 00 00 00
13 12 12 12 00 00 00 00 04 00 00 02 00 18 00 00 00 00 00 08
00 00 04 00 00 00 04 02 00 12 08 00 00 00 08 00 00 00 04 00
00 00 00 02 00 0C 00 04 00 00 02 00 00 00 00 00 00 00 08 18
00 06 00 02 00 00 00 08 00 00 00 04 00 00 18 00 00 00 00 1E
1E 00 00 00 00 00 10 08 02 10 18 18 00 00 06 00 02 1E 00 00
00 00 00 00 08 00 00 06 18 00 00 00 00 00 1E 00 00 00 00 02
00 00 00 08 00 00 00 04 00 00 00 06 18 00 00 00 00 00 1E 00
00 00 00 00 00 00 10 00 00 10 00 00 00 00 00 00 0E 10 00 06
18 00 00 00 00 00 1E 00 00 00 10 00 00 10 00 00 00 00 00 00
0E 10 00 06 18 00 00 00 00 00 1E 00 00 00 10 00 00 10 00 00
00 00 00 00 00 00 00 06 18 00 00 00 00 00 1E 00 00 00 10 00
00 10 00 00 00 00 10 00 06 0C 00 06 18 00 00 00 00 00 1E 00
00 00 10 00 00 10 00 00 00 00 10 00 06 0C 00 06 18 00 00 00
00 00 1E 00 00 00 10 00 00 10 00 00 00 00 00 00 00 00 00 06
18 00 00 00 06 00 1E 00 00 00 08 00 00 00 00 00 00 1E 00 06
18 00 00 06 00 00 1E 00 00 00 00 02 00 00 08 00 00 00 1E 02
06 00 00 00 0E 02 02 04 18 00 00 1C 00 02 08 18 00 06 00 00
00 10 10 08 18 10 18 00 02 00 02 00 12 00 00 02 02 00 06 00
00 06 1C 00 00 00 02 00 00 00 04 00 00 02 00 00 00 00 00 00
00 08 00 00 00 00
Hat jemand eine Idee, was hier falsch laufen könnte, und natürlich vor allem, wie man das fixen kann?
Wenn Infos fehlen, bitte nachfragen.