dxoverdy / Alpha2MQTT

A smart home interface for AlphaESS solar and battery inverters.
GNU General Public License v3.0
41 stars 6 forks source link

How to enable Modbus on 2022 SMILE5 #14

Closed dc42 closed 9 months ago

dc42 commented 1 year ago

Hi, I've built one of these (thanks for the project!) but I'm having problems with Modbus communication. My SMILE5 has 4.8V between pins 4 and 5 as expected when the Alpha2MQTT isn't connected. Using a scope I can see that Alpha2MQTT is transmitting at 9600b on those pins, but there is no response received from the SMILE5. So I suspect that Modbus is disabled. However, I can't find anywhere to enable it in the Settings menu of the Smile5. After selecting Settings and entering the password, I get only two options: System and Restart (there is no Function entry). System just lets me select Date/Time, Ethernet, New Password, and Exit. Can anyone tell me how to enable Modbus? The SMILE5 component versions reported are:

Inverter V02.05 Charger V01.18 EMS V1.02.50 BMS V11.91

Thanks!

Spookster commented 1 year ago

How do you get the reported versions, and Ill compare with mine

Experiences vary with accessing MODBUS it seems https://www.facebook.com/groups/629803784169356/search/?q=modbus

Spookster commented 1 year ago

Inverter V1.48 Charger V1.48 EMS V1.02.68 BMS V1.04

Im in NZ, so may explain the different firmware. Youve checked the system for updates? Mine didnt flag as being available until I checked and I got no response until the update was performed

dxoverdy commented 1 year ago

A lot of Smile 5s are struggling. A chap I’ve come to know in the UK had his Smile 5 unit swapped out because of it and it worked first time. If I recall he said the hardware was different.

I also read the Smile 5 is a bit more picky when it comes to RS485 timings.

Can I ask, given your knowledge on the MAX3485 on the other thread, what you actually built?

I am wondering if a MAX3485 chip with the flow control pin and a 3.3V/5V logic shifter could be more suitable?

dc42 commented 1 year ago

Thanks to all of you who responded so quickly. I should have mentioned that I am in the UK.

What I put together is a ESP32 Devkit V1, a board sold as a MAX3485 board (but that actually uses a MAX13847E) that looks identical to the one in the pictures in the README file, and a OLED display purchased in a pack of 5 from Amazon. I amended the code to use hardware serial on the ESP32 instead of software serial. I also fixed a bunch of compiler warnings, most of which were benign but a few of which could lead to buffer overflows, for example if unexpected data was received over Modbus (I have a policy of never trusting data from an external source). The code is in my fork of Alpha2MQTT at https://github.com/dc42/Alpha2MQTT/tree/master; however I don't advise anyone to use it until I have RS485 reception working, in case the switch to hardware serial needs some additional changes. I power the setup from the USB port of a 13A socket connected to the UPS output of the SMILE5.

Currently the display works and the ESP connects to WiFi and MQTT, but doesn't connect to the SMILE5. I used an oscilloscope to look at the Modbus signals, to confirm that the adapter board was transmitting at 9600b (after I corrected a TXD/RXD wire swap) and that the SMILE5 wasn't returning any data. I have another interface board on order in case my swapping TXD/RXD originally broke something.

However, having read the comments on Facebook I am wondering whether AlphaESS has deliberately disabled the Modbus setting, perhaps to prevent users from commanding discharge to the grid. I hadn't previously notice that "self consumption only" was part of the warranty condition. Perhaps that bit was added after my inverter was installed; I will locate my user manual and check.

As to the best choice of RS485 interface board, there are a few considerations:

Solutions to the Modbus interface that don't run the interface chip out of spec include:

  1. Red board powered from 5V, with 2 resistors (potential divider) to reduce the signal level to the receive input of the ESP from 5V to 3.3V. Level shifting the other way isn't needed because the MAX13847E only needs 2.0V signal input.
  2. As above but MAX485 board (again, only the data output needs level shifting down to 3.3V).
  3. (simplest) True MAX3485 board (see https://github.com/dxoverdy/Alpha2MQTT/issues/13) powered from 3.3V.
Spookster commented 1 year ago

When I was trying to sort mine out, Daniel suggested Arduino . tools > serial monitor to see what was going on. I assume you have, or does that give any debug clues?

dxoverdy commented 1 year ago

I’ve bought an esp32, a couple of max485-ttl modules (the blue 5v ones), a couple of the genuine max3485 boards (genuine 3.3v with the EN pin) and some 3.3v-5v logic shifters.

I’ll get the code compiling and working with my existing red TTL board with the curious MAX13847E, then I’ll try all the other combinations and post findings.

I think that is probably the only sensible starting point.

Alpha have explicitly said they don’t disable modbus, someone I know went to one of their shows and asked the techies and they reported yes they removed the option but it was simply to make it “always on”. All their other systems have it on by default, I suppose it made no sense to retain a pointless option on one system.

As I said, I also read somewhere that a specific revision of Smile 5 hardware is notoriously finicky about rs485 timings and I think it is prudent to take the auto-switching of TX/RX out of the equation too.

My gut feeling historically has been when they removed the modbus enable option, some systems if disabled are possibly remaining disabled but getting their tech to acknowledge is difficult. I tend to message the German team as they are on it but then I struggle behind Google Translate.

UK too by the way :)

