netmindz / balboa_GL_ML_spa_control

Control protocol between GL2000 controller and ML series compatibile top panel
17 stars 8 forks source link

handleMessage doesn't get called #56

Closed fherbert closed 11 months ago

fherbert commented 12 months ago

I've got a GL2000 with a ML700 panel. Using a ESP32-PICO-DevKitM-2 board. I'm using one of the suggested RS485 adapter boards. It not 100% clear to me if I need to worry about the RTS_PIN since my RS485 adapter doesn't need it, should it be set to the same pin as PIN_5_PIN? Currently I've got PIN_5_PIN set to the I/O that the molex pin 5 is connected to and RTS_PIN set to an I/O that isn't connected to anything.

On bootup the serial output shows:

Connecting to AP....
Connected with IP: 10.0.0.128
Setting pin 12 LOW
Setting serial port as pins 19, 21
Set serial port as pins 19, 21
Configuring WDT...
End of setup

When I browse to the web page, I see the following in the serial output: {"type": "status", "data" : { "temp": "-1.0", "heater": false, "light": false, "mode": "-1", "uptime": 0, "state": "unknown" } }

I've put an oscilloscope on the PIN_5_PIN and can see it going low. I can see some bytes available if I uncomment the printf here:

bytes avail = 25
bytes avail = 247
bytes avail = 127
bytes avail = 23
bytes avail = 32
bytes avail = 16
bytes avail = 25
bytes avail = 23
bytes avail = 32
bytes avail = 16
bytes avail = 25
bytes avail = 23
bytes avail = 32
bytes avail = 16
bytes avail = 25

Any suggestions on how to troubleshoot this? I have a logic probe and oscilloscope available.

fherbert commented 12 months ago

I've put a scope onto pin 5, (which is pin 20 on my esp32) and can see it going low for ~3.6ms every ~40ms, but the code never executes the handleMessage function (tested by uncommenting the printf lines at start).

fherbert commented 12 months ago

handleBytes is getting called, it randomly (once every 10 restarts or so) ends up calling handleMessage, but the majority of the time it's not. If I add some debugging output in handleBytes, it seems to add enough of a delay or something to end up calling handleMessage, after doing that, if I enable the print here I get:

message = ae0d03000000000000000000000000b4fb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d000000000000000000000000002dae0d000000000000000000000000002dfb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d010000000000000000000000005aae0d010000000000000000000000005afb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d02000000000000000000000000c3060000ff40ae0d010000000000000000000000005aae0d010000000000000000000000005afb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d02000000000000000000000000c3ae0d02000000000000000000000000c3fb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d03000000000000000000000000b4ae0d03000000000000000000000000b4fb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d000000000000000000000000002dae0d000000000000000000000000002dfb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d010000000000000000000000005aae0d010000000000000000000000005afb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40
message = ae0d03000000000000000000000000b4fb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d000000000000000000000000002dae0d000000000000000000000000002dfb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d010000000000000000000000005aae0d010000000000000000000000005afb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d02000000000000000000000000c3060000ff40ae0d010000000000000000000000005aae0d010000000000000000000000005afb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d02000000000000000000000000c3ae0d02000000000000000000000000c3fb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d03000000000000000000000000b4ae0d03000000000000000000000000b4fb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d000000000000000000000000002dae0d000000000000000000000000002dfb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d010000000000000000000000005aae0d010000000000000000000000005afb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d02000000000000000000000000c3ae0d02000000000000000000000000c3fb0664d4060000ff40fa143137304300106a00008082000c293e000000000027fa143137304300106a00008082000c293e000000000027fb0664d4060000ff40ae0d03000000000000000000000000b4ae0d03000000000000000000000000b4fb0664d4060000ff40fa143137304300106a00008082000c293e000000000027
message = ae0d03000000000000000000000000b4ae0d03000000000000000000000000b4fb0664d4060000ff40
netmindz commented 12 months ago

It's one that FA messages that we actually do anything with

Looks for some reason why it's reading more data into the buffer before calling handleMessage

That fact you are having data longer than a message on the serial buffer l looks a bit odd, but maybe that's when pin5 is high.

I suspect if you change

(result.length() >= msgLength)

To

(result.length() == msgLength)

Then you might just get nothing rather than processing the FA messages rather than discarding as it's on the end of the AE messages, but worth a try.

You can also try commenting out the if HIGH block so you aren't doing anything other than reading the serial to see if then do a better job of keeping up

netmindz commented 12 months ago

