// Xmas Tree demo for P2 // by Roy ELtham // // thanks to Jon McPhalen for his LED and encoder drivers // // ------ Libraries and Definitions ------ #include "simpletools.h" #include "string.h" #include "stdlib.h" #define N_PIXELS 241 #define PIX_DAT 48 #define ENC_BTN 18 #define ENC_B 17 #define ENC_A 16 #define ENC_LO 0 #define ENC_HI 16 #define BTN_DBNC 15 #define MODE_OPTION 0 #define MODE_BRIGHTNESS 1 // millisecond delay times #define MY_BRIGHTNESS 4 #define SWEEP_PAUSE 6 #define THEATER_PAUSE 80 // this number must be lower than N_PIXELS #define NUM_CANDLES 100 // ------ Global Variables and Objects ------ int RGBleds[N_PIXELS]; int candles[NUM_CANDLES]; int currentBrightness; struct __using("jm_rgbx_pixel.spin2") leds; struct __using("jm_quadrature.spin2") encoder; // ------ Function Declarations ------ void tree(); void sweepColor(int color); void unsweepColor(); void theaterChase(int color); void rainbow(int pause_time); void rainbowReverse(int pause_time); // ------ Main Program ------ int main() { encoder.start(ENC_A, ENC_B, ENC_BTN, encoder.DETENT, 0, ENC_LO, ENC_HI); leds.start_2812b(&RGBleds, N_PIXELS, PIX_DAT, 5); // setup candles for tree mode srand(_getcnt()); int n = 0; while (n < NUM_CANDLES) { for (int i = 0; i < N_PIXELS && n < NUM_CANDLES; i+=2) { if (rand() > (RAND_MAX*2)/3) { candles[n++] = i; } } } candles[NUM_CANDLES-1] = 240; // force top pixel to be a candle #if 0 // debug display of the candle randomness for (int i = 0; i < NUM_CANDLES; i++) { print("%d ", candles[i]); } #endif encoder.clear(); int last = encoder.value(); int selectedOption = last; int encoderMode = 0; currentBrightness = MY_BRIGHTNESS; while (1) { if (encoder.check_press(BTN_DBNC)) { encoder.force_release(BTN_DBNC); encoderMode++; if (encoderMode > MODE_BRIGHTNESS) { encoderMode = 0; } switch (encoderMode) { case MODE_OPTION: encoder.set_value(selectedOption); last = selectedOption; print("option = %d\n", selectedOption); break; case MODE_BRIGHTNESS: encoder.set_value(currentBrightness); last = currentBrightness; print("brightness = %d\n", currentBrightness); break; } } int now = encoder.value(); if (now != last) { last = now; if (encoderMode == 0) { selectedOption = now; print("option = %d\n", now); } else { currentBrightness = now; print("brightness = %d\n", now); } } switch(selectedOption) { case 0: tree(); break; case 1: sweepColor(leds.colorx(255, 0, 0, 0, currentBrightness)); unsweepColor(); break; case 2: sweepColor(leds.colorx(0, 255, 0, 0, currentBrightness)); unsweepColor(); break; case 3: sweepColor(leds.colorx(0, 0, 255, 0, currentBrightness)); unsweepColor(); break; case 4: sweepColor(leds.colorx(255, 255, 255, 0, currentBrightness)); unsweepColor(); break; case 5: sweepColor(leds.colorx(255, 255, 0, 0, currentBrightness)); unsweepColor(); break; case 6: sweepColor(leds.colorx(255, 0, 255, 0, currentBrightness)); unsweepColor(); break; case 7: sweepColor(leds.colorx(0, 255, 255, 0, currentBrightness)); unsweepColor(); break; case 8: theaterChase(leds.colorx(255, 0, 0, 0, currentBrightness)); break; case 9: theaterChase(leds.colorx(255, 255, 0, 0, currentBrightness)); break; case 10: theaterChase(leds.colorx(255, 0, 255, 0, currentBrightness)); break; case 11: rainbow(0); break; case 12: rainbowReverse(0); break; case 13: rainbow(5); break; case 14: rainbowReverse(5); break; case 15: rainbow(10); break; case 16: rainbowReverse(10); break; } } } void tree() { // fill with green for (int i = 0; i < N_PIXELS; i++) { RGBleds[i] = leds.colorx(0, 255, 0, 0, currentBrightness); } // light up candles for (int i = 0; i < NUM_CANDLES; i++) { RGBleds[candles[i]] = leds.colorx(255, 255, 48, 0, currentBrightness*2); } // if this is called in a loop, then the candles will appear to flicker } void sweepColor(int color) { for (int i = 1; i <= N_PIXELS; i++) { RGBleds[i] = color; pause(SWEEP_PAUSE); } } void unsweepColor() { for (int i = N_PIXELS; i > 0; i--) { RGBleds[i] = 0x00000000; pause(SWEEP_PAUSE); } } void theaterChase(int color) { for (int i = 0; i < 2; i++) { for (int spacer = 0; spacer < 3; spacer++) { for (int k = 0; k < N_PIXELS; k+=3) { RGBleds[constrainInt(k + spacer, 1, N_PIXELS) - 1] = color; } pause(THEATER_PAUSE); for (int k = 0; k < N_PIXELS; k+=3) { RGBleds[constrainInt(k + spacer, 1, N_PIXELS) - 1] = 0x00000000; } } } } void rainbow(int pause_time) { for (int colorWheelOffset = 0; colorWheelOffset < 256; colorWheelOffset++) { for (int i = 0; i < N_PIXELS; i++) { RGBleds[i] = leds.wheelx((i + colorWheelOffset) & 255, currentBrightness); } pause(pause_time); } } void rainbowReverse(int pause_time) { for (int colorWheelOffset = 255; colorWheelOffset >= 0; colorWheelOffset--) { for (int i = 0; i < N_PIXELS; i++) { RGBleds[i] = leds.wheelx((i + colorWheelOffset) & 255, currentBrightness); } pause(pause_time); } }