dc42 commented 1 year ago

@dxoverdy I published the code I used for the ESP32 at https://github.com/dc42/Alpha2MQTT/tree/master/Alpha2MQTT. The changes I made are summarised at https://github.com/dc42/Alpha2MQTT/tree/master/Alpha2MQTT. It's possible that with the change to use a hardware serial port, it may be necessary to flush the receive buffer immediately after transmitting. I'll check that if/when I start getting responses from the SMILE5.

I've also ordered a genuine MAX3485 board, and I have a MAX485 chip already; so I can try using those to take the auto switching out of the equation as you suggested.

@Spookster I don't have a laptop and my PC is too far from the inverter, so I haven't used serial monitor since I tested what I can without connecting to the inverter. However, my oscilloscope shows that the only transmissions on the RS485 bus are the ones from the Alpha2MQTT. The bit timing was close to 100us so about right for 9600 baud, but in the light of what Daniel has said about some SMILEW5 inverters being fussy about timings, I'll measure it more accurately next time.

dc42 commented 11 months ago

I tried connecting a MAX485 board powered from 5V, with its RO output connected to the ESP32 RX2 input via a couple of resistors to reduce the voltage to 3.3V. I found I had to modify the Alpha2MQTT code to keep the transmit control pin high until the transmission has finished, due to my use of a hardware serial port. But even with that fixed, the result was the same as before: I can see the data transmitted by Alpha2MQTT on the Modbus, but there is no response from the inverter. I modified the code to request the serial number registers on each loop iteration until it read them successfully, then used an oscilloscope to read the data being sent. It reads 55 03 07 43 00 08 B9 78 which looks correct to me including the CRC.

I tried holding the data output high for a couple of milliseconds before starting transmission, but that didn't help. Neither did adding a ground wire between the Alpha2MQTT and the inverter casing (Modbus components are supposed to have a common ground), and neither did using a different 5V USB power supply.

So I think either Modbus is still disabled on my SMILE5 despite the absence of a means to enable it in the Setup menu, or there is something wrong with the Modbus interface on my SMILE5.

dxoverdy commented 11 months ago

Comprehensive. I’m still waiting for my bits to arrive but I’ll will amend the code for each of the scenarios and ensure it works with mine, you can then try that code and hardware setup.

Do you have voltage on pins 3 and 6?

On Mon, 17 Jul 2023 at 16:18, dc42 @.***> wrote:

I tried connecting a MAX485 board powered from 5V, with its RO output connected to the ESP32 RX2 input via a couple of resistors to reduce the voltage to 3.3V. I found I had to modify the Alpha2MQTT code to keep the transmit control pin high until the transmission has finished, due to my use of a hardware serial port. But even with that fixed, the result was the same as before: I can see the data transmitted by Alpha2MQTT on the Modbus, but there is no response from the inverter. I modified the code to request the serial number registers on each loop iteration until it read them successfully, then used an oscilloscope to read the data being sent. It reads 55 03 07 43 00 08 B9 78 which looks correct to me including the CRC. I tried holding the data output high for a couple of milliseconds before starting transmission, but that didn't help. Neither did adding a ground wire between the Alpha2MQTT and the inverter casing (Modbus components are supposed to have a common ground), and neither did using a different 5V USB power supply.

So I think either Modbus is still disabled on my SMILE5 despite the absence of a means to enable it in the Setup menu, or there is something wrong with the Modbus interface on my SMILE5.

On Mon, 10 Jul 2023 at 11:44, David Crocker @.***> wrote:

@Daniel, I published the code I used for the ESP32 at https://github.com/dc42/Alpha2MQTT/tree/master/Alpha2MQTT. The changes I made are summarised at https://github.com/dc42/Alpha2MQTT/tree/master/Alpha2MQTT. It's possible that with the change to use a hardware serial port, it may be necessary to flush the receive buffer immediately after transmitting, I'll check that if/when I start getting responses from the SMILE5.

I've also ordered a genuine MAX3485 board, and I have a MAX485 chip already; so I can try using those to take the auto switching out of the equation as you suggested.

On Mon, 10 Jul 2023 at 07:43, Daniel Young @.***> wrote:

I’ve bought an esp32, a couple of max485-ttl modules (the blue 5v ones), a couple of the genuine max3485 boards (genuine 3.3v with the EN pin) and some 3.3v-5v logic shifters.

I’ll get the code compiling and working with my existing red TTL board with the curious MAX13847E, then I’ll try all the other combinations and post findings.

I think that is probably the only sensible starting point.

Alpha have explicitly said they don’t disable modbus, someone I know went to one of their shows and asked the techies and they reported yes they removed the option but it was simply to make it “always on”. All their other systems have it on by default, I suppose it made no sense to retain a pointless option on one system.

As I said, I also read somewhere that a specific revision of Smile 5 hardware is notoriously finicky about rs485 timings and I think it is prudent to take the auto-switching of TX/RX out of the equation too.

My gut feeling historically has been when they removed the modbus enable option, some systems if disabled are possibly remaining disabled but getting their tech to acknowledge is difficult. I tend to message the German team as they are on it but then I struggle behind Google Translate.

UK too by the way :)

— Reply to this email directly, view it on GitHub < https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1628336692>,

or unsubscribe < https://github.com/notifications/unsubscribe-auth/AAUYI3GX63MRCTYJ3KOHGGTXPOQAFANCNFSM6AAAAAA2C4ZSMI>

. You are receiving this because you authored the thread.Message ID: @.***>

-- David Crocker, Duet3D Ltd.

-- David Crocker, Duet3D Ltd.

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1638360903, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYMNPS2U7F4LQYJUISLXQVJUHANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

dc42 commented 11 months ago

I have no voltage between pins 3 and 6, just 4.88V between 4 and 5 with no load. There is no voltage between 2 and 7 but there is 120 ohm resistance between those pins, so I think those are the CAN pins.

The Modbus manual appears to confirm that pins 4 and 5 are correct: image

dc42 commented 11 months ago

@Spookster I already tried upgrading the firmware through the app, in Function -> Upgrade management. It says I am running the latest version.

dxoverdy commented 11 months ago

I've added ESP32 support (in a limited guise) - All the instructions to swap are in the 1.21.txt release notes. Essentially change a couple of definitions and follow the alternate pinout. It won't be a problem for you. It also supports the screen. It uses HardwareSerial using Serial2 and one of the many spare digital IO pins for directional control.

So. Something which will give you hope. Certain combinations I can't get working with my tried and tested Smile B3... I ran out of time today to flirt with timings and pins etc.... ButI suspect it is to do with control pins or timings anyway. I can literally swap the board to the red module while turned on and it will come to life. All combinations work on the ESP8266 which is curious too.

ESP8266 with the Red Module - Working ESP8266 Red Module Working

ESP8266 with the Small Factor MAX3485 Working: ESP8266 Small Factor Chip Working

ESP8266 with the Blue Module (MAX485) with Voltage Shifter Working: ESP8266 Blue Module with Voltage Shifter Working

ESP8266 with Red Module Voltage Shifter Working ESP8266 Red Module Voltage Shifter Working

ESP32 with Red Module Working (First attempt) ESP32 Red Module Working

ESP32 with Red Module (Rearranged as the jumper wires were getting awful) - Working ESP32 Red Module Rearranged Working

ESP32 with Blue Module Voltage Shifter (Rearranged) - Not Working ESP32 Blue Module Voltage Shifter Not Working

ESP32 with Blue Mini Chip with Voltage Shifter - Not working ESP32 Blue Chip Voltage Shifter Not Working

Give the code a go with your setup and see if it works.

dc42 commented 11 months ago

Thanks for adding the ESP32 support. It's interesting that with the wide blue module you get a CRC error; whereas I don't get any response from the inverter at all. That does suggest a timing error, at least in your configuration.

I'll try my setup with your code. I'll also try removing the 120 ohm termination resistor from the wide blue module.

dc42 commented 11 months ago

@dxoverdy I think your ESP32 code is missing the change needed to delay switching the transceiver over to receive until the whole packet has been transmitted. See this part of my code https://github.com/dc42/Alpha2MQTT/blob/cd50622da9c32cc09d3f9fe7ceb25e3c57303960/Alpha2MQTT/RS485Handler.cpp#L112. If you add this, and perhaps remove the delay(100) call that you added at line 111 of your code, I think it may solve your CRC issue.

I observed on the oscilloscope that without this change, transmission was curtailed. It's because when you write a block to HardwareSerial, the data goes into a buffer and is sent by an interrupt service routine, so the write call returns before all the data has been sent.

dxoverdy commented 11 months ago

I must clarify, the error message is kinda generic. There is no differentiation on the display between CRC and no response. I’ll modify the code tomorrow to be a bit more informative in that regard.