I'm wondering if the Pico has different speed or serial buffer or something than the classic esp32

netmindz commented 12 months ago

Can you also try checking out v0.0.9-readonly tag to see if the older way of parsing the data gives and results?

netmindz commented 12 months ago

Can you also try checking out the "library" branch of the code to see if that does any better?

netmindz commented 12 months ago

This issue describes what we expect from the pin5 based message framing

https://github.com/netmindz/balboa_GL_ML_spa_control/pull/13

fherbert commented 12 months ago

Using the v0.0.9-readonly tag, i get the following on the serial console:

Connecting to AP....
Connected with IP: 10.0.0.128
Setting pin 12 LOW
Setting serial port as pins 19, 21
Set serial port as pins 19, 21
Configuring WDT...
Unknown message (0): 
FA 14 Long
Sent temp data 16.500000
AE 0D Long
FA 14 Long
AE 0D Long
FA 14 Long
Unknown message (62): ae0d02000000000000000000000000c36a00008082000c073e00000000006f
FA 14 Long
AE 0D Long
FA 14 Long
AE 0D Long
FA 14 Long
AE 0D Long
FA 14 Long
AE 0D Long

Tried using library branch, webserver page doesn't respond, serial output shows:

Connecting to AP....
Connected with IP: 10.0.0.128
Setting serial port as pins 19, 21
Set serial port as pins 19, 21
Configuring WDT...
End of setup

From what I can tell so far, sendBuffer is never empty, so it doesn't process the webserver requests.

Also tried changing to (result.length() == msgLength) but still nothing, and commented out HIGH code block but still no comms.

fherbert commented 12 months ago

