helgeerbe / OpenDTU-OnBattery

Software for ESP32 to talk to Hoymiles Inverters and Victrons MPPT battery chargers (Ve.Direct)
GNU General Public License v2.0
253 stars 56 forks source link

Add support for additional UART interfaces via I2C-UART converter #1039

Open joe-ben-75 opened 3 weeks ago

joe-ben-75 commented 3 weeks ago

Is your feature request related to a problem? Please describe.

ESP32 provides only very limited number of HW serial interfaces. OpenDTU-on-Battery can connect to many devices using UART (all Victron equipment, JK-BMS, SML/SDM). A setup of more than 1 MPPT, a Shunt, a JK-BMS and a SML energy-meter can not be configured due to missing UART RX GPIOs on ESP32x. Although i.e. Shunt and JK-BMS does not seem useful it is a good option to use OpenDTU-on-Battery as a central data monitoring device.

Describe the solution you'd like

There is a I2C-UART converter board available from DFRobot (-> DFR0627) that provides two HW UART interfaces (incl. FIFO buffers) connected via I2C to the microcontroller (ESP32). The provided I2C functions to use the UART interfaces are very similar to the "original" serial functions. The board allows I2C address definition via two dip switches so that max four boards could be connected to the microcontrollers I2C bus adding eight (!) additional HW UART interfaces.

Describe alternatives you've considered

The limited number of HW UART (serial) interfaces could be extended by using SW serial interface, but this kind of "emulated" interface implies new limitations and problems. I have no other idea how to add more "real" UART interfaces to ESP.

Additional context

More UART interfaces would allow OpenDTU-on-Battery in the future to enhance its functionality further. From my point of view the power data from a SML/SDM device via UART used for DPL is more reliable than a MQTT connected EM3pro. Also the idea of additional power-meters for the 24V Hoymiles setup would benefit from additional UARTs.

schlimmchen commented 2 weeks ago

Nice to learn that somebody else has similar ideas.

There are problems, which lead me to discard this idea a couple of months ago:

  1. Users need to buy additional hardware. This is not only a money issue for the users, but a documentation issue for us, and support issue for us, as some people will not get it to work properly (without help).
  2. Such chips which are connected through a parallel bus need prohibitively many GPIOs.
  3. Chips using I2C are prohibitively expensive. I am very surprised that the board you found is comparatively cheap. Maybe that is because I looked into quad UART ICs...
  4. Drivers. Are there drivers for these chips for Arduino on ESP32? How about your specific example? And if there are, can we use them without too much hassle? If we need to rewrite all software components currently using hardware UARTs to be able to use the new type of serial interface, that would be a bummer. Especially if we need to make this dynamic, i.e., components need to choose which type of UART to use at runtime. Also, we must keep compatibility with existing setups, which possibly is a headache.

I believe that SoftwareSerial is the way to go. Here is why:

The JK BMS interface is the only interface which actually needs a hardware UART, as 115200 Baud is too fast and the amount of data transmitted is too much. Let's reserve one hardware UART for this. This also covers the SmartShunt, as only one battery interface at a time is supported.

Next, let's look at the SML power meter interface you mentioned. This never used a hardware serial as far as I know. It certainly does not for a year now. It is already using SoftwareSerial.

The SDM power meter interface uses a 9600 Baud (or less) serial interface. This does not warrant the use of a hardware serial. In fact, in my powermeter refactoring branch of code, I switched the SDM power meter to SoftwareSerial just yesterday, which now works hassle-free (tested against actual hardware (SDM72)).

Left are the Victron charge controllers. They communicate at 19200 Baud. I know that we can use SoftwareSerial to parse their data from earlier experiments. There is one catch: The interface must be polled asynchronously, i.e., using a separate FreeRTOS task. Polling the software based interface as part of the main loop does not work, as the ISR buffers have to be too big, then. Adding such a task is not a problem. I am also very confident, that sending data using SoftwareSerial will be perfectly possible as well.

Given that we are pushing users to upgrade their ESP32 to an ESP32-S3, most users should have three hardware UARTs available (use the native USB of the ESP32-S3 for the serial console). At least those who want to connect "so many" serial peripherals can be asked to use an ESP32-S3 with USB.

To sum up: The microcontroller offers three hardware UARTs, and all of them should be available to connect peripherals. Only one peripheral actually needs a hardware UART. Even if a JK BMS (or SmartShunt) is in use, one can connect two more Victron MPPT. If you really want to add more, SoftwareSerial will work for you as well.

Do you agree that adding support for such additional hardware is not worth the effort?