I got zero response from the modules dependent on a flow control pin on the ESP32, but the red module auto sensing flow control worked fine on the ESP32.

All combinations worked on the ESP8266 so in conclusion I’m very comfortable that the hardware TX/RX of UART2 (ESP32) is fundamentally sound because it worked with the red module.

Given that flow control works fine on pin D5 of the ESP8266 I can only come to the conclusion that either the single pin I’ve tried on the ESP32 so far is not suitable despite the fact I do get 3.3v when I forced it high for 5 seconds, or the ESP32 isn’t clearing the flow control quick enough. When im back home tomorrow I’ll play with timings.

If I don’t get anywhere then specifically on a wide blue module I’d like to try tying DE to 3.3 so transmission always active and only forcing RE low for receipt in code…. And perhaps a better idea, tying RE to ground and only forcing DE high for the period of transmission.

Dan

On Sun, 23 Jul 2023 at 10:12, dc42 @.***> wrote:

Thanks for adding the ESP32 support. It's interesting that with the wide blue module you get a CRC error; whereas I don't get any response from the inverter at all. That does suggest a timing error.

I'll try my setup with your code. I'll also try removing the 120 ohm termination resistor from the wide blue module.

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1646789033, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYJXEN75VS2CKHMKQITXRTTIFANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

dxoverdy commented 11 months ago

I will give that a go buddy late tonight when I’m back or tomorrow and report back.

I am new to the hardwareserial/ESP32 and working blind without an oscilloscope:)

Thanks Dan

On Sun, 23 Jul 2023 at 10:36, dc42 @.***> wrote:

@dxoverdy https://github.com/dxoverdy I think your ESP32 code is missing the change needed to delay switching the transceiver over to receive until the whole packet has been transmitted. See this part of my code https://github.com/dc42/Alpha2MQTT/blob/cd50622da9c32cc09d3f9fe7ceb25e3c57303960/Alpha2MQTT/RS485Handler.cpp#L112. If you add this, and perhaps remove the delay(100) call that you added at line 111 of your code, I think it may solve your CRC issue.

I observed on the oscilloscope that without this change, transmission was curtailed. It's because when you write a block to HardwareSerial, the data goes into a buffer and is sent by an interrupt service routine, so the write call returns before all the data has been sent.

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1646793747, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYLKDGJKT2AMUFL5USTXRTWCVANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

dc42 commented 11 months ago

I got zero response from the modules dependent on a flow control pin on the ESP32, but the red module auto sensing flow control worked fine on the ESP32.

All combinations worked on the ESP8266 so in conclusion I’m very comfortable that the hardware TX/RX of UART2 (ESP32) is fundamentally sound because it worked with the red module. <<

That confirms that the issue is with the timing of switching the transmit/receive command pin. The red module doesn't use that signal. On the ESP8266 you use SoftwareSerial, so the write() call doesn't return until all the data has been sent.

I've found a NodeMCU ESP8266 module in my spares box, so I'll try using that with your code.

dc42 commented 11 months ago

I've got the inverter to respond to Modbus commands at last. This is what I did:

I'll do some experiments to see which of the incorrect baud rates need to be tried before a successful connection is possible.

dxoverdy commented 11 months ago

Great finds so far!

I’ve just checked the 8N1 and I stupidly haven’t put that begin within the ESP32 section and a second .begin for software serial.

Too eager to get something to you before I went away for the weekend.

I will move that line and implement later today.

It should be

if defined MP_ESP8266

_RS485Serial = new SoftwareSerial(RX_PIN, TX_PIN);

_RS485Serial->begin(INVERTER_BAUD_RATE);

elif defined MP_ESP32

_RS485Serial = new HardwareSerial(2); // Serial 2 PIN16=RXgreen, pin17=TXwhite

_RS485Serial->begin(INVERTER_BAUD_RATE, SERIAL_8N1);

endif

On Sun, 23 Jul 2023 at 15:11, dc42 @.***> wrote:

I've got the inverter to respond to Modbus commands at last. This is what I did:

  • I tried using your code (latest version on Github) on my version 0.9 ESP8266 NodeMCU. To get it to compile I had to change SERIAL_8N1 on line 33 of RS485Handler.cpp to SWSERIAL_8N1. Unfortunately the OLED display doesn't work - it prints some random-looking dots and then clears the lower ~25% of the display. [Perhaps the latest OLED library isn't compatible with ESP8266]. On the bench, serial monitor showed that it connected to WiFi and MQTT successfully and gave the expected Modbus timeout messages. When connected to the inverter (no serial monitor available), the oscilloscope showed no responses from the inverter.
  • I removed the 120 ohm termination resistor from the blue board. No change.
  • I try my fork of Alpha2MQTT on the ESP8266 NodeMCU. Same thing (display not working, no Modbus connection).
  • I investigated the signals on Modbus. I found that with the Alpha2MQTT disconnected, there is a common mode voltage at 50Hz with amplitude more than 80V peak to peak (31V RMS according to my meter). But the current sourced is only 100uA RMS, so the common mode voltage all but disappears when the Alpha2MQTT is connected and grounded via the oscilloscope.
  • Further testing with a multimeter indicated that pin 3 of the RJ45 connector is almost certainly the RS485 COM connection. So I have connected it to ground of the Alpha2MQTT.
  • I reverted to the ESP32 version because that has a working display, and re-tested. Still no communication.
  • Thinking that the baud rate could be wrong, I changed the code to change the baud rate each time it failed to get the serial number, scanning over a range of baud rates that I found in the Alpha-ESS literature. Now I get a connection!
  • The odd thing is, when it connects the baud rate is 9600, the same as I originally set! When I power up the Alpha2MQTT it initially gives the "not known" message indicating that fetching the serial number at the initial baud rate (still 9600) fails; but within a few seconds it connects. So I think trying to connect at the wrong baud rate must be priming the inverter in some way. I'll do some experiments to see which of the incorrect baud rates need to be tried before a successful connection is possible.

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1646850020, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYMZ7AXWZ65CF2CYGXDXRUWH3ANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

dc42 commented 11 months ago

I've simplified my code a bit and committed it to Github, https://github.com/dc42/Alpha2MQTT/tree/master. I still need to check that the data sent to MQTT is correct.

dxoverdy commented 11 months ago

I'm back home now.

First off, I've read over everything and caught up. Congratulations for getting it to respond, you're the first to get a response out of a troublesome unit. You are going to make a lot of folk happy if your findings help put something in play to sort the notorious Smile 5 issue permanently.

It is very interesting that the Smile 5, from what you are saying, appears to be booted into action after some interaction at varying baud rates... and I think it would be prudent to put some code in boot-up which attempts to wake the inverter by checking all known baud rates. If it succeeds on one it can set it and move forward, otherwise it can keep iterating known baud rates.... Ultimately, no reason to specify the baud rate or inverter by way of #define... As such, on boot, it will try 38400, 19200, 14400, 9600, 4800 with one second delays between each. Once it gets a response it will carry on. Otherwise it will stay there in perpetuity.

Thanks for the tip regarding flush - you've clearly done your homework with the documentation with regards to behaviour on softwareserial vs hardwareserial. Replacing 'happy-go-lucky' delays with flush() before releasing the control indeed brought it to life straight away. So we have a working ESP32/ESP8266 main branch.

I've uploaded code v1.22 which fixes issues from earlier with regards to compiling on both ESP32/ESP8266, and I've introduced NO-RSP as a display message for no response vs bad CRC which will respond with RSP-BADCRC. Regarding the display, I am not sure if you are using an OLED SHIELD with an RST pin or one of the displays without the RST pin. If you are using a display without the RST pin, clear OLED_HAS_RST_PIN in Definitions.h to false. That will cause the library to appropriately skip its reset handling and may result in a correct screen output for you. If you are using an OLED with an RST pin on the ESP32, please ensure RST is connected to GPIO13 as per 1.21 instructions. Otherwise, just ensure the shield is correctly mounted pin for pin on top of the ESP8266.

I know you have your own fork which I have no doubt you are frantically working on, but if you'd give v1.22 a try I'd appreciate it.

Thanks for your diligence so far! Dan

On Sun, 23 Jul 2023 at 16:10, dc42 @.***> wrote:

I've simplified my code a bit and committed it to Github, https://github.com/dc42/Alpha2MQTT/tree/master. I still need to check that the data sent to MQTT is correct.

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1646865676, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYLUFHEK56HX37JWTILXRU5GHANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

dc42 commented 11 months ago

Hi, the display I am using doesn't have a reset pin. It's this one: https://www.amazon.co.uk/dp/B08ZKY4VFK. It works with my ESP32 Devkit but not with my ESP8266 NodeMCU version 0.9 (the board doesn't have a version marked on it, but it works if I select NodeMCU 0.9 in Arduino Boards Manager but continuously reboots if I select NodeMCU 1.0). I tried adding external 4K7 pullup resistors to +3.3V on the two I2C pins but that didn't help. I am using the latest stable Arduino IDE, libraries, and ESP8266 and ESP32 cores.

As for the flush call, I only realised this was an issue when I saw on the oscilloscope that the transmit enable signal on pin 5 was much shorter than the pulse train on the ESP32 TxD pin. If you've been working blind, you've done very well to get as far as you did!

It would be good if we could merge our changes sometime. I have no desire to maintain a separate fork, I only did it to have somewhere to record my changes to support ESP32 and fix the compiler warnings.

