Be forewarned: I am either an idiot or overthinking this.

Be forewarned: I am either an idiot or overthinking this. Thank you in advance for your forbearance.

How do I convert an int16_t into a uint8_t?

Specifically, I want to do something like this:

uint16_t i = 0;
for (;:wink: {
leds[x] = CHSV(colour, sin8(i), 255);
i++;
}

i.e., fade the saturation of a pixel in and out in a sine wave pattern. The input to sin8() is an unsigned 16 bit int (with 0 representing 0 radians and 65535 representing how many radians?) and the output is a signed 16 bit int, which I want to turn into a uint8_t to plug into the CHSV’s saturation. Will simply casting it do what I want—turning -32767 into 0 and 32767 into 255?

Omg I am so dumb lol

sin16 effectively takes a value from 0-2 radians, expressed fractionally as 0-65535 (e.g. 32768 would be ā€œ1 radianā€) - it’s a way to get fractional values without using floating point.

As for the output, what you can do is: ((sin16(i) >> 8) + 128) & 0xFF

What that’s doing is effectively dividing the output of sin16 by 256, which will give you a value from -128 to 127, adding 128 shifting you to 0 to 255, and then masking off the bits (just to be sure, that last bit may not be entirely necessary, actually - head’s a bit unclear today).

Also, not an idiot!

Slightly idiot—in my day job I operate at so much a higher level I’ve lost the ability to reason through such bit-twiddling :-).

I was originally going the other way around and trying to add 32767 to the output of sin8(), storing the output in a long, then shifting back down to a uint8_t, I’m not sure what I was doing wrong but I was losing some precision somewhere. This is obviously the way to do it.

Is there a call for trig methods that natively return uint8_t values? It’s all I ever seem to want to use.

ā€œusin8(…)ā€ is on my list for soon-version of the library.

Because ditto.