0

I have a value for led brightness that is stored as an unsigned char (0-255)

unsigned char* colors[3];
colors[0] = 255;
colors[1] = 0;
colors[2] = 0;

I want to multiply a brightness percentage to that value.

float percent = 0.5;
auto red_brightness = colors[0] * percent

Since colors[0] is of type char and percent is of type float. It gives error Invalid operands of types 'unsigned char*' and 'float' to binary 'operator*'

unsigned char brightness;
float percent;
unsigned char* colors[3];

void setup() {
  Serial.begin(9600);
  colors[0] = 255;
  colors[1] = 0;
  colors[2] = 0;
}

void loop() {
    brightness = 127;
    float percent = (float)brightness / 255;
    float newRed = (float)colors[0] * percent;
    
    Serial.println(percent);
    Serial.print("red ");
    Serial.print(newRed);
    Serial.println("");
    delay(1000);
}

How can I multiply colors[0] (255) by 0.5 to get 127?


What I've tried

  1. Cast colors[0] to a float or int
    # invalid cast from type 'unsigned char' to type 'float'

    float newRed = (float)colors[0] * percent;
  1. strtod

Using this conversion website, I've tried converting like so:

    float tempColor = (float)strtod(colors[0],NULL);
    float newRed = tempColor * percent;

While this compiles, it always returns 0 (not 127 like I expect)

unsigned char brightness;
float percent;
unsigned char* colors[3];

void setup() {
  Serial.begin(9600);
  colors[0] = 255;
}

void loop() {
    brightness = 127;
    float percent = (float)brightness / 255;
    float tempColor = (float)strtod(colors[0],NULL); // <- returns 0.00

    Serial.print("tempColor");
    Serial.println(tempColor);
    delay(1000);
}

How can I multiply 255 by 0.5 to get ~127 ?


Solution

Thanks to the pointer by st2000 and this sparkfun article on datatypes

I avoided floating point and char arrays and converted everything to byte and now my code works as expected. Thank you

byte brightness;
byte percent;
byte colors[3];

void setup() {
  Serial.begin(9600);
  colors[0] = 255;
}
void loop() {
      percent = 50;
      auto foobar = colors[0] * percent / 100;
      Serial.print("foobar: ");
      Serial.println(foobar);
11:12:19.833 -> foobar: 127

2 Answers 2

1

Using "floats" is expensive both in required space and execution time. Consider avoiding the problem entirely and use uint8_t or byte for everything.

Then just assume

percent = 50; 

... is 50%. Then try:

tempColor =  colors[0] * percent / 100;

... where all variables are of type uint8_t or byte.

1
  • @spuder, please follow up to let us know if the above code suggestion works. I think C uses type int for intermediate values in which case the worst expected case (255*100) should not exceed the limits of a type int variable. Otherwise casting one of the variables to a type uint16_t would likely make the code more portable / less likely to break.
    – st2000
    Commented Aug 14, 2022 at 17:19
4

You wrote:

I have an led brightness that is stored as an unsigned char (0-255)

unsigned char* colors[3];

This is not an array of unsigned char, this is an array of pointers to unsigned char. If you instead write

unsigned char colors[3];

Everything should work as expected.

But then, st2000 has very good advice on how to avoid expensive floating point operations.

1
  • Oooo, good catch @edgar!
    – st2000
    Commented Aug 14, 2022 at 20:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.