Conversion from Hex to RGB

Hi guys, I am having a little trouble with my conversion from hex to RGB. I am currently using this code

for(int i = 0; i < 4; i++){
red[i] = hex[i] >> 16 ;
green[i] = (hex[i] & 0x00ff00) >> 8;
blue[i] = (hex[i] & 0x0000ff);
}

But if I input for exemple blue, white, blue, white. I will get the blue, white, purple, white. Any idea ?

Thanks !

1 Like

The conversion looks OK, but are all your arrays big enough ([4])?

1 Like

@tchinou1, you need to add a little more context. Is the RGB coded as 888 (8 bits for each color) or 565 or other format. If you explain what device or library you are using, it would help. :smile:

2 Likes

If you have a lot of 888 converting to do, you might like to consider this aproach :wink:

/* Types required for RGB-LED control */
struct ARGB_COLOR {
	byte B;  // blue  channel
	byte G;  // green channel
	byte R;  // red   channel
	byte A;  // alpha channel to indicate RGB.control true (!= 0) / false (== 0)
};

union COLOR {
	ARGB_COLOR argb;
	unsigned int value;
} color;

  // sample usage
  color.value = 0xFF123456; 
  RGB.control(color.argb.A);  // alpha channel used for RGB control true/false
  RGB.color(color.argb.R, color.argb.G, color.argb.B);
1 Like

Thanks guys for your answers, the hex value come from a webpage, I use HttpClient to get the data from the webpage. Usually I have 10 values to transfers, I just made a short version for the question. Once the value are converted, I send them to an Arduino uno. How can I know if I’m in 888 or in 565 ? I will try to clean up the code and post it after.

1 Like

If you have to think of this question, you might be in trouble, since there are lots of other possible formats too :wink:
https://en.wikipedia.org/wiki/BMP_file_format#RGB_video_subtypes

But you can easily “guess” the most likely ones
If you get 0x00FFFFFF for white you’re probably getting 24bit RGB 888 without alpha channel, if you have 0xFFFFFFFF you might have 32bit ARGB 8888 with alpha channel.
If you get 0xFFFF for white you’re getting 16bit (RGB 565 or aRGB a555 or ARGB 4444 or …).

1 Like

This is what I used to control a set of addressable LED from externally.

int setLEDrgbhex (String hex)
    {
        uint32_t rgb;
        Serial.println(hex);
        if (1 == sscanf (hex.c_str(), "%lx", &rgb) ) {
        colorWipe (rgb, 10);
        return 1337;
        }
        else {return -404; }
    }

Then I can send the HEX value via a spark.function and the conversion happens on the fly locally on the core.

2 Likes

Here is my code, I think there is not to much junk but if you have an idea to optimize the code feel free to tell me !

#include "application.h"
#include "HttpClient.h"
#include "jsmnSpark.h"


#define TOKEN_EQ(t, tok_start, tok_end, tok_type) \
((t).start == tok_start \
&& (t).end == tok_end  \
&& (t).type == (tok_type))

#define TOKEN_STRING(js, t, s) \
(strncmp(js+(t).start, s, (t).end - (t).start) == 0 \
&& strlen(s) == (t).end - (t).start)

#define TOKEN_PRINT(t) \

HttpClient http;

byte red[22];
byte green[22];
byte blue[22];

http_request_t request;
http_response_t response;
const char *js;
const char *js1;

unsigned long int js_value[45];
unsigned long int js_value_last[45];
int mode;
int mode_last;
int modif;
int on;
int rotation;
int rotation_order;
int rotation_time;
int aleatory_mode;
int mode_time;
int mood;
int mood_type;

String spark_id = Spark.deviceID();
String request_url = "/app/data.php?id=";


http_header_t headers[] = {
    { "Accept" , "*/*"},
    { NULL, NULL } // NOTE: Always terminate headers will NULL
};



void setup() {
    Serial.begin(9600);
    Serial1.begin(9600);
    request_url = request_url + "" + spark_id;
}

void loop() {
    modif = 0; 

    request.hostname = "luxontower.com";
    request.port = 80;
    request.path = request_url;
 	int i, r;
	jsmn_parser p;
	jsmntok_t tok[256];
	char obj[20];

    http.get(request, response, headers);
    Serial.println(response.body);
  js = response.body.c_str();


    nextTime = millis();


Serial.println(js);
    obj[0] = Serial.read();
	jsmn_init(&p);
	r = jsmn_parse(&p, js, tok, 256);
	if (r == JSMN_SUCCESS)
	    Serial.println("parsed successfuly");
	else {
	    Serial.println("parse failed");
	    return;
	}




int js_size = tok[1].size + 2;

	for (i = 3; i < 41; i++) {
		if (tok[i].type != JSMN_STRING)
		    Serial.println("error: expected string");
		else {
			strlcpy(obj, &js[tok[i].start], (tok[i].end - tok[i].start + 1));		      
			js_value[i] = strtol(obj,NULL,16); 
		}
	}

for (i=3;i<41;i++) {
if (js_value[i]!=js_value_last[i]) {
modif = 1; 
Serial.println(js_value[i]);
Serial.println(js_value_last[i]);

Serial.println("not equals");
}}

/*if(js_value[24]!=js_value_last[24] || js_value[26]!=js_value_last[26]){
modif = 1;
Serial.println("not equals");
}*/

if (modif == 1) {
  mode = js_value[24];
	on = js_value[26];
	rotation = js_value[28];
	rotation_order = js_value[30];
	rotation_time = js_value[32]/2.56;
	aleatory_mode =  js_value[34];
	mode_time =  js_value[36]/2.56;
    mood = js_value[38];
    mood_type = js_value[40];



    for(int i = 4; i < 23; i = i+2){
    red[i] = js_value[i] >> 16 ;
    green[i] = (js_value[i] & 0x00ff00) >> 8;
    blue[i] = (js_value[i] & 0x0000ff);
    }
    Serial.println(js_value[14]);
   //Conversion hex to RGB
    int var[39] = {
        red[4], green[4], blue[4],
        red[6], green[6], blue[6],
        red[6], green[8], blue[8],
        red[10], green[10], blue[10],
        red[12], green[12], blue[12],
        red[14], green[14], blue[14],
        red[16], green[16], blue[16],
        red[18], green[18], blue[18],
        red[20], green[20], blue[20],
        red[22], green[22], blue[22],
        mode, on, rotation, rotation_order, 
        rotation_time, aleatory_mode, mode_time,
        mood, mood_type
        };
        Serial.println("mood");
Serial.println(mood);

Serial.println("Sending values to arduino");
    for(int i = 0; i < 39; i++){
        Serial1.write (var[i]);    // send the number
        Serial.println(var[i]);
       // Serial.println (var[i]);
    }
Serial.println("Data sent");
for(i=3 ;i<41;i++) {
  js_value_last[i] = js_value[i];  
  }  

}


delay(10);

}

