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
asked Aug 14, 2022 at 16:42

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.

answered Aug 14, 2022 at 16:59
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. 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.

answered Aug 14, 2022 at 17:26
1
  • Oooo, good catch @edgar! Commented Aug 14, 2022 at 20:02

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.