As the title says I would like to convert a String into an unsigned char array. Here are some details:
With a HTTPClient I am reading the body of a String, e.g.
String varString "0XFF0XFF0XFF";
No I would like to convert it into the following:
unsigned char charVar[] = {0Xff, 0XFF, 0XFF}
How can this be done?
Background:
The incoming String is the data of an black and white image. 8 pixels of the image are transformed to a 8 bit binary number, e.g. 8 white pixels means 11111111, which is 255 in decimal numbers and FF in hex numbers. Therefore we get the first 4 characters of the String "0XFF".
In case it is easier to build the unsigned char array with another String representative, e.g. "255255255" or "FFFFFF", then this will be done.
In case it is easier to build the unsigned char array with another String representative, e.g. "255255255" or "FFFFFF", then this will be done.
if you were to use this approach and your numbers were 22 212 and 17, your String would hold 2221217 but when you get that you have no clue if this is not 222 121 and 7 or 2 221 and 217...
--> you do need separators like your 0x
but not sure why you want to go through a String in the first place.. if you are analyzing an image, don't you have numbers in the first place?
if you were to keep the string approach, first don't use the String class but c-Strings and to make your like simple, then add a space in between the numbers and you can use the strtol() function to parse the data
If you want to keep using the "String varString "0XFF0XFF0XFF";" protocol something like this can be used to parse the bytes out:
String
sSample = "0x5a0xa50x030x040x050xFF0x7F0x0f0x01";
char
*pszStr;
void setup()
{
byte
val,
idx;
char
hi, lo;
Serial.begin(9600);
while(!Serial);
sSample.toUpperCase();
pszStr = (byte *)malloc( sSample.length() + 2 );
if( pszStr != NULL )
sSample.getBytes( pszStr, sSample.length()+1 );
idx = 0;
while(1)
{
if( *(pszStr+idx) == 0 )
break;
else
{
if( *(pszStr+idx) == '0' && *(pszStr+idx+1) == 'X' )
{
//move past "0X"
idx+=2;
//grab next two characters and convert to binary
hi = *(pszStr+idx++);
lo = *(pszStr+idx++);
Serial.print(hi); Serial.print(lo); Serial.print(" ");
hi = ConvASCIItoBin(hi);
lo = ConvASCIItoBin(lo);
val = (hi << 4) | lo;
Serial.println( val );
}
else
idx++;
}
}while( *(pszStr+idx) != 0 );
Serial.println("Finished.");
free(pszStr);
}//setup
byte ConvASCIItoBin( byte val )
{
if( val >= '0' && val <= '9' )
val -= '0';
else if( val >= 'A' && val <= 'F' )
val = val - 'A' + 10;
else
val = 0;
return val;
}
void loop()
{
}
If you know the length of string will always be less than some arbitrary value you can create a char array one or two bytes bigger than that and save the use of malloc() and free().
Blackfin:
If you want to keep using the "String varString "0XFF0XFF0XFF";" protocol something like this can be used to parse the bytes out
...
If you know the length of string will always be less than some arbitrary value you can create a char array one or two bytes bigger than that and save the use of malloc() and free().
@Blackfin why do you duplicate the buffer whilst you could just go through the String back end buffer using c_str() ?
For getting the image data I am calling a webservice with a code like
HTTPClient http;
http.begin(URL); //HTTP
String payload = http.getString(); // reading the body
That is the reason why I am using a String.
As I mentioned I can change the data, which is send by the webservice.
What is required is an unsigned char array. Pay attention, that it has to be UNSIGNED.
I know the length of the string, which is sent by the webservice. In the above mentioned example ("0XFF0XFF0XFF")
How is the string created?
I am reading a black and white image. The pixels are split into blocks of 8 pixels and every pixel is represented by 0 for black and 1 for white. For 4 white pixels and 4 black pixels I get 11110000 as a binary number, which is transformed into a hex value: (11110000)_2 = (F0)_16. This hex number gets the prefix 0X and then all the 4-characters strings are connected.
the question is why do you go the extra step of transforming your data in ASCII? why don't you just send the byte value as it is ie if you read 111100002 just stream out that value (24010) which fits in 1 byte instead of send "0xF0" in ASCII which fits on 4 bytes...
then there is no decode needed and it's 4 times less data to carry around...
My intention was that most of the work should be done by the webservice.
Example:
INPUT: String message = "0XFF0XFF0XFF";
PROCESSING Loop over message do { unsigned char myChar = "0XFF";} (maybe with a cast or whatever)
OUTPUT unsigned char myCharArray[] = {0XFF, 0XFF, 0XFF}
In best case there would have been some kind of autoboxing.
Finally it was not necessary to convert the String into an unsigned char array.
The String contains concatenated 2 digit hex numbers, e.g. FF010F. These hex numbers are converted into 8 bit binary numbers, which just solved my issues.