As in my first post, I think you’ve got the array sizes wrong.

e.g. byte red[22]; does not allow for the use of red[i] = js_value[i] >> 16; when i == 22.
And ... red[22], green[22], blue[22], ... will return values that are not within the array space.

1 Like

I changed it to 23 and I still get the same error. The error just happened with certain set of color and at the third color (I think, but I’m not sure that this happened only with blue). Exemple if I send this set of color (the first one is at the bottom)
I receive this: R1: 0 G1: 0 B1: 255 R2: 255 G2: 0 B2: 255 R3: 255 G3: 0 B3: 255 R4: 255 G4: 0 B4: 255 R5: 0 G5: 0 B5: 255 R6: 255 G6: 0 B6: 255 R7: 0 G7: 0 B7: 255 R8: 255 G8: 0 B8: 255 R9: 0 G9: 0 B9: 255 R10: 255 G10: 0 B10: 255

But the RGB3 is supposed to be R3: 0, G3: 0, B3: 255

Thanks guys ! :smile:

Maybe you should try to debug not only the final result but start debugging from the beginning.

Are you actually getting the correct data in, are you parsing it correctly, are you transfering the parsed data correctly, are you iteraring over your data correctly and only when all this goes OK you’ll have a correct output.

For debugging it might also be useful to provide a hardcoded test string to be parsed. That would also allow us to test your code. Without that we’d no way to test it due to lack of information and infrastructure.

Hey @tchinou1,

I did the same thing: taking a http request as a HEX String and convert it to 3 INTs.

String color = raw_response.substring(43+3+27,44+3+27+5);//the HEX color in the msg: RRGGBB
Serial.println(color);

String Tcolor;
int Rcolor;
int Gcolor;
int Bcolor;
int temp;
char C_color;

//HEX char to INT - Red color
C_color = color[0];
Rcolor = hexToDec(C_color,1);
C_color = color[1];
Rcolor = (hexToDec(C_color,0)) + Rcolor;
Serial.println(Rcolor);

//HEX char to INT - Green color
C_color = color[2];
Gcolor = hexToDec(C_color,1);
C_color = color[3];
Gcolor = (hexToDec(C_color,0)) + Gcolor;
Serial.println(Gcolor);

//HEX char to INT - Blue color
C_color = color[4];
Bcolor = hexToDec(C_color,1);
C_color = color[5];
Bcolor = (hexToDec(C_color,0)) + Bcolor;
Serial.println(Bcolor);

and

int hexToDec(char hexString,int x) {
  
  int decValue = 0;
  int tempvalue =0;
  
  if ((hexString != 'A') && (hexString != 'B') && (hexString != 'C') && (hexString != 'D') && (hexString != 'E') && (hexString != 'F')){
      
      int tempvalue = hexString - '0';
      if (x==1){
        decValue=tempvalue *16;
      } else {
          decValue=tempvalue + decValue;
      }
    }
    
    else {
        if (hexString == 'A'){
        tempvalue=10; } 
        if (hexString == 'B'){
          tempvalue=11; }
        if (hexString == 'C'){
          tempvalue=12; } 
        if (hexString == 'D'){
          tempvalue=13; } 
        if (hexString == 'E'){
        tempvalue=14; }
        if (hexString == 'F'){
          tempvalue=15; } 
        
        if (x==1){
        decValue=tempvalue *16;
      } else {
          decValue=tempvalue + decValue;
        }
    }

return decValue;
}

I’m not sure this is the best way but it’s working :grin:
good luck

For converting HEX strings to numeric datatype try out strtol(long int strtol (const char* str, char** endptr, int base);

1 Like

Hi guys, sorry for the delay, I wasn’t around lately. I think I found problem, It was a stupid miswriting ! I just receive the Photon and when I upload the code the Photon crash (flash red). I was able to isolate the problem down to this piece of code:

  for(int i = 2; i < 56; i = i+2){
    red[i] = js_value[i] >> 16 ;
    green[i] = (js_value[i] & 0x00ff00) >> 8;
    blue[i] = (js_value[i] & 0x0000ff);
   }

Any explanation/solution ?

Thanks guys !