Using the main branch again, If I change this line to if (msgLength == 0 && result.length() == 2) {, I get the following on the serial monitor:

Connecting to AP....
Connected with IP: 10.0.0.128
Setting pin 12 LOW
Setting serial port as pins 19, 21
Set serial port as pins 19, 21
Configuring WDT...
End of setup
message = ae0d010000000000000000000000005afb0664d4060000ff40fa143230304300106a00008082000c2344000000000079fa143230304300106a00008082000c2344000000000079fb0664d4060000ff40ae0d02000000000000000000000000c3ae0d02000000000000000000000000c3fb0664d4060000ff40fa143230304300106a00008082000c2344000000000079fa143230304300106a00008082000c2344000000000079fb0664d4060000ff40ae0d03000000000000000000000000b4ae0d03000000000000000000000000b4fb0664d4060000ff40fa143230304300106a00008082000c2344000000000079
message = fa143230304300106a00008082000c2344000000000079
YAY: command response : 40
Sent temp data 20.000000
message = ae0d000000000000000000000000002d
message = fa143230304300106a00008082000c2344000000000079
message = ae0d010000000000000000000000005a
message = fa143230304300106a00008082000c2444000000000078
YAY: command response : 40
message = ae0d02000000000000000000000000c3
message = fa143230304300106a00008082000c2444000000000078
message = ae0d03000000000000000000000000b4
message = fa143230304300106a00008082000c2444000000000078
message = ae0d000000000000000000000000002d
message = fa143230304300106a00008082000c2444000000000078
message = ae0d010000000000000000000000005a
message = fa143230304300106a00008082000c2444000000000078
message = ae0d02000000000000000000000000c3
message = fa143230304300106a00008082000c2444000000000078
message = ae0d03000000000000000000000000b4
message = fa143230304300106a00008082000c2444000000000078
netmindz commented 12 months ago

That's the original version of that bit of code. Now you are seeing that you should have the correct info on the status page and the right info coming through to Home Assistant

netmindz commented 12 months ago

Looks like for some reason the original code is more reliable https://github.com/netmindz/balboa_GL_ML_spa_control/issues/46

fherbert commented 12 months ago

It's not 100% clear to me how you determine which bytes in the serial receive buffer are meant for us to process - ie when pin 5 is low? From what I can tell, since serial is started in setup, anything received on the RX line will be stored in the serial buffer and then the buffer will be passed to handleBytes once pin 5 goes low? Wouldn't we want an empty buffer at the start of pin5 going low so we've only got data meant for our 'panel'?

Also, I don't know if my version of GL2000 is slightly different to yours, but using my logic probe, I can only see 2 sets of messages sent by the control unit, not 3. The format is the same though, FA to our panel, FA to ML700, which returns a FB, AE to our panel, AE to ML700, which returns a FB, then repeats.

netmindz commented 11 months ago

We always call serial.read, but only actually call handleBytes when the bytes were read when pin5 == LOW

It's a bit ugly, but generally works ok. Could you would use interrupts, but there are restrictions as to what you can actually do inside one, certainly can't write, not sure if you can clear the buffer

You didn't comment as to if you are now up and running now the messages are being handled.

As for the protocol, do you have 2 or 3 sockets on the main board for top panels? You should see data as pin5 goes LOW on each socket in turn see https://github.com/netmindz/balboa_GL_ML_spa_control/wiki/Message-Format and https://github.com/netmindz/balboa_GL_ML_spa_control/discussions/3

fherbert commented 11 months ago

I can't send any commands, says pin went high before command sent. The handling of messages also doesn't match what I'm seeing on the panel. I'm trying a few differerent ways of getting the serial data, but can't seem to get it reliably receiving data and sending in the same pin5 level change. I tried using the pin change interrupt but haven't had much luck so far, just managing to crash the esp32 with messages like assert failed: taskSelectHighestPriorityTaskSMP tasks.c

I only have 2 sockets on the board for panels, so I guess that explains why only 2 sets of commands are sent. My GL2000 part number is 21998 REV A.

I'll do some checking of the actual messages to make sure they still confirm to what handleMessage is expected. Also I'm going to try and use ESP-IDF to enable the serial using pin change interrupt when pin5 goes low, get the first byte, then interrupt when the expected number of bytes have been received and then try sending commands. I won't have any of the HA/mqtt libraries though, so this might be a waste of time.

fherbert commented 11 months ago

FYI, here's what I'm seeing on pin 5 and the RX pin.

Screenshot 2023-10-11 at 6 51 45 AM

The FA message I'm receiving

Screenshot 2023-10-11 at 6 56 35 AM

The AE message I'm seeing:

Screenshot 2023-10-11 at 6 57 22 AM

The FA the the ML700 with FB response:

Screenshot 2023-10-11 at 6 58 55 AM

The AE to the ML700 with FB response:

Screenshot 2023-10-11 at 6 59 43 AM
netmindz commented 11 months ago

Ok, so command sending works for some ESP32 setups, but the timing isn't great, it's a WiP so some users see issues, my ESP32-C3 doesn't send properly

I'll ask again, are you seeing the read of data ok - What does the status page show?

I've not checked every byte, but from a quick look the info you show on the scope is in line with what I would expect given you have only 2 ports

As you have a better scope than me, one thing you could help with is confirming what the timing interval is when we try and send an FB message vs from the official top panel

netmindz commented 11 months ago

Please report any issues with sending commands on this issue https://github.com/netmindz/balboa_GL_ML_spa_control/issues/58

fherbert commented 11 months ago

If I revert the code changes made https://github.com/netmindz/balboa_GL_ML_spa_control/issues/46 then I get comms working. This on the serial console:

Connecting to AP..
Connected with IP: 10.0.0.128
Setting pin 12 LOW
Setting serial port as pins 19, 21
Set serial port as pins 19, 21
Configuring WDT...
End of setup
YAY: command response : 40
Sent temp data 0.000000
[0] Connected from 10.0.0.19 url: /
{"type": "status", "data" : { "temp": "0.0", "heater": false, "light": false, "mode": "-1", "uptime": 0, "state": "Cleaning" } }
YAY: command response : 40
YAY: command response : 40
YAY: command response : 40
Sent temp data 17.000000

17C is what is showing on the panel.

This is what shows on the web status page

Mode: -1
State: Cleaning
Temp: 17.0C
Heating: true
Last Update: Wed Oct 11 2023 20:26:52 GMT+1300 (New Zealand Daylight Time)

Switching the light on works!

I'll keep working on it and see if I can get it working using interrupts, I think this way it would be much more reliable.

netmindz commented 11 months ago

Interrupt would mean clearing the serial buffer when it goes low, then keep reading till we have read the total number of bytes expected, based on the first two bytes read

fherbert commented 11 months ago

My idea at this stage is to not use the arduino serial library but to try access the registers to start UART receive in the pin falling interrupt. Just an idea at this stage, just need some more hours in the day to figure it out and try.

I've already tried clearing the serial buffer in the pin change interrupt but got assert errors, so I don't think I can use the Arduino serial library for this.

netmindz commented 11 months ago

Before you go down that rabbit hole, current issues are about sending rather than receiving. So your time would be much more helpful given you have a decent scope helping with https://github.com/netmindz/balboa_GL_ML_spa_control/issues/58