This sketch shows the rough alignment of components for the project. Alternating strips of warm and cool white DotStar LEDs chain together to form a bank of light. For more detailed wiring instruction, visit the circuit diagram on the next page.

It pays to prototype your circuit on a solderless breadboard before soldering everything together. If you can manage to have a duplicate set of parts, that's even better-- you can use your working prototype as a model to work from when building the final soldered circuit.

Below is some rudamentary code for adjusting the brightness of the two LED strips using the membrane keypad as follows:

1: strip 1 brightness up

2: strip 1 brightness down

3: strip 2 brighness up

4: strip 2 brightness down

The brightness value incrementers don't have any thresholding, so values will "wrap around" (ie pressing 2 when the strips are off will raise that strip to full brightness).

Load the following code onto your Pro Trinket:

#include <Adafruit_DotStar.h>
// Because conditional #includes don't work w/Arduino sketches...
#include <SPI.h>         // COMMENT OUT THIS LINE FOR GEMMA OR TRINKET
//#include <avr/power.h> // ENABLE THIS LINE FOR GEMMA OR TRINKET

#define NUMwarmPIXELS 60 // Number of LEDs in strip
#define NUMcoolPIXELS 60 // Number of LEDs in strip

#define DATAPINwarm    6
#define CLOCKPINwarm   8
#define DATAPINcool    3
#define CLOCKPINcool   4
Adafruit_DotStar warmStrip = Adafruit_DotStar(NUMwarmPIXELS, DATAPINwarm, CLOCKPINwarm);
Adafruit_DotStar coolStrip = Adafruit_DotStar(NUMcoolPIXELS, DATAPINcool, CLOCKPINcool);

#define DEBOUNCE 10  // button debouncer, how many ms to debounce, 5+ ms is usually plenty

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {9, 10, 11, 12}; // the analog 0-5 pins are also known as 14-19
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'currently pressed' 
byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

int warmBrightness = 0;
int coolBrightness = 0;

void setup() {
  byte i;
 
  // Make input & enable pull-up resistors on switch pins
  for (i=0; i<NUMBUTTONS; i++){
    pinMode(buttons[i], INPUT_PULLUP);
  }
  
  // pin13 LED
  pinMode(13, OUTPUT);
  
  warmStrip.begin(); // Initialize pins for output
  warmStrip.show();  // Turn all LEDs off ASAP
  coolStrip.begin(); // Initialize pins for output
  coolStrip.show();  // Turn all LEDs off ASAP
  fillAll(warmStrip.Color(255, 255, 255));
  warmStrip.show();
  coolStrip.show();
}


void loop() {
warmStrip.setBrightness(warmBrightness);
coolStrip.setBrightness(coolBrightness);
warmStrip.show();
coolStrip.show();
digitalWrite(13, LOW);

check_switches();      // when we check the switches we'll get the current state

  for (byte i = 0; i<NUMBUTTONS; i++){
    if (pressed[i]) {
      digitalWrite(13, HIGH);
      // is the button pressed down at this moment
    }
    if (justreleased[i]) {
      if (i == 0){  
        warmBrightness+=5;
      }else if (i == 1){
        warmBrightness-=5;
      }else if (i == 2){
        coolBrightness+=5;
      }else if (i == 3){
        coolBrightness-=5;
    }
    }
  }
  for (byte i=0; i<NUMBUTTONS; i++){  // remember, check_switches() will necessitate clearing the 'just pressed' flag
    justpressed[i] = 0;
  }
}

void check_switches()
{
  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];
  static long lasttime;
  byte index;

  if (millis() < lasttime){ // we wrapped around, lets just try again
     lasttime = millis();
  }
  
  if ((lasttime + DEBOUNCE) > millis()) {
    // not enough time has passed to debounce
    return; 
  }
  // ok we have waited DEBOUNCE milliseconds, lets reset the timer
  lasttime = millis();
  
  for (index = 0; index<NUMBUTTONS; index++){ // when we start, we clear out the "just" indicators
    justreleased[index] = 0;
     
    currentstate[index] = digitalRead(buttons[index]);   // read the button
   
    if (currentstate[index] == previousstate[index]) {
      if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
          // just pressed
          justpressed[index] = 1;
      }
      else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
          // just released
          justreleased[index] = 1;
      }
      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  }
}

void fillAll(uint32_t c)
{
  for(uint16_t i=0; i<warmStrip.numPixels(); i++) {
      warmStrip.setPixelColor(i, c);
  }
  for(uint16_t i=0; i<coolStrip.numPixels(); i++) {
      coolStrip.setPixelColor(i, c);
  }
  warmStrip.show();
  coolStrip.show();
}

This guide was first published on May 27, 2015. It was last updated on May 27, 2015.

This page (Prototype & Code) was last updated on May 08, 2015.

Text editor powered by tinymce.