Hallo, ich bastel gerade etwas auf einem ESP32 und IOBroker mit Sensordaten. Aktuell läuft es da über MQTT, aber viele Wechselrichter und Smartmeter arbeiten ja mit Modbus TCP, wird ja auch nen Grund haben. Was ist den von der Performance her "effektiver", oder das schnellere Protokoll um kontinuierlich und häufig einen Datensatz zu verschicken. Also welche benötigt auf dem ESP32 weniger recoursen? MQTT war jetzt mit "boardmitteln" schnell am laufen, bei Modbus TCP habe ich nur das gefunden https://github.com/eModbus/eModbus... Grüße...
MQTT wurde für was ganz großes entwickelt. Das solltest du nutzen! https://en.wikipedia.org/wiki/MQTT
Frank schrieb: > Also welche > benötigt auf dem ESP32 weniger recoursen? Warum sollte das wichtig sein? Der ESP32 hat so unfassbar viel Reserven, da kannst du haufenweise Modbus-TCP und MQTT-Verbindungen gleichzeitig benutzen, und noch zusätzlich einen HTTP-Webserver mit Templating + Websocket laufen lassen, ohne den auch nur ansatzweise ins Schwitzen zu kriegen.
Was ist einfacher viele einzelne Modbus Clients abfragen oder die Clients melden selber an einen zentralen Punkt? Bleib bei MQTT denn das ist dafür ausgelegt. Die paar modbus Clients die z.B. deine Wechselrichter sind kannst du mit einer Modbus - MQTT bridge mit nem ESP erledigen. Tasmota kann das auch.
Es ging mir nicht um "einfacher" sondern um die Performance... eigentlich auch unabhängig vom ESP32. Nehmen wir an ich will ~50 Datensätze oder mehr übertragen wie beim Wechselrichter. Ist dann Modbus TCP schneller, oder MQTT. Hängt ja vom Protokoll ab und wie in meinem µC die Daten aufarbeiten werden müssen. Bei MQTT ist bei mir so bei ~250ms Sendeintervall "ende" wobei ich das auch mal mit mehreren Werten testen muss... dann fängt der Client sich wohl an zu verschlucken. Liegt sicher auch an WLan Latenzen und so... Die Werte sind die Millisekunden zwischen zwei Nachrichten...
1 | #include <WiFi.h> |
2 | #include <PubSubClient.h> |
3 | |
4 | // WiFi
|
5 | const char *ssid = ""; // Enter your WiFi name |
6 | const char *password = ""; // Enter WiFi password |
7 | |
8 | // MQTT Broker
|
9 | const char *mqtt_broker = "192.168.178.12"; |
10 | const char *topic = "esp32/test"; |
11 | const int mqtt_port = 1883; |
12 | |
13 | WiFiClient espClient; |
14 | PubSubClient client(espClient); |
15 | unsigned long last_msg; |
16 | |
17 | void setup() { |
18 | // Set software serial baud to 115200;
|
19 | Serial.begin(115200); |
20 | // connecting to a WiFi network
|
21 | WiFi.begin(ssid, password); |
22 | while (WiFi.status() != WL_CONNECTED) { |
23 | delay(500); |
24 | Serial.println("Connecting to WiFi.."); |
25 | }
|
26 | Serial.println("Connected to the WiFi network"); |
27 | //connecting to a mqtt broker
|
28 | client.setServer(mqtt_broker, mqtt_port); |
29 | client.setCallback(callback); |
30 | |
31 | while (!client.connected()) |
32 | {
|
33 | Serial.print("Attempting MQTT connection..."); |
34 | // Attempt to connect
|
35 | if (client.connect("DummyESP32")) |
36 | {
|
37 | Serial.println("connected"); |
38 | }
|
39 | else
|
40 | {
|
41 | Serial.print("failed, rc="); |
42 | Serial.print(client.state()); |
43 | Serial.println(" try again in 5 seconds"); |
44 | // Wait 5 seconds before retrying
|
45 | delay(5000); |
46 | }
|
47 | }
|
48 | |
49 | // publish and subscribe
|
50 | client.subscribe(topic); |
51 | }
|
52 | |
53 | void callback(char *topic, byte *message, unsigned int length) { |
54 | |
55 | String messageTemp; |
56 | |
57 | for (int i = 0; i < length; i++) { |
58 | messageTemp += (char)message[i]; |
59 | }
|
60 | |
61 | Serial.println( (millis() - last_msg) ); |
62 | last_msg = millis(); |
63 | |
64 | }
|
65 | |
66 | void loop() { |
67 | client.loop(); |
68 | }
|
Ja ehrlich... So zumindest in vielen, oder allen Tutorials die auf der Pubsub lib beruhen? Aber ich stecke da nicht so tief drin, als das ich eine entsprechende lib optimieren könnte. Man freut sich sicher über andere Ansätze.
Frank schrieb: > Smartmeter > arbeiten ja mit Modbus TCP, wird ja auch nen Grund haben. Der Grund ist historisch und der das mehrere Geräte an einem Bus hängen können. Aber bei Modbus sendest du eine Anfrage auf den Bus und musst hoffen der Client hat mitgehört und dann Antwortet er hoffentlich, in der Zeit musst du mithorchen und hoffen er Antwortet in dem gewissen Zeitrahmen. In dieser Zeit kannst du nichts anderes machen als warten auf Antwort. Ließ dir mal die Modbus spec durch Nimm MQTT. Da feuerst du die kleine Message an den Server so schnell dein ESP den Sensor auswerten kann und dein Netzwerk dies zulässt. Was aber oft keinen Sinn macht weil sich der Wert meistens nicht so schnell ändert. Dich interessiert ja nur wenn sich der Wert ändert.
Frank schrieb: > Was ist den > von der Performance her "effektiver" Das hängt in hohem Maße von der Anwendung ab. Bei MQTT wartet die Zentrale (vulgo:Host) und die vielen kleinen Arbeitsbienen (vulgo:Slaves) schicken von sich aus etwas, wenn sich was ändert. Bei Modbus ist es umgekehrt. Die Zentrale muß ständig Meßergebnisse abfragen, um Änderungen zu erkennen. Daher ist MQTT im Vorteil, wenn sich nur selten etwas ändert. Modbus hat die Nase vorn, wenn sich viel ändert, da es schlanker ist. Just my 2 cents
Frank schrieb: > Ja ehrlich... So zumindest in vielen, oder allen Tutorials die auf der > Pubsub lib beruhen? Da ist dann ein wenig Grundlagenwissen über die Programmiersprache und die Libraries von Vorteil. Die Original-Beispiele machen das übrigens nicht so. Die haben zwar auch diese Schleife über "message", schieben das aber Buchstabenweise über die Serielle Schnittstelle raus, d.H. da wird kein String zusammengesetzt. Irgendjemand hat dann wohl mal das Serial.print(char) durch den String-append ersetzt, sich nichts dabei gedacht, und das wurde dann x-mal im Internet rumkopiert. > Aber ich stecke da nicht so tief drin, als das ich > eine entsprechende lib optimieren könnte. Man freut sich sicher über > andere Ansätze. Das Problem ist, dass der String bei jedem Anhängen eines Buchstaben verlängert wird, und dabei potentiell neuen Speicher anfordert, und dabei erstmal alles umkopieren muss. Ergibt damit quadratische Komplexität. Am PC (C++, std::string) umgeht man das indem man einfach verschwenderisch mit dem Speicher umgeht, und die reservierte Speichergröße jedesmal verdoppelt. Ergibt dann "amortised constant time" für das append. Am µC ist das nicht so implementiert, da ist der Speicher knapp. Verbesserung: Vor der for-Schleife einmal mit messageTemp.reserve(length) den nötigen Speicherplatz vorab reservieren. Oder statt der Schleife einfach mit messageTemp.concat(message, length) die gesamte Payload auf einmal in den String schieben.
Danke für den Input! Ich schaue mir das mal an...
1 | void callback(char *topic, byte *message, unsigned int length) { |
2 | |
3 | String messageTemp = String((char*)message, length); |
4 | Serial.println(messageTemp); |
5 | |
6 | }
|
wäre das auch eine Variante? Ich denke der Artikel beschreibt die Problematik? https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.