Hi,
I've got a problem with a product of 2 uint8_t variables.
If I do this:
uint8_t val = 255;
uint8_t sat = 255;
uint16_t output = val*sat/120;
the result of output is 'strange' at best, definitely too big. It should be around 540 something, but ends up close to 0xFFFF. Using brackets around (val*sat) to reduce rounding errors is futile as well.
Changing the code to this helps, WHY ?
uint8_t val = 255;
uint8_t sat = 255;
uint16_t product = val*sat;
uint16_t output = product/120;
The actual code is this:
void
set_led_hsv (uint8_t led, uint16_t hue, uint8_t sat, uint8_t val)
{
/* BETA */
/* finally thrown out all of the float stuff and replaced with uint16_t
*
* hue: 0-->360 (hue, color)
* sat: 0-->255 (saturation)
* val: 0-->255 (value, brightness)
*
*/
hue = hue % 360;
uint8_t sector = hue / 60;
uint8_t rel_pos = hue - (sector*60);
uint16_t const mmd = 255*255; /* maximum modulation depth */
uint16_t top = val*255;
uint16_t bottom = val*(255-sat); /* (val*255) - (val*255)*(sat/255) */
uint16_t mod_depth = val*sat;
uint16_t slope = mod_depth/120; /* dy/dx = (top-bottom)/(2*60) */
uint16_t a = bottom + slope*rel_pos;
uint16_t b = bottom + mod_depth/2 + slope*rel_pos;
uint16_t c = top - slope*rel_pos;
uint16_t d = top - mod_depth/2 - slope*rel_pos;
Serial.print("hue: ");
Serial.println(hue,DEC);
Serial.print("sat: ");
Serial.println(sat,DEC);
Serial.print("val: ");
Serial.println(val,DEC);
Serial.print("sector: ");
Serial.println(sector,DEC);
Serial.print("rel_pos: ");
Serial.println(rel_pos,DEC);
Serial.print("top: ");
Serial.println(top,DEC);
Serial.print("bottom: ");
Serial.println(bottom,DEC);
Serial.print("slope: ");
Serial.println(slope,DEC);
Serial.print("a: ");
Serial.println(a,DEC);
Serial.print("b: ");
Serial.println(b,DEC);
Serial.print("c: ");
Serial.println(c,DEC);
Serial.print("d: ");
Serial.println(d,DEC);
uint16_t R, G, B;
if (sector == 0)
{
R = c;
G = a;
B = 0;
}
else if (sector == 1)
{
R = d;
G = b;
B = 0;
}
else if (sector == 2)
{
R = 0;
G = c;
B = a;
}
else if (sector == 3)
{
R = 0;
G = d;
B = b;
}
else if (sector == 4)
{
R = a;
G = 0;
B = c;
}
else
{
R = b;
G = 0;
B = d;
}
uint16_t scale_factor = mmd / __max_brightness;
R = (uint8_t) (R / scale_factor);
G = (uint8_t) (G / scale_factor);
B = (uint8_t) (B / scale_factor);
set_led_rgb (led, R, G, B);
}
This function is used to convert HSV color space to RGB.