Try Other Programs

Next, try the other Circuit Playground programs that came with the library. File >> Examples >> Adafruit Circuit Playground >> Hello_Circuit Playground >>. See what they do. When you’re finished with those, jump up to some of the others like Birthday_Candles or FidgetSpinner.

#include <Adafruit_CircuitPlayground.h>
// learn more about state changes here: https://www.arduino.cc/en/Tutorial/StateChangeDetection?from=Tutorial.ButtonStateChange
// this constant won't change:
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPin = 6; // the pin that the LED is attached to
// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
void setup() {
CircuitPlayground.begin();
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// read the pushbutton input pin:
buttonState = CircuitPlayground.leftButton();
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
} else {
// if the current state is LOW then the button went from on to off:
Serial.println("off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
// turns on the LED every four button pushes by checking the modulo of the
// button push counter. the modulo function gives you the remainder of the
// division of two numbers:
if (buttonPushCounter % 2 == 0) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}

At today’s workshop, we’ll follow a series of small projects using parts from our kit. We’ll copy and paste code to see what it does. Then later, we’ll dive into the inner working of the code. Finally, we’ll make something on our own with the combined parts.

At today’s workshop, we’ll follow a series of small projects using parts from our kit. We’ll copy and paste code to see what it does. Then later, we’ll dive into the inner working of the code. Finally, we’ll make something on our own with the combined parts.

Wiring Diagram

Soon, we will break for the free form section of the workshop where you can customize your project in your own way. But before we do, let’s review some tricks to think about while you work on your project.

Pace your time

Plan something that you can accomplish given the timeframe we have left. Start small, get that working, then iterate something other idea building on the last, get that working, and so on, and so on. Time will fly.

Help your Neighbors

Work on your project, but help answer questions from those around you. Through out questions and ideas. We always make better ideas bouncing them around between a group. There will be others in the room who have done this before. Ask them for help too.

No More Aligator Clips

The alligator clips are wonderful to iterate ideas quickly, but they do not hold up to abuse. There are two easy ways to make your circuits more permanent.

Soldering

Soldering in action. Photo by zazenergy.

Soldering is commonplace in electronics. If you have not done this before, today is a great day to start. We will have a few soldering stations setup in the room, and we can show you the basics.

What is the Form?

Beautiful flower

Camera

Abstract circles

What do you want your creation to look like? Is it a button for your name tag? Does it sit on your hat or your bag? Is it more abstract or does it have a more real form? Take fabric, or paper, glue, or whatever you want to make your project your own. Think about defusing the light from the NeoPixels somehow. A tennis ball works well.

Tweak the Code

Inside the code. Photo by David Asch.

Have an idea to change the interaction behavior? This workshop did not handle much on how to code, but during this free form section of the workshop, you can dive in. Find others who have coded before and tell them your vision. If it’s simple enough, you could get it working. Get ready for bug fixing, function building, and magic making. There are some greatforums to ask questions too.

Here is another piece of example code with some new function that you might want to play with.

Interactions

We will need a fresh blank sketch. Go into the File menu and choose New.

Copy and paste the following 257 lines of code.

/*
Created by chris@drumminhands.com
Modified by combining these tutorials
Blink without Delay http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
State change detection (edge detection) http://arduino.cc/en/Tutorial/ButtonStateChange
Adafruit Strandtest https://github.com/adafruit/Adafruit_NeoPixel
Debounce http://www.arduino.cc/en/Tutorial/Debounce
Cyclon eyes https://github.com/EternalCore/NeoPixel_Cylon_Scrolling_Eye
*/
//Choose a default program to run all the time, until the button is pressed.
//Then run the second program for a time. Then go back to the original program.
#include <Adafruit_NeoPixel.h>
// constants won't change.
#define neoPixelPin 0 // the number of the neopixel pic
#define buttonPin 2 // the number of the input pin
#define numPixelsInStrip 12 // the number of pixels in the strip/circle
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixelsInStrip, neoPixelPin, NEO_GRB + NEO_KHZ800);
//////////////////////////////////////////////////////////////////////////////////////
// Change the following variables to play with different outcomes //
//
int defaultBrightness = 128; // the max brightness, between 0 and 256 //
int reactionDuration = 2000; // how long to run the second program, in miliseconds //
//
// Do not change anything outside of this comment box, unless you know what it does.//
//////////////////////////////////////////////////////////////////////////////////////
// Variables used in programs
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
int programState = 0; // current program seleted
int ledState = HIGH; // the current state of the output pin
long previousMillis = 0; // will store last time LED was updated
int neoPixelToChange = 0; //track which neoPixel to change
int neoPixel_j = 0; //stores values for program cycles
long color = 0x01000000; //store the color value when reacting
// Setup is a program run once at the beginning to get things in place
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
strip.begin(); // prep the NeoPixels
strip.show(); // Initialize all pixels to 'off'
strip.setBrightness(defaultBrightness); // initialize brightness
}
// Loop is the program that runs repeatedly after Setup. Look for the programs below to change.
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
//change the program
programState = 1; //change to the second program
color = random(0x01000000); // choose a color at random for the reaction
}
}
}
// save the reading. Next time through the loop
lastButtonState = reading;
// if it's been longer than the reaction duration
if ((millis() - lastDebounceTime) > reactionDuration) {
programState = 0; //go back to the default program
}
//run the chosen program
switch (programState) {
case 0:
///////////////////////////////////////////////////////////////////////////////////////////
rainbowCycle(7); //The default program. Change as needed //
///////////////////////////////////////////////////////////////////////////////////////////
break;
case 1:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
blinkColor(color,100); // use this line to blink a random color //
//blinkColor((unsigned long)random(0x01000000),100); // use this line to blink a new random color each blink //
//blinkColor(strip.Color(128,0,204),100); // use this line to blink a specific color //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
break;
default:
allColor(strip.Color(0,0,0)); //if nothing else matches, turn all off
}
}
// Fill all the dots with one color
void allColor(uint32_t c) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
}
} // note for a random color, use:
// allColor((unsigned long)random(0x01000000)); // random color
void blinkColor(uint32_t c, uint8_t wait) {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > wait) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW){
ledState = HIGH;
allColor(c);
} else {
ledState = LOW;
allColor(strip.Color(0,0,0)); // off
}
}
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
unsigned long currentMillis = millis();
//only do this if some of the pixels still need to be lit
if (neoPixelToChange <= strip.numPixels()){
if(currentMillis - previousMillis > wait) {
// save the last time you changed a NeoPixel
previousMillis = currentMillis;
//change a pixel
strip.setPixelColor(neoPixelToChange, c);
strip.show();
neoPixelToChange++;
}
}
}
// Fill the dots one after the other with a color
void colorWipeCycle(uint32_t c, uint8_t wait) {
unsigned long currentMillis = millis();
//only do this if some of the pixels still need to be lit
if (neoPixelToChange <= strip.numPixels()){
if(currentMillis - previousMillis > wait) {
// save the last time you changed a NeoPixel
previousMillis = currentMillis;
//change a pixel
strip.setPixelColor(neoPixelToChange, c);
strip.show();
neoPixelToChange++;
}
} else {
// reset the cycle
previousMillis = 0;
neoPixelToChange = 0;
allColor(strip.Color(0,0,0));
}
}
void rainbow(uint8_t wait) {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > wait) {
// save the last time you changed a NeoPixel
previousMillis = currentMillis;
//change the colors of the pixels
uint16_t i;
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+neoPixel_j) & 255));
}
strip.show();
neoPixel_j = (neoPixel_j + 1) % 255; //increment j until all colors are used, then start over
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > wait) {
// save the last time you changed a NeoPixel
previousMillis = currentMillis;
//change the colors of the pixels
uint16_t i;
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + neoPixel_j) & 255));
}
strip.show();
neoPixel_j = (neoPixel_j + 1) % 1279; // 5 cycles of all colors on wheel, then start over
}
}
void softBlink(uint32_t c, uint8_t brightness, uint8_t wait) {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > wait) {
//set the color of all pixels
allColor(c); // is there a way to set this only once per program ????????????????????
// save the last time you changed a NeoPixel
previousMillis = currentMillis;
uint16_t i;
int b = (neoPixel_j * brightness) / brightness;
strip.setBrightness(b);
strip.show();
// sometime figure out how to get this to fade down too instead of just restarting //////////////////////
neoPixel_j = (neoPixel_j + 1) % brightness;
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}

