8 years, 2 months ago.

Initialising and Filling a Character array with binary values

Got stuck, again :(

I need to send various command's as a set of binary characters through the Serial port. It woks as it should however I now want to split the function in two and select multiple lines of data and send it as below. The issue is obvious but I'm not sure how to specify the container and fill the data.

Also the value '49' if the 'for' loop is the total amount of characters I'm sending. Is there a way to calculate this similar to strlen. The next line of data has a different amount '37' so I need to change this. I can do it manually but would be better if it can be simply calculated.

Any suggestions?

Code snip

char data[100];

void GPS::init() {
     
     char data[49] = {181,98,6,49,32,0,0,1,0,0,50,0,0,0,1,0,0,0,1,0,0,0,0,0,0,128,153,153,153,25,0,0,0,0,239,0,0,0,223,100,181,98,6,49,1,0,0,56,229};
     sendUBS();
     char data[37] = {181,98,6,0,20,0,1,0,0,0,208,8,0,0,128,37,0,0,7,0,3,0,0,0,0,0,162,181,181,98,6,0,1,0,1,8,34};
     sendUBS();

}

void GPS::sendUBS() {
    
    for(int y = 0; y < 49; y++) {        
        gps.putc(data[y]);
    }
            
}

2 Answers

8 years, 2 months ago.

The strlen methods works by looking for a value of 0x00 in the string. That value indicates the end of a string and it is automatically inserted by the compiler when it sees a text string constant. The magic value 0x00 can be used in strings because it is not a valid character code and would never show up in a regular text string. In case of binary data you probably dont have a special value that could never show up as part of the actual payload. You can however use a special value as an escape sequence: select a special value, for example 0xFF. When that value shows up in the payload you must insert a second value of 0xFF so that it will be processed as regular value of 0xFF, when you want to indicate the end of the binary constant array you insert 0xFF and then you insert 0x00 for the next and final character value. The send methods scans the binary string, looks for 0xFF and inspects the next char to decide what needs to be done.

Alternative solution is to use the first entry in the constant string to store the length and calculate/insert that value manually.

void GPS::init() {
     
     const char data[] = {49,
     181,98,6,49,32,0,0,1,0,0,50,0,0,0,1,0,0,0,1,0,0,0,0,0,0,128,153,153,153,25,0,0,0,0,239,0,0,0,223,100,181,98,6,49,1,0,0,56,229};
     sendUBS((char *) data);

     const char data2[] = {37, 
     181,98,6,0,20,0,1,0,0,0,208,8,0,0,128,37,0,0,7,0,3,0,0,0,0,0,162,181,181,98,6,0,1,0,1,8,34};
     sendUBS((char *) data2);
}
 
void GPS::sendUBS(char *data) {
    
    for(int y = 1; y <= data[0]; y++) { 
        gps.putc(data[y]);
    }
            
}

Use the const keyword to make sure the compiler stores the strings in flash. You dont need to include the array size between the brackets in the array declarations.

Accepted Answer

Thank's Wim, that worked fine. Without thinking I was trying to fill the array with the data command for each setting I wanted to send. Realized I needed to load these in Flash anyway using different names and then send the relevant command.

posted by Paul Staron 14 Mar 2016
8 years, 2 months ago.

Hello, You can calculate the length of an array as

int size_of_array = sizeof(array)/sizeof(*array);


and then pass it to the sendUBS function

void GPS::init() {
    int legth;
     
     const char data1[] = {181,98,6,49,32,0,0,1,0,0,50,0,0,0,1,0,0,0,1,0,0,0,0,0,0,128,153,153,153,25,0,0,0,0,239,0,0,0,223,100,181,98,6,49,1,0,0,56,229};
     length = sizeof(data1)/sizeof(*data1);
     sendUBS((char*)data1, length);
     
     char data2[] = {181,98,6,0,20,0,1,0,0,0,208,8,0,0,128,37,0,0,7,0,3,0,0,0,0,0,162,181,181,98,6,0,1,0,1,8,34};
     length = sizeof(data2)/sizeof(*data2);
     sendUBS((char*)data2, length);
}
 
void GPS::sendUBS(char* array, int len) {
    
    for(int y = 0; y < len ; y++) {        
        gps.putc(array[y]);
    }
            
}


NOTE: Calculating the length inside the sendUSB function doesn't work. The size must be calculated before passing the pointer to function.

Thank you Zoltan, I used Wim's solution but great to have a different approach.

posted by Paul Staron 14 Mar 2016