joe-ben-75 commented 2 weeks ago

Danke für die umfangreiche Antwort ! Ich mach es mir mal einfach und schreib auf deutsch weiter (ich hatte den Request nur auf Englisch verfasst, um eine größere Reichweite für die Idee zu bekommen ...).

Im Prinzip gebe ich Dir Recht : die Kernfrage ist, ob der Nutzen bzw. die Vorteile von der Implementierung von "I2C-UART" den Aufwand dafür rechtfertigen. Allerdings kann ich den Aufwand nicht abschätzen, weil ich mich mit dem Code und der Programmstruktur von OpenDTU-on-Battery noch nicht auseinander gesetzt habe. Ich programmiere zwar auch diverse µController für allerlei Zwecke, aber längst nicht auf dem Level wie Euer Projekt.

Deine ersten 3 Argumente sehe ich nicht so "verhindernd". Meine vorgeschlagene HW ist nicht wirklich ein Kostenfaktor, wenn wir über Projekte reden, in denen erheblich mehr Geld in PV-Module, Solar-Ladegräte, Wechselrichter und Akkus investiert wird. Da sind die gesamten Kosten für die OpenDTU-on-Batterie HW ein recht geringer Posten. Außerdem ist sowieso schon zusätzliche HW notwendig (Radiomodul, Signal-Koppler, CAN-/RS485-Adapter, Displays etc). Das I2C-UART Modul ist nicht nur preiswert, sondern auch verhältnismäßig einfach zu handhaben - wer ein I2C Display verwendet, kann auch diese Module verwenden. Allerdings habe ich selbst damit noch keine Erfahrung gesammelt. Ich habe mir nur die DFRobot Wiki-Page dazu angeschaut und daraus gemutmaßt, dass die Handhabung mit der bereitgestellten Libary für Arduino und ESP32 quasi analog zu den Serial-Functions ist (siehe github DFRobot/DFRobot_IICSerial). Daher war ach meine Hoffnung, dass der Implementierungsaufwand "verhältnismäßig" ist (.beginn , .available , .read , .flush). Damit wäre ich bei Deinem 4. Argument. Wirf mal einen Blick in diese Libary, dann kannst Du am besten beurteilen, wie leicht oder schwer das wäre.

In meinem Setup habe ich einen Victron MPPT, der in mittlerer Zukunft vlt. um einen erweitert wird. Der (die) MPPT(s) feeden in ein Akku mit JK-BMS (die neue Inverter-Version), wobei auch ein SmartShunt zum Einsatz kommt. Das alte JK-BMS hat einen eher schlechten Ah-Integrator und eine fehlende Funktion zum 100% Reset (aber ich finde den Ballancer großartig). Daraus ergibt sich eine inakzeptable Drift nach verhältnismäßig kurzer Zeit. Daher der Smartshunt, der auch über 4 Wochen bei <10% Drift bleibt und zumindest erkennen kann, wenn wieder 100% anliegen sollen. Mal sehen, wie das neue Inverter JK-BMS funktioniert, dass hat ja nun auch einen 100% Reset. Aus dem Akku bedient sich ein HMT-2000. Der soll auf Nulleinspeisung laufen. Dazu hatte ich zunächst einen EM3 pro am Hauptzähler im Sinn, doch mittlerweile traue ich der Übertragung via HTTP nicht so recht (Zuverlässigkeit, Update-Rate). Daher will ich den Hauptzähler direkt über SML auslesen und verwenden. Das halte ich für zuverlässig und hochfrequent (und preiswert ist es obendrein). In diesem Setup sind mind. 3 UARTs nötig und dann ist kein Ausbau mehr möglich. Das war meine Motivation ...

Ich wusste nicht, dass SW-Serial bereits für einige Geräte möglich bzw. aktiv ist (z.B. SML). Das kommt in der Doku nicht rüber (oder habe ich es übersehen). Ich dachte, dass für alle UART-Endgeräte entsprechende UART Rx-Pins am ESP32 gewählt werden müssen.

Wenn Du der Meinung bist, dass der Aufwand für die Implementierung des I2C-UART Converters mit der bereitgestellten Libary zu aufwendig ist, verstehe ich das und komme auch mit dem ESP32-S3 zurecht. Danke nochmal für Deine Mühe !

Ich habe für ein Projekt mit 6 UART Interfaces übrigens eine Teensy 4.1 benutzt - der bietet 8 Ports und ist rasend schnell. Aber er hat kein Wifi onboard, dafür Ethernet (was ich eher bevorzuge) und ist deutlich teurer als ein ESP32.