Spookster commented 11 months ago

What pins are required for the OLED shield? I dont have mine piggy backed, and the (minimum) pins that worked before dont now. Ive tried #define OLED_HAS_RST_PIN false / true

Im using pins: 3v3 rst D1 D2 G

dxoverdy commented 11 months ago

It’s a little confusing.

I’ve probably not been obvious with my naming nor understood under the hood myself.

If you are running on an ESP8266 and have MP_ESP8266 defined then at the moment, that “oled has rst pin” is ignored anyway. I understood during development that the display needed a pin to briefly go low then high in order for it to 'boot' For the ESP8266 D0 was chosen, and that "oled has rst pin" does nothing.

When adding ESP32 support it no longer sat on top and so I assumed i'd need to link RST on the shield to another pin, and so I chose GPIO13. But this morning when I woke up and read your message it got me thinking that it made no sense that it worked using D0 -> D0 (ESP8266) but RST -> GPIO13 on the ESP32.

I've checked this morning and on both devices, with an OLED shield, only the four pins are needed. GND->GND 3.3V->3.3V SCL->SCL (D1 on ESP8266, GPIO22 on the ESP32) SDA->SDA (D2 on ESP8266, GPIO21 on the ESP32)

IMG_9967 IMG_9969

On reflection and a little re-reading other comments online, the reset pin is superfluous if using I2C (the SCL and SDA pins). I'll remove the complexity in a later version but for now those four pins should work perfect for you.

dxoverdy commented 11 months ago

I have posted v1.23 which removes the display configuration complexity. I have tested on both an ESP8266 and ESP32.

dxoverdy commented 11 months ago

Hi, the display I am using doesn't have a reset pin. It's this one: https://www.amazon.co.uk/dp/B08ZKY4VFK. It works with my ESP32 Devkit but not with my ESP8266 NodeMCU version 0.9 (the board doesn't have a version marked on it, but it works if I select NodeMCU 0.9 in Arduino Boards Manager but continuously reboots if I select NodeMCU 1.0). I tried adding external 4K7 pullup resistors to +3.3V on the two I2C pins but that didn't help. I am using the latest stable Arduino IDE, libraries, and ESP8266 and ESP32 cores.

As for the flush call, I only realised this was an issue when I saw on the oscilloscope that the transmit enable signal on pin 5 was much shorter than the pulse train on the ESP32 TxD pin. If you've been working blind, you've done very well to get as far as you did!

It would be good if we could merge our changes sometime. I have no desire to maintain a separate fork, I only did it to have somewhere to record my changes to support ESP32 and fix the compiler warnings.

Agreed.

I think the only changes now relate to compiler warnings (logical bit shifting and what have you.) If you have tidied them up I will lift and shift.

For what it is worth, mine is compiling/working under NodeMCU 1.0 (ESP-12E Module). Your continuous reboots though remind me of a problem I had with a batch of ESP8266s. They continually rebooted the moment WIFI was initiated. If I commented out the WIFI initialisation (setupWifi();) then the devices didn't continually bounce themselves... but that wasn't actually a solution. I presumed it was a shite batch of chips with broken WIFI but maybe it's just that they were older 0.9 boards after all.

Was there anything else you did besides checking a load of different baud rates to bring the smile 5 to life?

Thanks again Dan

dc42 commented 11 months ago

It's the checking different baud rates that made the big difference. As a test I reverted to not trying different baud rates, and it failed to connect. I also tried reducing the number baud rates in the table. I started out with 4800, 9600, 19200, 38400, 115200 and 256000 (the documentation for register 0x810 indicates that 9600, 115200 and 256000 are supported). I then tried 4800, 9600, 19200 but that didn't work. Then I tried 9600, 19200, 38400, 115200 and it worked again. I left it at that.

The other things I did that may have helped were to add the COM connection to the inverter and to remove the 120 ohm termination resistor from the RS485 board.

Overnight it seems to have collected good data about the battery, but it got a bad grid power value of 1.4MW at one point as you can see from this power diagram:

image

Do you see any similar anomalies? When the code assembles data to send via MQTT, how does it handle a bad read (CRC or timeout) of one of the inverter registers? I haven't looked much at that part of the code yet.

dxoverdy commented 11 months ago

It's the checking different baud rates that made the big difference. As a test I reverted to not trying different baud rates, and it failed to connect. I also tried reducing the number baud rates in the table. I started out with 4800, 9600, 19200, 38400, 115200 and 256000 (the documentation for register 0x810 indicates that 9600, 115200 and 256000 are supported). I then tried 4800, 9600, 19200 but that didn't work. Then I tried 9600, 19200, 38400, 115200 and it worked again. I left it at that.

