rakhmaevao/JbdBms

Work with newer versions of smart BMS?

parallaxengineering opened this issue · 12 comments

I noticed this code works with older version but not newer versions of the smart JBD BMS. Right now it only correctly reads the cell information but has communication error with basic information. I believe it is a checksum issue

I noticed this code works with older version but not newer versions of the smart JBD BMS. Right now it only correctly reads the cell information but has communication error with basic information. I believe it is a checksum issue

Hello.
Unfortunately, I have neither the old nor the new BMS board. It would be great if you found a bug and described its solution.
And best of all - you make a pull request.
I just can't help.

Hello, thanks for reply. Actually I just confirmed that it is a checksum issue. If i set checkCheckSumRecieve(responce) == false, than it reports the data properly. So there is some issue with checksum in new version. Not sure if it helps but I am printing the response of the new devices and this is what I get:

DD03001D0536000059A459D800002C5A00000000000080640104030BA00B940B97FA

Could you provide some guidance in how to fix this issue?

I do not know if I can give any help, but I've been struggling with my BMS communications and I don't know if it is the early version or not. I have never had trouble reading cell voltages, and I've always had trouble with the basic bms info request.
So, I am attaching the code I use, even though it's for a Pro-Mini and uses the hardware builtin Serial port. (Not software serial).
The way I check to verify the data I receive is by making sure the 3rd byte is the right length of following bytes (27). If that's good, then I know it's all good or successful.

//Pro Mini Slave I2C, task: read Serial from BMS, then convert to one char array for the master's I2C request.

#include <Wire.h>

uint8_t RX1bytes[42];     //MAKE SURE THESE ARE LONG for overflow!!!
uint8_t RX2bytes[42];        //an array to hold cell incoming data (needs unsigned int)
uint8_t I2Cbytes[24];   //  (index0-22+term.  So give 23(called 0-22)bytes, and then terminate with index23)

