UART not working in Polling Mode

Hello,
I am new on Arduino Boards.
I am using "Daly 16s 60V 50A" BMS. This is communicative BMS which supports CAN/485, UART. In this BMS first we have to send request to BMS and BMS reply.

In this code, I am sending only 7 command to BMS and BMS replying to me.

Problems :-

  1. This code is running once only then stop.
  2. When I does not use "send_msg6()" so this is working fine.
Msg1 = A5 40 90 08 00 00 00 00 00 00 00 00 7D 
rply = A5 01 90 08 02 7B 00 00 75 30 03 C1 24

In this I am sending 10 messages to BMS and BMS replying. These are commands.

Msg1 = A5 40 90 08 00 00 00 00 00 00 00 00 7D 
Msg2 = A5 40 91 08 00 00 00 00 00 00 00 00 7E
Msg3 = A5 40 92 08 00 00 00 00 00 00 00 00 7F
Msg4 = A5 40 93 08 00 00 00 00 00 00 00 00 80
Msg5 = A5 40 94 08 00 00 00 00 00 00 00 00 81
Msg6 = A5 40 95 08 00 00 00 00 00 00 00 00 82
Msg7 = A5 40 96 08 00 00 00 00 00 00 00 00 83
Msg8 = A5 40 97 08 00 00 00 00 00 00 00 00 84
Msg9 = A5 40 98 08 00 00 00 00 00 00 00 00 85
Msg10 = A5 40 D8 08 00 00 00 00 00 00 00 00 C5

Here is code :-

byte receive_data[800];
byte receive_decode[8];

uint16_t pressure = 0;
uint16_t acquisition = 0;
uint16_t current = 0;
uint16_t soc = 0;

uint16_t max_mono_V = 0;
uint8_t max_unitV_cellN = 0;
uint16_t mini_mono_V = 0;
uint8_t mini_unitV_cellN = 0;

int16_t max_mono_T = 0;
uint16_t max_temp_cellN = 0;
int16_t min_mono_T = 0;
uint16_t min_temp_cellN = 0;

uint8_t charge_discharge = 0;
uint8_t charge_MOS_STUS = 0;
uint8_t dischage_MOS_STUS = 0;
uint8_t BMS_life = 0;
uint32_t residual_capacity = 0;

uint8_t battery_string = 0;
uint8_t temperature = 0;
uint8_t charger_STUS = 0;
uint8_t load_STUS = 0;
uint16_t charge_discharge_cycle = 0;
boolean DI1 = 0, DI2 = 0, DI3 = 0, DI4 = 0;
boolean DO1 = 0, DO2 = 0, DO3 = 0, DO4 = 0;

uint16_t vCells_1_to_16[17] = {0};

uint8_t mono_temp = 0;


union
{
  struct {
    bool bit7: 1;
    bool bit6: 1;
    bool bit5: 1;
    bool bit4: 1;
    bool bit3: 1;
    bool bit2: 1;
    bool bit1: 1;
    bool bit0: 1;
  } fields;
  uint8_t val;
} State;


void send_msg1() {

  byte message1[] = {0xA5, 0x40, 0x90, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D};
  for (uint8_t i = 0; i < sizeof(message1); i++)
  {
    Serial.write(message1[i]);
  }
}

void send_msg2() {

  byte message2[] = {0xA5, 0x40, 0x91, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E};
  for (uint8_t i = 0; i < sizeof(message2); i++)
  {
    Serial.write(message2[i]);
  }
}

void send_msg3() {

  byte message3[] = {0xA5, 0x40, 0x92, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F};
  for (uint8_t i = 0; i < sizeof(message3); i++)
  {
    Serial.write(message3[i]);
  }
}

void send_msg4() {

  byte message4[] = {0xA5, 0x40, 0x93, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};
  for (uint8_t i = 0; i < sizeof(message4); i++)
  {
    Serial.write(message4[i]);
  }
}

