Skip to content
skippermeister edited this page Aug 17, 2024 · 27 revisions

This fork differs from the OpenDTU-onBattery from https://github.com/helgeerbe/OpenDTU-OnBattery in the following points:

My concept works a little differently. I work with at least two Hoymiles inverters. One for the night and one for the day. The nighttime inverter is connected to the battery, the daytime inverter has no direct connection to the battery. I modified and added a few queries to the PowerLimiter (DPL) module. The PowerLimiter only controls the inverter connected to the battery if

  1. the inverter is accessible
  2. the inverter is enabled for polling and command (I differentiate between day and night when configuring the inverter)
  3. the battery provider was initialized correctly and the battery was recognized
  4. the battery has enough capacity.
  5. the measured temperature of the battery is within the permitted range
  6. daybreak is not announced (2 minutes before sunrise, a status which is displayed in my supplement for approx. 2 minutes, see module SunPosition.cpp)
  7. and the Meanwell charger is not charging the battery.

Point 6 means that the inverter will definitely be shut down 2 minutes before sunrise.

Point 7 means that if the Meanwell charger charges the battery during the day, the inverter is shut down. This is correct for me because the inverter on the battery is only activated at night and the Meanwell charger does not charge. Even if the charger is manually switched on at night via the WebGUI in LiveView, the inverter connected to the battery is immediately shut down. It makes no sense to generate alternating current from the battery and charge the battery using alternating current at the same time. The inverter for night operation only starts again at sunset.

If you only have one inverter for day and night operation, you should set the parameters for your environment in the platformio.ini or platformio_override.ini as follows

-DPRE_CHARGE_PIN=-1 ; MosFET transistor
-DFULL_POWER_PIN=-1 ; MosFET transistor

or set the parameters

"batteryConnectedInverter":{
"pre_charge":-1,
"full_power":-1
},
in your pin_mapping.json file. This deactivates my changes in the DPL and the DPL behaves exactly as in the original openDTU-onBattery. These two pins control MosFETs which in my setup connect the DC lines from the battery to the inverter and switch them off in the morning. If these parameters are set to -1, then the manageBatteryDCpowerSwitch() functions and all other changes I implemented in the PowerLimiter.cpp module are ignored.

The note in the PowerLimiter regarding "A charger should be activated" must be observed because in winter the solar power will not be sufficient to charge the battery. The battery will have to be recharged within 3 months and the Victron cannot do that with the solar panels from around November to February. The sun is then simply too low. I use the Meanwell NPB-450-48 charger, which communicates via CAN bus (the internal CAN bus of the ESP32) (see module MeanWell_can.cpp).

In my setup, the ZeroExport PI controller is intended for the inverter, which produces electricity during the day (max 2 are controlled). You define the corresponding inverters in the WebGUI. If you have more than one inverter, all inverters will also be displayed there for selection. If you only have one inverter for day and night operation, then the Zero Export PI controller must not be activated. In this case, the regulation must take place via the PowerLimiter.

A note for the Meanwell power supply. Make sure that you get a power supply with a newer software version. The manual then has at least version 7. The newer version supports the EEPROM write disable function. Ask your supplier. Unfortunately, I still have an older software version that does not contain this function.

1. Pylontech and Pytes Battery Provider

1a. Pylontech Batterie connected via RS485 using two different RS485 Modules

  • Type1: a module with a simple MAX3485 or SP3485 Chip, needs RX, TX and RTS (/RE DE)

image

  • Type2: a TTL to RS485 module with an automatic self driven /RE DE logic. Needs only RX and TX lines

image

The implementation supports more than one Pylontech battery connected via RS485. The batteries must be linked to each other via the link ports and the master battery is connected to the Type 1 or Type 2 RS485 adapter via the RS485 port. The following constellations have been successfully tested so far:

  • 1x US2000C
  • 1x US3000C
  • 2x US5000

