Go Down

Topic: How to use communication protocol for a electric car with uart serial rs232 (Read 262 times) previous topic - next topic

Hitzbleck

Hi guys,

At the moment i'm busy with a project to make a interface for a electric car. I already have a nice interface. Only the problem i have is to read the information from the vehicle management system(VMS) of the electric car. This VMS is spamming data through a uart-rs232 connection. I already succeeded to send data to the car to start and stop charging but i'm stuck with the data spamming. The data is send in hexadecimal code. The protocol of payload 0 is

Payload ID 0:

AC 13 301B 00 003436 0F5B0F6E0F6A001F0065003E5E

0xAC: start of message

0x13: number of bytes to follow

0x301B: CRC-16-CCITT checksum

0x00: payload ID (in dit geval 0 = L3PAYLOAD_ID_BMS_SUMMARY)

0x003436: timestamp ( x 10 ms) from the start of the system 0x003436 * 10 ms = 13366 * 10 ms = 133.66 sec

0x0F5B: v_min = 3931 mV =lowest voltage of the battery cells
0x0F6E: v_max = 3950 mV = highest voltage ofthe battery cells
0x0F6A: v_avg = 3946 mV =avarge voltage of all the cells


0x001F: t_min = 31, in C temp of the coldest cell
0x0065: t_max = 101, in C temp of the warmest cell
0x003E: t_avg = 62 = Averge temp
0x5E: soc_percent = 94 (state of charge in percent)


The VMS of the car is sending more data. But i only need this payload at the moment.
I alreay read a lot about serial protocols but i'm still don't get it. Please give me a start or a hint where to search.

Great thanks


Robin2

The VMS of the car is sending more data. But i only need this payload at the moment.
I alreay read a lot about serial protocols but i'm still don't get it. Please give me a start or a hint where to search.
I don't know what it is that you want help with. You seem to know how to interpret the data.

If the problem is that you don't know how to receive the message then have a look at the third example in Serial Input Basics

It's not actually written to do what you need because it expects an end-marker as well as a start-marker. But it should not be too difficult to modify the code to get the number of bytes from the byte that follows the start marker and then count the next N bytes until the full message is received - rather than waiting for an end-marker.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Hitzbleck

Thanks R,

The problem is indeed to recieve and filter the message and make the payloads usefull in realtime. So i can connect the data to the interface. I wil start with the serial input basics. Another thanks!!!


Robin2

I forgot to say that the code in my tutorial assumes you are receiving ascii characters so it uses the char data type in several places. You should change that to byte.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Hitzbleck

The tutorial was a great help. I succeeded to use the startmarker and filter the code. Only i'm not a champion in programming. So i still have two problem now. First i want to use the start of message and the number of bytes both as the startmarker i tryed to put them in a array but it didn't worked. Next i tryed different ways to count for the 19 bytes for the endmarker. But here i didn't succeeded eigther. Tommorrow another day for succes but if you guys have a tip great thanks.



AC 13 301B 00 003436 0F5B0F6E0F6A001F0065003E5E

0xAC: start of message

0x13: number of bytes to follow


Code: [Select]

// Example 6 - Receiving binary data

const byte numBytes = 32;
byte receivedBytes[numBytes];
byte numReceived = 0;

boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvBytesWithStartEndMarkers();
    showNewData();
}

void recvBytesWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    byte startMarker[] = {0xAC, 0x13};
    byte endCount = 0;
    byte rb;
   

    while (Serial.available() > 0 && newData == false) {
        rb = Serial.read();

        if (recvInProgress == true)
        {
            if (endCount != 19)
            {
                receivedBytes[ndx] = endCount;
                ndx++;
                endCount++;
                if (ndx >= numBytes)
                {
                    ndx = numBytes - 1;
                }
            }
            else {
                receivedBytes[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                numReceived = ndx;  // save the number for use when printing
                ndx = 0;
                newData = true;
            }
        }

        else if (rb == sizeof(startMarker))
       
        {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in (HEX values)... ");
        for (byte n = 0; n < numReceived; n++) {
            Serial.print(receivedBytes[n], HEX);
            Serial.print(' ');
        }
        Serial.println();
        newData = false;
    }
}

Robin2

There is a lot wrong with your program - some of it might be due to a lack of programming knowledge but a good bit is due to faulty logic.

For example you can't have two start markers - it just makes no sense.

Have a look at this version. I think it might work but I have not tested it. If it does not work it won't need any major changes to fix it.

Code: [Select]

// Example XX - Receiving binary data with start marker and message length

const byte numBytes = 32;
byte receivedBytes[numBytes];
byte numReceived = 0;

boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvBytesWithStartMarkerAndCount();
    showNewData();
}

void recvBytesWithStartMarkerAndCount() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    byte startMarker= 0xAC;
    static byte messageLen = 0;
    byte rb;
  

    while (Serial.available() > 0 && newData == false) {
        rb = Serial.read();

        if (recvInProgress == true)  {
            
            if (messageLen == 0) {
                messageLen = rb;
            }
            
            else {
                receivedBytes[ndx] = rb;
                ndx++;
                
                if (ndx >= messageLen) {
                    receivedBytes[ndx] = '\0'; // terminate the string
                    recvInProgress = false;
                    numReceived = ndx;  // save the number for use when printing
                    ndx = 0;
                    messageLen = 0;
                    newData = true;
                }
            }
        }

        else if (rb == sizeof(startMarker)) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in (HEX values)... ");
        for (byte n = 0; n < numReceived; n++) {
            Serial.print(receivedBytes[n], HEX);
            Serial.print(' ');
        }
        Serial.println();
        newData = false;
    }
}


...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up