#include #include "rgbled.h" #include "hsv2rgb.h" tinyNeoPixel rgb = tinyNeoPixel(RGB_COUNT, PIN_PA1, NEO_GRB, rgbled); uint8_t rgbp_rainbow(uint8_t init); uint8_t (*rgb_program[1])(uint8_t) = { rgbp_rainbow }; #define RGB_COUNT 5 uint8_t rgbled[3 * RGB_COUNT]; // configures and enables the 50Hz timer interrupt that is used for RGB program updates void conf_rgb_timer() { // this timer will run at half speed. // so 8MHz / 2 (prescale) / 1 (CLK_PER) = 4MHz // this will allow a full cycle time of ~61Hz. _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0); // disable CLK_PER divider disable_rgb_timer(); TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc; // prescale timer to run at half speed TCB0.CCMP = 0xffff; // count to full TCB0.CNT = 0; } ISR(TCB0_INT_vect) { // reset the INTFLAGS - necessary on this series uint8_t intflags = TCB0.INTFLAGS; TCB0.INTFLAGS = intflags; // we don't care why we interrupted. // we'll now return to executing loop() } // rgb program 0: rainbow puke #define RAINBOW_HUE_INC 40 // how much to increment the hue every frame #define RAINBOW_OFFSET (1536/5) // offset between each LED #define RAINBOW_TIMEOUT 240 // how long to show this program #define RAINBOW_SAT 0xff // saturation #define RAINBOW_VAL 0x40 // value (brightness); keep low enough to keep average current down uint16_t rainbow_hue = 0; uint16_t rainbow_timeout; uint8_t rgbp_rainbow(uint8_t init) { uint8_t i; uint8_t r, g, b; uint16_t hue; // set our timer when initializing. otherwise every call is identical if (init) { rainbow_timeout = RAINBOW_TIMEOUT; } if (--rainbow_timeout) { // copy stored hue to working hue hue = rainbow_hue; for (i = 0; i < RGB_COUNT; i++) { // each LED will increment its hue hue += RAINBOW_OFFSET; // hue wheel is 256*6 large, so bound the value if (hue >= 1536) hue -= 1536; // compute rgb from hue/sat/value hsv2rgb(hue, RAINBOW_SAT, RAINBOW_VAL, &r, &g, &b); // apply it to this LED rgb.setPixelColor(i, r, g, b); } // increment stored hue wheel for the next cycle through the program rainbow_hue += RAINBOW_HUE_INC; if (rainbow_hue > 1536) rainbow_hue -= 1536; return 1; } // done with program return 0; }