The other things I did that may have helped were to add the COM connection to the inverter and to remove the 120 ohm termination resistor from the RS485 board.

Overnight it seems to have collected good data about the battery, but it got a bad grid power value of 1.4MW at one point as you can see from this power diagram:

image

Do you see any similar anomalies? When the code assembles data to send via MQTT, how does it handle a bad read (CRC or timeout) of one of the inverter registers? I haven't looked much at that part of the code yet.

Thanks for the clarification.... I think it may be sensible to include Pin 3 of the RJ45 to GND on the 485 in the instructions for belt and braces. That together with cycling known baud rates should hopefully do it. I did have a chat earlier in the year with one fella in Australia who couldn't get it working but was equally techy and so I'll try and touch bases with him again with the new approach.

Only a valid packet would make its way through to post processing. CRC errors / invalid length / invalid function codes etc are all ignored... As such, you can be confident at least to that point it is fine. A couple of others reported very infrequent stratospheric readings and they ended up working ad-hoc fixes into Node Red to the tune of "if > x, ignore"

I did look over 'REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1' when it was first reported to see if potentially there is an over/underflow but came up with nothing conclusive because it doesn't do too much by way of post processing.

In the case of REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1, in the documentation it is a signed integer, and so the following process takes place:

Four data bytes bitwise shifted into signedIntValue (same code for any signed integer register): rs->signedIntValue = (int32_t)(rs->data[0] << 24 | rs->data[1] << 16 | rs->data[2] << 8 | rs->data[3]);

And finally, signedIntValue sprintf into a char array for inserting into the MQTT message as formattedDataValue case REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1: { // Type: Integer // 1W/bit // Minus = feeding, Positive = drawing sprintf(rs->dataValueFormatted, "%d", rs->signedIntValue); break; }

I don't run an Alpha2MQTT locally believe it or not. It was more a fun project. I only get it out for things like this. To assist in finding out whether the Alpha is actually spitting out that value or some post processing is causing it to break, it may be worth pinging the alpha2mqtt a message every ten seconds:

Topic: Alpha2MQTT/request/read/register/handled Payload: { "registerAddress": "0x0021" }

You will get a response to Alpha2MQTT/response/read/register/handled

With something akin to this: { "responseStatus": "readDataRegisterSuccess", "registerAddress": "0x0021", "functionCode": 3, "registerName": "REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1", "dataType": "signedInt", "dataValue": 123515, "formattedDataValue": 12351.50, "rawDataSize": 4, "rawData": [0,1,226,123], "end": "true" }

If you store dataValue, formattedDataValue and rawData together, when a rogue message comes in (where formattedDataValue is humongous) we can look at the rawData to see if the actual received bytes derive that number or if it is some post processing in Alpha2MQTT.

It would be great if you could do that once you are settled with it all.

Thanks Dan

Spookster commented 11 months ago

That is annoying when you want a nice graph, and HA doesnt make it easy to fix. As Dan mentioned, you can use a filter at node red for all the graphed values to remove spikes: image

dc42 commented 11 months ago

Thanks @Spookster, I'll try that, or else add some filtering in Alpha2MQTT.

I just had another anomaly, this time with Load:

image

dc42 commented 11 months ago

The solar and grid frequencies are off by a factor of 10. Has anyone else seen this? Inverter frequency is OK though. I can't see any reason for it in the code, the AlphaESS Modbus doc says all three are reported in units of 0.01Hz.

image

dc42 commented 11 months ago

It occurred to me that perhaps the code that checks the received CRC doesn't really check it - and that is indeed the case:

bool RS485Handler::checkCRC(uint8_t frame[], byte actualFrameSize)
{
    unsigned int calculated_crc, received_crc;

    received_crc = ((frame[actualFrameSize - 2] << 8) | frame[actualFrameSize - 1]);
    calcCRC(frame, actualFrameSize);
    calculated_crc = ((frame[actualFrameSize - 2] << 8) | frame[actualFrameSize - 1]);

    return (received_crc = calculated_crc);
}

Note the single "=" in the return statement. I'll fix this and see if the occasional bad values stop.

PS - is there a way to clear out the existing inverter data in HA so that the charts will restart with a sensible power scale? I renamed the HA database and then restarted HA, and although that cleared out some of the history it didn't affect today's power diagram.

dc42 commented 11 months ago

The live status display of importing or exporting display was incorrect (swapped). The Format node of the Ten Second Status node needed to be changed to this:

msg.payload.GRID_STATUS = msg.payload.REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1 == 0 ? "Idle" : msg.payload.REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1 < 0 ? "Exporting" : "Importing";

I changed > to < in this line. The red/green colour selection in Grid Power was similarly reversed so I edited that dashboard element.

dxoverdy commented 11 months ago

Out of interest was it a slight oversight on my part or does the alpha modbus instructions indicate what I did?

Thanks :) Dan

