Sleeper85 / esphome-jk-bms-can

GNU General Public License v3.0
64 stars 18 forks source link

CAN communication not stable #23

Closed lucize closed 4 months ago

lucize commented 4 months ago

using the original version from uksa007 I have stable connection with the inverter but using this code it seems that the inverter loses connectivity quite frequently with the inverter, I get several alarms on the inverter ar random times. I'm using Bluetooth and mcp2515 CAN adapter as I couldn't make it work with the TJA adapter (maybe it was faulty) and esp32doit-devkit-v1 with the old code I also use Bluetooth proxy with stable communication some hints on the build option ?

Sleeper85 commented 4 months ago

uksa007 has not made a Bluetooth version of the YAML and MCP2515 is not a CAN module that we have tested.

Is it more stable if you use the Wire version?

What alarms do you receive?

Does the “CANBUS Status” sometimes go OFF?

lucize commented 4 months ago

yes, the canbus status goes off, I've adapted his script to Bluetooth, I didn't catch the log with exact time when the errors ocurs. But his scrips was rock solid for about half of the year since I've started using this solution

image

Sleeper85 commented 4 months ago

What CAN protocol do you use? Did you compile the BLE version with the esp-idf framework?

Sleeper85 commented 4 months ago

It is this code which is responsible for checking the status of the CAN connection. Your inverter should send ID 0x305 to confirm the connection is OK. When receiving the ID 0x305 the can_ack_counter is reset to 0. If this counter is >= 20 the CAN bus connection is marked OFF and waits 120s before testing the communication again.

Maybe you should increase the condition below to 30.

if (id(can_ack_counter) < 30)
# +--------------------------------------+
# | Start CAN Handling                   |
# +--------------------------------------+
canbus: # 0x305 - Inverter ACK - SMA/LG/Pylon/Goodwe reply
  - platform: esp32_can
    tx_pin: ${can_tx_pin}
    rx_pin: ${can_rx_pin}
    can_id: 4
    bit_rate: 500kbps
    on_frame:
    - can_id: 0x305
      then:
        - light.toggle:
            id: blue_led
        - lambda: |-
            id(can_ack_counter) = 0;                              // Reset ACK counter
            id(can_bus_status).publish_state(true);               // Set CANBUS Status to ON
            ESP_LOGI("main", "received can id: 0x305 ACK");

interval:
  - interval: 120s
    then:
      - lambda: id(can_ack_counter) = 0;                          // Reset ACK counter for test inverter ACK

  - interval: 100ms
    then:
      - if:
          condition:
            lambda: |-

              if (id(can_ack_counter) < 20) {                     // Inverter ACK ? => CANBUS ON

                id(can_ack_counter)++;                            // CANBUS ACK counter ++
                id(can_msg_counter)++;                            // CANBUS MSG counter ++
                return true;                                      // Condition OK

              }
              else if (id(can_bus_status).state == false) {       // CANBUS already OFF ?

                return false;                                     // Nothing to do

              }
              else {

                id(can_bus_status).publish_state(false);          // Set CANBUS Status to OFF
                ESP_LOGI("main", "No rx can 0x305 reply, Inverter not connected/responding...");
                return false;                                     // Condition NOK

              }
lucize commented 4 months ago

pylon+, the last yaml used, esp-idf recommended Bluetooth data get's updated as they should

lucize commented 4 months ago

the inverter also goes in alarm so is like the esp32 doesn't send the data fast enough ?

image

lucize commented 4 months ago

for mcp I use this

canbus:
#  - platform: esp32_can
#    tx_pin: ${can_tx_pin}
#    rx_pin: ${can_rx_pin}
#    can_id: 4
#    bit_rate: 500kbps
  - platform: mcp2515
    cs_pin: ${can_cs_pin}
    bit_rate: 500kbps
    can_id: 4
    on_frame:
    - can_id: 0x305

EDIT: I'll try later with increased number

Sleeper85 commented 4 months ago

You can increase the speed of sending CAN IDs from 100ms to 50ms to test.

  - interval: 50ms
    then:
      - if:
          condition:
            lambda: |-

              if (id(can_ack_counter) < 20) {                     // Inverter ACK ? => CANBUS ON

                id(can_ack_counter)++;                            // CANBUS ACK counter ++
                id(can_msg_counter)++;                            // CANBUS MSG counter ++
                return true;                                      // Condition OK

              }
              else if (id(can_bus_status).state == false) {       // CANBUS already OFF ?

                return false;                                     // Nothing to do

              }
              else {

                id(can_bus_status).publish_state(false);          // Set CANBUS Status to OFF
                ESP_LOGI("main", "No rx can 0x305 reply, Inverter not connected/responding...");
                return false;                                     // Condition NOK

              }
lucize commented 4 months ago

changed both, seems more stable, but still some drops on the esp32 side seems to be more often on the inverter side I can see less, maybe because I read at 7 sec interval but at least it doesn't trip the battery communication alarm on deye software

I can see the battery temperature spike read by the inverter when it's not receiving data image and on esp the connection seems to fail for a second but more often than what the inverter is logging (again maybe because I read the data at 7 sec interval)

image should I try the ack counter a bit higher ?

MrPabloUK commented 4 months ago

Quick question, do you have the termination jumper in place on the MCP2515 board? image

lucize commented 4 months ago

of course, I also measured it, the thing is that the old script is working fine, this one maybe it's a bit more complex and maybe there are some delays, but anyhow I'll try with ack counter increase.

lucize commented 4 months ago

in the end i think this relaxed settings are working fine

  - interval: 50ms
    then:
      - if:
          condition:
            lambda: |-

              if (id(can_ack_counter) < 60) {                     // Inverter ACK ? => CANBUS ON
OselDusan7 commented 4 months ago

Sleeper85 , could you please make this interval, and ack counter value as variables set in the head of YAML ? I think best would be to create section there , with note like # please do no change unless you know what you are doing.

Sleeper85 commented 1 month ago

Sleeper85, pourriez-vous s'il vous plaît créer cet intervalle et accuser la valeur du compteur en tant que variables définies dans l'en-tête de YAML ? Je pense que le mieux serait de créer une section ici, avec une note comme #, veuillez ne rien changer à moins que vous sachiez ce que vous faites.

This is done like this in the new version which is in the development branch.