Save the code on your computer with a filename that makes sense.

The circuit should already be setup, as long as you did not unplug the button when you plugged in the NeoPixels. If you need to tweak, be sure unplug the GEMMA from your computer before changing the circuit. Double-check the following:

Yellow from GEMMA DO to NeoPixels IN

Red from GEMMA Vout to NeoPixels PWR

Black from GEMMA GND to NeoPixels GND

White from GEMMA D2 to button

Green from GEMMA GND to other side of the button

Plug the GEMMA into your computer’s USB port, if it’s not already.

Upload the code. Remember to press the button on the GEMMA before uploading.

After uploading, the GEMMA should be running the code. A soft rainbow pattern will circle.

Try pushing the button. The NeoPixels should do something very different for a few seconds and then go back to the original soft rainbow pattern.

What’s happening here is the output changes depending on the input. It reacts to you.

Tweak the code

Now let’s tweak the code, just a bit. Don’t be scared. Let’s make some changes to customize this for you.

Scroll down in the code until you find a section that looks like this:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
blinkColor(color,100); // use this line to blink a random color //
//blinkColor((unsigned long)random(0x01000000),100); // use this line to blink a new random color each blink //
//blinkColor(strip.Color(128,0,204),100); // use this line to blink a specific color //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Notice only one line has different color in the text. The others are “commented out,” meaning that there are two slashes (//) at the start of the line. This means that you can type anything you want after those slashes and those characters won’t influence the behavior at all. It’s a way for you to write comments for yourself or others who read the code. It is also a way to hide particular lines of code for later use.

Add two comment slashes to line 97 and un-comment line 99, similar to below:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//blinkColor(color,100); // use this line to blink a random color //
//blinkColor((unsigned long)random(0x01000000),100); // use this line to blink a new random color each blink //
blinkColor(strip.Color(128,0,204),100); // use this line to blink a specific color //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

With this change, the NeoPixels will do something different when the button is pushed. Save the file and upload it. Give the button a try. What color does it change to?

Now tweak the code to your liking. Change the color value to anything you want. This is the specific part that sets the color, with three values, one each for Red, Green, and Blue.

strip.Color(128,0,204)

Each of the three values can a whole number from 0 to 255. Change the values and try uploading it again. Maybe use a color picker to get the RGB values you want.