On Mon, 24 Jul 2023 at 15:12, dc42 @.***> wrote:

The live status has importing/exporting swapped. The Format node of the Ten Second Status node needed to be chahged:

msg.payload.GRID_STATUS = msg.payload.REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1 == 0 ? "Idle" : msg.payload.REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1 < 0 ? "Exporting" : "Importing";

I changed > to < in this line.

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1647999411, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYN7AGN5D2YL4V4JC6TXRZ7GHANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

dxoverdy commented 11 months ago

Genius!!!!!!!!!! Top man!

On Mon, 24 Jul 2023 at 13:19, dc42 @.***> wrote:

It occurred to me that perhaps the code that checks the received CRC doesn't really check it - and that it indeed the case:

`bool RS485Handler::checkCRC(uint8_t frame[], byte actualFrameSize) { unsigned int calculated_crc, received_crc;

received_crc = ((frame[actualFrameSize - 2] << 8) | frame[actualFrameSize - 1]); calcCRC(frame, actualFrameSize); calculated_crc = ((frame[actualFrameSize - 2] << 8) | frame[actualFrameSize - 1]);

return (received_crc = calculated_crc);

} ` Note the single "=" in the return statement. I'll fix this and see if the occasional; bad values stop.

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1647806510, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYKYUEPJI7NDSGH6QUTXRZR5ZANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

dc42 commented 11 months ago

Out of interest was it a slight oversight on my part or does the alpha modbus instructions indicate what I did?

If you mean the Format node then I'm guessing it was an oversight, because the preceding two lines that calculate exported and imported power used >= and < correctly, i.e. negative REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1 means exporting.

I've committed those changes to my fork.

dxoverdy commented 11 months ago

Do you want to be contributor / admin to the Alpha2MQTT project? You have a keen eye and would be able to reconcile changes you feel are necessary to avoid you needing a fork?

I think readings which are out by a factor of something should possibly remain out on the chip and instead corrected in post in node red on a piece by piece basis by occasional folk who need to. Otherwise there is possibly a rabbit hole to fall down. How many registers have you found affected can I ask?

I have two modbus documents and found some calculation factors varied between the two. At first I only implemented the newer documentation but someone I know with a T10 actually honoured the older factors and that’s why that is in there.

Regards Dan

On Mon, 24 Jul 2023 at 16:31, dc42 @.***> wrote:

Out of interest was it a slight oversight on my part or does the alpha modbus instructions indicate what I did?

If you mean the Format node then I'm guessing it was an oversight, because the preceding two lines that calculate exported and imported power used >= and < correctly, i.e. negative REG_GRID_METER_R_TOTAL_ACTIVE_POWER_1 means exporting.

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1648144223, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYOHJPXML5S5U3HXZTDXR2INBANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

Spookster commented 11 months ago

The solar and grid frequencies are off by a factor of 10. Has anyone else seen this? Inverter frequency is OK though. I can't see any reason for it in the code, the AlphaESS Modbus doc says all three are reported in units of 0.01Hz.

image

https://github.com/dxoverdy/Alpha2MQTT/issues/12

Spookster commented 11 months ago

< sorted >

(and I dont want to divert from the good work that is going on in this thread!)

dxoverdy commented 11 months ago

As well as no display??

On Mon, 24 Jul 2023 at 22:17, Spookster @.***> wrote:

Another note - Plugging 1.23 into my working system results in a continuous baud checking loop

— Reply to this email directly, view it on GitHub https://github.com/dxoverdy/Alpha2MQTT/issues/14#issuecomment-1648624545, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZC7OYP3P2CAGVUZH52EAWLXR3Q6HANCNFSM6AAAAAA2C4ZSMI . You are receiving this because you were mentioned.Message ID: @.***>

Spookster commented 11 months ago

As well as no display??

Apologies -I think the wiring (tx/rx) was borked on the test unit. I have it running now.....

dc42 commented 11 months ago

@dxoverdy thanks for inviting me to be an admin for the project. I'd be happy to make contributions. However, I'm not really interested in supporting ESP8266 now that ESP32 boards are so cheap and have significant advantages (much more RAM, no need to mess with PROGMEM etc.). My only attempt as using an ESP8266 device failed (I couldn't get the display to work). So I wouldn't be testing any changes I make on ESP8266 systems, and that wouldn't be help to existing users of your project.

BTW since I fixed the CRC code I have seen no more instances of wildly out-of-range readings. Prior to that I saw a whole cluster of them around the same time. So my guess is that that they were caused by electrical noise.

I'd be happy to close this issue now.

dxoverdy commented 9 months ago

Awesome. Thanks for your input. Glad e got there in the end.