1b. Pylontech Battery connected via CAN0 Bus or MCP2515 CAN Bus or an I2C CAN Bus Controller Controller

Implemented but not fully tested. If the CAN0 bus is used for communication with a battery, then the charger charger (Meanwell or HUAWEI) cannot be used on the CAN0 bus at the same time. The charger would then have to be connected to the MCP2515 CAN bus controller or I2C CAN Bus Controller. This is implemented in the MeanWell_can.cpp and Huawei_can.cpp module, but not fully tested. The communication of a CAN Bus connected batteries via MCP2515 CAN bus controller and I2C CAN Bus Controller has been implemented but not fully tested. This is implemented in the module BatteryCanReceiver.cpp. If the battery is not to be connected via RS485, then the variant via MCP2515 is recommended for the Pylontech battery. However, using my OpenDTU-onBattery fork for a Pylontech battery with CAN0 or MCP2515 CAN bus controller makes no sense.

1c. Pytes Battery connected via CAN0 or MCP2515 CAN Bus Controller

Implemented but not yet tested. The communication of a Pytes battery via CAN0 bus, MCP2515 CAN bus controller and I2C CAN Bus Controller has been implemented but not yet fully tested. If the CAN0 bus is used for communication with the Pytes battery, then the charger cannot be used on the CAN0 bus at the same time. The charger would then have to be connected to the MCP2515 CAN bus controller or I2C CAN Bus Controller. This is implemented in the MeanWell_can.cpp and Huawei_can.cpp module (can be activated via macros USE_CHARGER_MEANWELL or USE_CHARGER_HAWEI. Don't activate both macros together).

2. Daly BMS module integrated as an additional battery provider.

Connection options:

  • RS232 (RX and TX)
  • Type 1 RS485 - a module with a simple MAX3485 or SP3485 Chip, needs RX, TX and RTS (/RE DE)
  • Type 2 RS485 - a TTL to RS485 module with an automatic selfdriven /RE DE logic. Needs only RX and TX lines

3. Charger from Meanwell instead of Huawei. Supported are:

  • Meanwell NPB-450-24 (not tested)
  • Meanwell NPB-750-24 (not tested)
  • Meanwell NPB-1200-24 (not tested)
  • Meanwell NPB-1700-24 (not tested)
  • Meanwell NPB-450-48 (tested)
  • Meanwell NPB-750-48 (not tested)
  • Meanwell NPB-1200-48 (tested)
  • Meanwell NPB-1700-48 (not tested)

When initializing the MeanWell module, an attempt is made to set Bid 10 (EEP_OFF) of the Meanwell charger in the SYSTEM_CONFIG register. This prevents the EEPROM from being damaged early by the periodic writing of the current values. Unfortunately this is not yet implemented on my charger.

4. Automatic control of the DC connection between the Pylontech battery and a Hoymiles inverter

for power generation at night. Contains a logic for controlling 2 MosFET transistors via 2 GPIO pins with pre-charge function for pre-charging the inverter's input capacitors (soft start).

If the parameters PRE_CHARGE_PIN and FULL_POWER_PIN are in the platformio.ini or platformio_override.ini or in the pin_mapping.json

"batteryConnectedInverter":{
"pre_charge":-1,
"full_power":-1
},

be set to -1, then the handling of the MosFETs is ignored and the DPL works just like in the original OpenDTU-onBattery

See also here https://github.com/skippermeister/OpenDTU-OnBattery/discussions/7#discussioncomment-10107072

5. Modules configurable via macros

in the platformio.ini platformio-override.ini (compilation required)

6. Zero Export to Grid PI controller

for up to 2 Hoymiles inverters per day.

If you only have one inverter for day and night operation, then this controller must not be activated, otherwise it will compete with the DPL.

7. Automatic charging of the Pylontech battery with the Meanwell charger

using excess solar power. Integrated security features.

  • Temperature monitoring
  • SOC monitoring
  • Over and under voltage monitoring.
  • Monitoring request of charge from the battery (Pylontech's Immediately Charge Request below 5%-9% and 9%-13%)
  • Monitoring long-term discharge (>30 no charge)

If the MeanWell charger is switched off in the LiveView of the WebGUI, the automatic charging system monitors the battery. If the battery requests a FullChargeRequest or ImmediatelyChargeRequest, the Meanwell charger charges the battery during the day to

  • up to 100% for FullChargeRequest
  • and to the value of Battery.Stop_Charging_BatterySoC_Threshold for ImmediatellyChargeRequest.

The Daly BMS is integrated in the same manner but not fully tested.

8. LED_Strip Module

for LED strips with 2 pieces of WS2812 LEDs as status display for network and inverter.

If the Led_Single or Led_Strip module is deactivated in platformio_override.ini, the Led tab is hidden in the WebGUI under Settings->Hardware

9. Display_Graphic module extension

ePaper display and preparation for a software SPI (not tested).

If the Display_Graphic module is deactivated in platformio.ini or platformio_override.ini, the Display tab is hidden in the WebGUI under Settings->Hardware

10. ModbusDTU module

to simulate either a Fronius Smart Meter TS 65A-3 or an original DTU via ModusIP (both not yet finally tested)

11. PowerMeter module runs in an own task

The PowerMeter module is now asynchron to the main Scheduler loop and implemented as in original OpenDTU-onBattery. The PowerMeter module no longer blocks the program flow. It is tested with Shelly3EM via HTTP and with a SDM630 emulator (self-developed with esphome) via RS485.

A SoftwareSerial Port is used to connect an Eastron SDMxxx. However, in platformio.ini or platformio_override.ini you can switch to hardware serial port (USE_POWERMETER_HWSERIAL, but not recommended) I changed the library EspSoftwareSerial (from Version 8.0.2) and it is now part of the included libraries. My tests have shown that GPIO 0 can be used as a TX port on the ESP32. To do this, I adapted the isValidPin function in SofwareSerial.h. Here too I support the two RS485 adapters (Type 1 and Type 2). The handling of transmitter activation for Type 1 is handled by the EspSoftwareSerial library or uart in the case of HardwareSerial.

The SMA_HM module can be activated via a macro switch in platformio_override.ini (USE_SMA_HM) and is deactivated by default. The SMA_HM module is still running in the main loop in the scheduler. Changes still need to be made and tests carried out here.

12. Add an additional parameter for Sunrise and Sunset

Now you can select between the 5 options for sunrise and sunset

  • Standard dawn (90.8°)
  • Nautical dawn (102°)
  • Civil dawn (96°)
  • Astronomical dawn (108°)
  • Special angle for sun rise (60..120°) and sun set (60..120°)

13. Modification of CMT2300A GPIOs

On my module, GPIO1 and GPIO2 were routed to the outside of the 8-pin header. This caused my CMT module to flood the CPU with interrupts after a few seconds. The solution was to set GPIO2 and GPIO3 to -1. Be sure to note my new pin mapping, e.g. "ESP32_S3_USB_CMT_HUAWEI.json". A few changes have been made, as the GPIOs of the CMT module can now be mapped internally in the CMT chip (e.g. Interrupt1 on GPIO2 and Interrupt2 on GPIO1). The CMT module uses the interrupts to report to the ESP CPU whether something has been received or whether a packet has been sent.

The mapping of the GPIO pins is implemented using the two additional parameters chip_int1gpio and chip_int2gpio as in the following example. If these parameters are set to -1 or omitted, the CMT driver assumes that Int1 is routed to GPIO2 and Int2 to GPIO3 (default). The routing example is for my CMT2300A module and routes the actual GPIO1 pin of the chip module to the designated GPIO3 ports of the 8-pin header. To put it another way. My module has the chip pin GPIO1 and GPIO2 routed to the outside of the 8-pin header.

"cmt": {
"clk": 10,
"cs": 9,
"fcs": 11,
"sdio": 12,
"gpio2": 14,
"gpio3": 13,
"chip_int1gpio": 2,
"chip_int2gpio": 1
},

This is what my module looks like:

CMT2300A Modul Solarzero white

14. Extended CAN communications via different interfaces

For the Charger:

  • CAN0 (ESP32 internal CAN bus)
  • MCP2515
  • I2C0 with an I2C CAN Bus Controller (from SeeedStudio)
  • I2C1 with an I2C CAN Bus Controller (from SeeedStudio)

For the battery:

  • RS485 via typ 1 and typ 2 adapter (see above)
  • RS232 (including wakeup signal for Daly BMS)
  • CAN0 (ESP32 internal CAN bus)
  • MCP2515
  • I2C0 with an I2C CAN Bus Controller (from SeeedStudio)
  • I2C1 with an I2C CAN Bus Controller (from SeeedStudio)

This is what the Seeed Studio I2C CAN Bus Controller my module looks like:

SeeedStudio I2C CAN Bus Controller

You can see how the interfaces are distinguished in the pin mapping file “ESP32_S3_USB_CMT_HUAWEI.json”. A new library “I2C_CAN_Arduino” has been added for the SeeedStudio I2C CAN bus module. I adapted this to the ESP32 CPU family. The SeeedStudio CAN Bus Controller is an MCP2515 with an ATMEGA168 CPU. So it provides CAN bus communication via I2C. This is intended to ensure that NRF24+CMT+Charger is possible via CAN and battery via CAN, i.e. 2x SPI plus 2x CAN bus.

For the charger (Meanwell or Huawei) via an MCP2515, the section in the pinmapping file looks like this:

"charger": {
"mcp2515_irq": 4,
"mcp2515_clk": 5,
"mcp2515_mosi": 6, "mcp2515_miso": 7,
"mcp2515_cs": 15,
"power": 16
},

and via the SeeedStudio module connected to the I2C0 bus it looks like this:

"charger": {
"i2c0_scl": 18,
"i2c0_sda": 17
},

and via the internal CAN0 bus it looks like this:

"charger": {
"can0_rx": 3,
"can0_tx": 8
},

For the battery it is as follows, here using CAN0 as an example:

"battery": {
"can0_rx": 45,
"can0_tx": 47
},

The pin numbers are exemplary and must be adapted to your own requirements.

15. Simultaneous use of an MCP2515 and CMT2300A

The SPIPortManager supports the dynamic assignment of the existing SPI ports. ESP32 and ESP32-S2 as well as ESp32-S3 have 2 freely available SPI ports. The SPI port is assigned according to the series of initialized SPI devices. This means that the CMT2300A module can be used alongside the MCP2515 for the Huwei or Meanwell power supply (Huawei is not yet tested).

16. Configuring and compiling your own environment

In order to adapt the binary code to your own board and requirements as well as to minimize the required flash and RAM resources, individual adjustments can be made via macros in the platformio.ini and platoformio_override.ini files.

The driver modules for the charger and battery can be activated as follows: To select the used charger module

-DUSE_CHARGER_MEANWELL
or

-DUSE_CHARGER_HUAWEI
and for the the CAN Bus Controller

-DUSE_CHARGER_CAN0
-DUSE_CHARGER_MCP2515
-DUSE_CHARGER_I2C

To select the used battery module

-DUSE_PYLONTECH_CAN_RECEIVER
or

-DUSE_PYLONTECH_RS485_RECEIVER
or

-DUSE_PYTES_CAN_RECEIVER
or -DUSE_JKBMS_CONTROLLER
or

-DUSE_DALYBMS_CONTROLLER
or

-DUSE_VICTRON_SMART_SHUNT
or

-DUSE_MQTT_BATTERY

and if selected a CAN Bus connected battery select the CAN Bus Controller as follows:

-DUSE_BATTERY_CAN0
-DUSE_BATTERY_MCP2515
-DUSE_BATTERY_I2C

A recompilation is then required