void setup() {
  Wire.begin(6);
  Wire.onRequest(requestEvent);
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void requestEvent() {     //master arduino requests data from this pro-mini
   Wire.write(I2Cbytes, 23);
}

void loop() {
    digitalWrite(13, HIGH);
    TX1BMS();
    RX1BMS();
    TX2BMS();
    RX2BMS();
    digitalWrite(13, LOW);
    delay(700);  //later I should adapt this to a kind of sleep mode
}

  void TX1BMS() {   //----------------REQUEST CELL INFO
    while (Serial.available() > 0) {
      Serial.read();
      delay(50);
    }
    uint8_t celldata[7] = {221, 165, 4, 0, 255, 252, 119};        //Create request array
    Serial.write(celldata, 7);                 // DD  A5  4 0 FF  FC  77   //REQUEST CELL INFO
    delay(100);                                 // required for reliability
  }

  void RX1BMS() {
    if (Serial.available() > 0) {
      for (int i = 0; i < 12; i++) {               // just get first 4 bytes +8
        RX1bytes[i] = Serial.read();               //kinda unnecessary to read first to byte then to add to array later
        delay(5);
      }
      RX1bytes[12] = '\0';   //terminates 'for' loop char array
    }

    if (RX1bytes[3] == 8) {                // THE [3]4TH byte HOLDS LENGTH
      I2Cbytes[0] = RX1bytes[4];
      I2Cbytes[1] = RX1bytes[5];
      I2Cbytes[2] = RX1bytes[6];
      I2Cbytes[3] = RX1bytes[7];
      I2Cbytes[4] = RX1bytes[8];
      I2Cbytes[5] = RX1bytes[9];
      I2Cbytes[6] = RX1bytes[10];
      I2Cbytes[7] = RX1bytes[11];
    }
    else {
      I2Cbytes[0] = 0;
      I2Cbytes[1] = 0;
      I2Cbytes[2] = 0;
      I2Cbytes[3] = 0;
      I2Cbytes[4] = 0;
      I2Cbytes[5] = 0;
      I2Cbytes[6] = 0;
      I2Cbytes[7] = 0;
    }
  }

  void TX2BMS() {     //-----------------------------REQUEST BASIC INFO
    while (Serial.available() > 0) {
      Serial.read();
      delay(50);
    }
    uint8_t basicdata[7] = {221, 165, 3, 0, 255, 253, 119};  //  DD  A5 03 00  FF  FD  77
    Serial.write(basicdata, 7);
    delay(100);
  }

  void RX2BMS() {
    if (Serial.available() > 0) {
      int n = Serial.available();    ////slave address of Pro-Mini is 6.  Ask for 23 bytes (index 0-22)
      for (int i = 0; i < n; i++) {
        RX2bytes[i] = Serial.read();
        //Length = RX2bytes[3];
        delay[5];
      }
      RX2bytes[n + 1] = '\0';
    }

    //first 4 bytes: [0]=DD [1]=05 [2]=00 [3]=XX (00 = OK signal, XX =n LENGTH)
    //Cells, 4-5, 6-7, 10-11,   17,  20-21,   23,  24,   27-28, 29-30
    //-------v----a----CAP---BAL--STA---SOC-FET--T1-----T2--
    // FULL STRING length = 23 (0-22+23RD ENDER)

    if (RX2bytes[3] == 27) {
      I2Cbytes[8] = RX2bytes[4];
      I2Cbytes[9] = RX2bytes[5];
      I2Cbytes[10] = RX2bytes[6];
      I2Cbytes[11] = RX2bytes[7];
      I2Cbytes[12] = RX2bytes[10];
      I2Cbytes[13] = RX2bytes[11];
      I2Cbytes[14] = RX2bytes[17];
      I2Cbytes[15] = RX2bytes[20];
      I2Cbytes[16] = RX2bytes[21];
      I2Cbytes[17] = RX2bytes[23];
      I2Cbytes[18] = RX2bytes[24];
      I2Cbytes[19] = RX2bytes[27];
      I2Cbytes[20] = RX2bytes[28];
      I2Cbytes[21] = RX2bytes[29];
      I2Cbytes[22] = RX2bytes[30];
      I2Cbytes[23] = '\0';
    }
    else {
      I2Cbytes[8] = 0;
      I2Cbytes[9] = 0;
      I2Cbytes[10] = 0;
      I2Cbytes[11] = 0;
      I2Cbytes[12] = 0;
      I2Cbytes[13] = 0;
      I2Cbytes[14] = 0;
      I2Cbytes[15] = 0;
      I2Cbytes[16] = 0;
      I2Cbytes[17] = 0;
      I2Cbytes[18] = 0;
      I2Cbytes[19] = 0;
      I2Cbytes[20] = 0;
      I2Cbytes[21] = 0;
      I2Cbytes[22] = 0;
      I2Cbytes[23] = '\0';
    }
  }

Use this library and set line 41 in Jbdbms.cpp ==false instead of true. Than it will read the basic data. Sounds like you have a new BMS like me and this library will still work but you need to make that code change.

Friends, unfortunately I can't code and test this library today.

If you are sure that in the new BMS the checksum is calculated in a new way, then write a new child class as I did in the 8-add-the-function-of-workeing-with-the-sn75176 branch.

Test and make a pull request.

Hi,

i tried to look into this and i think i found the problem. The checksum calculation is ok and working fine. The problem is the length of the response. In the response from parallaxengineering i can see that two bytes are missing.

So changeing the JbdBms.h should help.
#define BMS_LEN_RESPONCE 36

I can't test it for myself, but simulated it.

Hi,

i tried to look into this and i think i found the problem. The checksum calculation is ok and working fine. The problem is the length of the response. In the response from parallaxengineering i can see that two bytes are missing.

So changeing the JbdBms.h should help. #define BMS_LEN_RESPONCE 36

I can't test it for myself, but simulated it.

This is great.
Who could verify this?

I have to JBD SP04S034 4s 200A new Version and I can confirm that with the #define BMS_LEN_RESPONCE 36 fix it works fine.

Edit:
I've done lot of debuging. BMS_LEN_RESPONCE is 34 enought.
My problem was BMS output voltage LOW level was far from GND. I put 1Kohm between GND and BMS output pin.
BMS is SP15S020-P7S-40-B , firmware version is 22. BMS include 2 temp sensor ( one internal, one external)

the BMS_LEN_RESPONCE is not enough.

I've raised a patch to fix two major issues.

#16