6 years, 3 months ago.

Problem with decoding code rs232

Hi friends I have a some problem with my decoding,Sometimes I have gotten bad values with it. I got in buf[5]= 208 sometimes 0 why? and sometimes buffer[1] is getting T .

This is the code sending

sprintf(buf,"%d",throttle);

buf1[0] = 'T'; buf1[1] = buf[0]; buf1[2] = buf[1]; buf1[3] = buf[2]; buf1[4] = buf[3]; buf1[5] = buf[4]; buf1[6] = '\n';

HAL_UART_Transmit(&huart1, buf1, 7,1000);

This is receiving codes

TR_Receive(pData,buf,sizeof(pData)/sizeof(pData[0]),'T','\n');

data[0] = buf[1]; data[1] = buf[2]; data[2] = buf[3]; data[3] = buf[4]; data[4] = buf[5];

throttle = atoi(data);

void TR_Receive(char *rData,char *buffer,int8_t dim,char c1, char c2) { int8_t i=0,j=0,k=0,l=0,n,DIM;

n = dim-1; DIM = n+1;

while(rData[i]!=c1) { i++; }

while(rData[j]!=c2) { j++; }

while(i<DIM) { if(rData[DIM-1] == c2 || rData[0] == c1) break; buffer[l] = rData[i]; i++; l++;

}

while(j>-1) { if(rData[DIM-1] == c2 || rData[0] == c1) break; buffer[n] = rData[j]; n; j; } }

1 Answer

6 years, 3 months ago.

Hi,

Don't know that I have a solution, just questions and observations.

1) Why go all the way down to HAL_Uart_Transmit()? It's more common and easier to just use the higher level serial api, i.e. serial.printf();

2) The lack of proper string termination character '\0' catches my attention. But I can't say for sure it is causing a problem. Some string functions expect the string to have proper termination and could cause problems if it is missing. Something to keep an eye on.

3) Be sure to check the result of your sizeof math, that doesn't always give the answer one would expect and would cause issues if not right.

4) Your while loops are a little scary and rely on a precise condition to be met to leave them. Would be better to use for loops here with upper bound so you eventually leave them.

5) Should consider using strcat() function to combine buf and buf1. It's easier and probably overall more reliable for combining strings than manually doing it yourself everytime.

strcat(buf1,buf);

6) Overall Approach. A good strategy for sending data over a serial port is to use Tokens. You break your data into Fields using a separator character like a comma. Then you use the string Tokenize function strtok() to break the string apart into tokens for you. Then you can deal with each token. Let's say throttle is an int value 0 to 100. The string sent over the serial port looks like

"THROTTLE, 100"

Now you have one function on the receive end that checks for the token "THROTTLE" and handles it if it comes in. Becomes very easy to add more communication parameters this way. Here is a function that will break a buffer into tokens.

/** Parse buffer into Tokens
    Break into string Tokens via strtok using delimitors
    Strtok replaces the delimitor in buffer string with \0 to end the string
    All these pointers still point to the same buffer memory but with diff start addresses
    @param  buffer  Char Array containing string to Parse.  Function updates values.
    @param  tokens  Char Array of type char pointer. Function updates values.
*/
static void parseTokens(char buffer[], char *tokens[]) {
    char *tok;       // temp token pointer
    int   index = 0; // index to tokens
    // Any of these chars are treated as delimitors
    tok = strtok(buffer, " ,\n");
    while (tok != NULL) {
        // Store Pointers
        tokens[index++] = tok;
        tok             = strtok(NULL, " ,\n");
    }
}

Then you call a series of functions to handle various commands. For example this one if token[0] is "FIRMWARE_GET" it responds with a string like "FIRMWARE,1.0.1".

int firmwareCommandHandler(char buffer[], char *tokens[]) {
    if (strstr(tokens[0], "FIRMWARE_GET")) {
        printf("FIRMWARE,%s", VERSION);
    }
}