void send_msg5() {

  byte message5[] = {0xA5, 0x40, 0x94, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81};
  for (uint8_t i = 0; i < sizeof(message5); i++)
  {
    Serial.write(message5[i]);
  }
}

void send_msg6() {

  byte message8[] = {0xA5, 0x40, 0x95, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82};
  for (uint8_t i = 0; i < sizeof(message8); i++)
  {
    Serial.write(message8[i]);
  }
}

void send_msg7() {

  byte message7[] = {0xA5, 0x40, 0x96, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83};
  for (uint8_t i = 0; i < sizeof(message7); i++)
  {
    Serial.write(message7[i]);
  }
}



void setup() {

  Serial.begin(9600);
  Serial.println("Ready");
  send_msg1();
}

void loop() {

  if (Serial.available())
  {
    Serial.readBytesUntil('\n', receive_data, 13);

    switch (receive_data[2])
    {
      case (0x90):
        memcpy (receive_decode, receive_data + 4, 8);

        pressure = (receive_decode[0] << 8) | receive_decode[1];
        acquisition = (receive_decode[2] << 8) | receive_decode[3];
        current = (receive_decode[4] << 8) | receive_decode[5];
        soc = (receive_decode[6] << 8) | receive_decode[7];

        pressure = pressure * 0.1;
        current = current / 10;
        soc = soc * 0.1;

        Serial.print("0X90: ");
        Serial.print(pressure);
        Serial.print(",");
        Serial.print(acquisition);
        Serial.print(",");
        Serial.print(current);
        Serial.print(",");
        Serial.print(soc);
        Serial.println(" ");

        delay(20);
        send_msg2();
        break;


      case (0x91):
        memcpy (receive_decode, receive_data + 4, 8);

        max_mono_V = (receive_decode[0] << 8) | receive_decode[1];
        max_unitV_cellN = receive_decode[2];
        mini_mono_V = (receive_decode[3] << 8) | receive_decode[4];
        mini_unitV_cellN = receive_decode[5];

        Serial.print("0X91: ");
        Serial.print(max_mono_V);
        Serial.print(",");
        Serial.print(max_unitV_cellN);
        Serial.print(",");
        Serial.print(mini_mono_V);
        Serial.print(",");
        Serial.print(mini_unitV_cellN);
        Serial.println(" ");


        delay(20);
        send_msg3();
        break;

      case (0x92):
        memcpy (receive_decode, receive_data + 4, 8);

        max_mono_T = receive_decode[0];
        max_temp_cellN = receive_decode[1];
        min_mono_T = receive_decode[2];
        min_temp_cellN = receive_decode[3];
        max_mono_T = max_mono_T - 40;
        min_mono_T = min_mono_T - 40;

        Serial.print("0X92: ");
        Serial.print(max_mono_T);
        Serial.print(",");
        Serial.print(max_temp_cellN);
        Serial.print(",");
        Serial.print(min_mono_T);
        Serial.print(",");
        Serial.print(min_temp_cellN);
        Serial.println(" ");


        delay(20);
        send_msg4();
        break;

      case (0x93):
        memcpy (receive_decode, receive_data + 4, 8);

        charge_discharge = receive_decode[0];
        charge_MOS_STUS =  receive_decode[1];
        dischage_MOS_STUS =  receive_decode[2];
        BMS_life =  receive_decode[3];
        //residual_capacity = ((receive_decode[4] << 24) | (receive_decode[5] << 16)) | ((receive_decode[6] << 8) | (receive_decode[7]));
        ///Serial.println(((receive_decode[4] << 24) | (receive_decode[5] << 16)));

        //uint16_t myVar = ((receive_decode[6] << 8) | (receive_decode[7]));

        Serial.print("0X93: ");
        Serial.print(charge_discharge);
        Serial.print(",");
        Serial.print(charge_MOS_STUS);
        Serial.print(",");
        Serial.print(dischage_MOS_STUS);
        Serial.print(",");
        Serial.print(BMS_life);
        Serial.println(",");
        //Serial.println(myVar);


        delay(20);
        send_msg5();
        break;

      case (0x94):
        memcpy (receive_decode, receive_data + 4, 8);

        battery_string = receive_decode[0];
        temperature = receive_decode[1];
        charger_STUS = receive_decode[2];
        load_STUS = receive_decode[3];
        State.val = receive_decode[4];

        DI1 = State.fields.bit0;
        DI2 = State.fields.bit1;
        DI3 = State.fields.bit2;
        DI4 = State.fields.bit3;
        DO1 = State.fields.bit4;
        DO2 = State.fields.bit5;
        DO3 = State.fields.bit6;
        DO4 = State.fields.bit7;

        charge_discharge_cycle = (receive_decode[5] << 8) | receive_decode[6];

        Serial.print("0X94: ");
        Serial.print(battery_string);
        Serial.print(", ");
        Serial.print(temperature);
        Serial.print(", ");
        Serial.print(charger_STUS);
        Serial.print(", ");
        Serial.print(load_STUS);
        Serial.print(", ");
        Serial.print("(");
        Serial.print(DI1);
        Serial.print(", ");
        Serial.print(DI2);
        Serial.print(", ");
        Serial.print(DI3);
        Serial.print(", ");
        Serial.print(DI4);
        Serial.print(", ");
        Serial.print(DO1);
        Serial.print(", ");
        Serial.print(DO2);
        Serial.print(", ");
        Serial.print(DO3);
        Serial.print(", ");
        Serial.print(DO4);
        Serial.print(")");
        Serial.print(", ");
        Serial.println(charge_discharge_cycle);

        delay(20);
        send_msg6();
        break;

      case (0x95):

        memcpy(receive_decode, receive_data + 4, 8);
        uint8_t voltage_flag = 0;

        if (receive_decode[0] == 0x01)
        {
          vCells_1_to_16[0]  = (receive_decode[1] << 8) | receive_decode[2];
          vCells_1_to_16[1]  = (receive_decode[3] << 8) | receive_decode[4];
          vCells_1_to_16[2]  = (receive_decode[5] << 8) | receive_decode[6];
        }
        else if (receive_decode[0] == 0x02)
        {
          vCells_1_to_16[3]  = (receive_decode[1] << 8) | receive_decode[2];
          vCells_1_to_16[4]  = (receive_decode[3] << 8) | receive_decode[4];
          vCells_1_to_16[5]  = (receive_decode[5] << 8) | receive_decode[6];
        }
        else if (receive_decode[0] == 0x03)
        {
          vCells_1_to_16[6]  = (receive_decode[1] << 8) | receive_decode[2];
          vCells_1_to_16[7]  = (receive_decode[3] << 8) | receive_decode[4];
          vCells_1_to_16[8]  = (receive_decode[5] << 8) | receive_decode[6];
        }
        else if (receive_decode[0] == 0x04)
        {

          vCells_1_to_16[9]  = (receive_decode[1] << 8) | receive_decode[2];
          vCells_1_to_16[10]  = (receive_decode[3] << 8) | receive_decode[4];
          vCells_1_to_16[11]  = (receive_decode[5] << 8) | receive_decode[6];
        }
        else if (receive_decode[0] == 0x05)
        {
          vCells_1_to_16[12]  = (receive_decode[1] << 8) | receive_decode[2];
          vCells_1_to_16[13]  = (receive_decode[3] << 8) | receive_decode[4];
          vCells_1_to_16[14]  = (receive_decode[5] << 8) | receive_decode[6];
        }
        else if (receive_decode[0] == 0x06)
        {
          vCells_1_to_16[15]  = (receive_decode[1] << 8) | receive_decode[2];
          voltage_flag = 1;
        }

        if (voltage_flag) {
          for (byte i = 0; i < 16 ; i++)
          {
            Serial.print(vCells_1_to_16[i]);
            Serial.print(",");
          }
          voltage_flag = 0;
          delay(20);
          send_msg7();
        }
        break;

      case (0x96):
        Serial.println("MSG = 0x96");
        memcpy(receive_decode, receive_data + 4, 8);

        if (receive_decode[0] == 0x01)
        {
          //        mono_temp = receive_decode[0];
          //        mono_temp = mono_temp - 40;
          //        Serial.println(mono_temp,HEX);
          for (uint8_t i = 0; i < sizeof(receive_decode); i++)
          {
            Serial.print(receive_decode[i]);
          }
        }

        else if (receive_decode[0] == 0x02)
        {
          for (uint8_t i = 0; i < sizeof(receive_decode); i++)
          {
            Serial.print(receive_decode[i]);
          }
        }
        delay(20);
        send_msg1();
        break;
    }

  }

}```

Start by putting the messages in a 2 dimensional array so that they can be sent without the need for 10 separate functions. If nothing else this will reduce the size of the sketch

Which Arduino board are you using?

Do you have a user manual for it?

How do you tell it which interface you are using.

Looking at your code, I assume it's not the CAN or RS485 interface you are trying to use.

How have you connected the Arduino and the BMS?

I am using Arduino UNO board.
Connections:
RX>TX
TX>RX
GND=GND

Part 4_ Daly RS485+UART Protocol.pdf (269.2 KB)

The hardware UART on the UNO is pretty much dedicated to communicating with the USB-serial interface.

As you require 9600 baud, I would suggest one of the software serial port libraries. My personal preference is for AltSoftSerial:

It will help you to initially reduce your code down to sending just 1 message and receiving a reply. Once you get that working, then expand your code to included the additional messages using the suggestion from @UKHeliBob.

There is no '\n' in the protocol. This will cause a problem if any byte in the reply message is 0x10 (Newline). I suspect your "Message 6" has a 0x10 in the data somewhere.

Oops. Make that 0x0A (decimal 10) and not 0x10 (decimal 16) as pointed out below.

ASCII code for Newline character is:
0x10? (you did typo mistake)

I am receiving these data:-
Received_Data

I see nothing.
Please try again

I can see it; unless you're referring to the fact that it's an image and not text as normal people use so others can easily copy and paste :wink:

image

I hope you can see the image that I posted.

I can see both now whereas originally I could not see the image posted by @gauravkr

Msg1 = A5 40 90 08 00 00 00 00 00 00 00 00 7D 
rply = A5 01 90 08 02 7B 00 00 75 30 03 C1 24

Msg2 = A5 40 91 08 00 00 00 00 00 00 00 00 7E
rply = A5 01 91 08 0F 4E 04 0F 32 01 03 A7 8C

Msg3 = A5 40 92 08 00 00 00 00 00 00 00 00 7F
rply = A5 01 92 08 44 01 44 01 32 01 03 A7 A7

Msg4 = A5 40 93 08 00 00 00 00 00 00 00 00 80
rply = A5 01 93 08 00 01 01 2D 00 00 83 7C 6F

Msg5 = A5 40 94 08 00 00 00 00 00 00 00 00 81
rply = A5 01 94 08 10 01 00 00 02 00 03 7C D4

Msg6 = A5 40 95 08 00 00 00 00 00 00 00 00 82
rply = A5 01 95 08 01 0F 32 0F 3C 0F 42 7C 9D
rply = A5 01 95 08 02 0F 4E 0F 4C 0F 44 7C CC
rply = A5 01 95 08 03 0F 46 0F 32 0F 37 7C 9E
rply = A5 01 95 08 04 0F 42 0F 38 0F 44 7C AE
rply = A5 01 95 08 05 0F 45 0F 45 0F 4A 7C C5
rply = A5 01 95 08 06 0F 32 0F 45 0F 4A 7C B3

Msg7 = A5 40 96 08 00 00 00 00 00 00 00 00 83
rply = A5 40 96 08 01 44 00 00 00 00 00 00 89
rply = A5 40 96 08 02 00 00 00 00 00 00 00 46

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.