MCN Workshop Part 6

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 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.

  • Here is a great tutorial on how to solder, if you want to get started without one of us.
  • Remember, soldering can be dangerous. Please respect the tools, don’t hurt yourself, and don’t burn down the building. 😉

Conductive Thread

Conductive thread in use. Photo by Shannon Henry.
Conductive thread in use. Photo by Shannon Henry.

Another approach is using conductive thread. Each table has some needles and conductive thread. Be careful not to cross the streams—er, um wires—or you will short your circuit. Here is a great tutorial on using conductive thread.

 What is the Form?

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.
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 great forums to ask questions too.

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

/* 
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
*/
#include <Adafruit_NeoPixel.h>
// constants won't change. 
#define buttonPin 2 // the number of the pushbutton pin
#define neoPixelPin 0 //the number of the neopixel pin
#define numPixelsInStrip 16 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixelsInStrip, neoPixelPin, NEO_GRB + NEO_KHZ800);
///////////////////////////////////////////////////////////////////////////
// Change the following variables to play with different outcomes        //
//
int defaultBrightness = 64; // the max brightness, between 0 and 256     //
//
// 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 -- buttonpresses rotate between programs
int numOfPrograms = 5; // how many programs are there total, not including the off state
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
//cylon variables
int fadeDirection = -1;//change sign to fade up or down
boolean cylonDirection = true; //keeps track of the direction the pixels should swipe
boolean cylonPause = false; //keeps track of the pause inbetween swipes
long delayMillis = 0; // will store the last time the cylon swipe was paused
// 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 = (programState + 1) % (numOfPrograms + 1); //include numOfPrograms + 1, since there is an off state
}
}
}
// save the reading.  Next time through the loop
lastButtonState = reading;
//////////////////////////////////////////////////////////////////////////////
// Change the program states to cycle when the button is pressed.           //
// Try changing the colors and duration.                                    //
// NOTE if you change the number of programs in the switch statement above, //
// be sure to change the variable numOfPrograms at the top.                 //
//////////////////////////////////////////////////////////////////////////////
//run the chosen program
switch (programState) {
case 0:
allColor(strip.Color(0,0,0)); // turn all lights off
break; 
case 1:
//blinkColor(strip.Color(255,0,0),100); // blink red every 100
blinkColor((unsigned long)random(0x01000000),250);
break;        
case 2:
softBlink(strip.Color(0,255,255),defaultBrightness, 50); // soft blink blue every 50
break;
case 3:
strip.setBrightness(defaultBrightness); // initialize brightness
rainbow(20); //all rainbow with a 20 wait setting
break;
case 4:
rainbowCycle(10); //all rainbow, but slightly different--try it to see
break;
case 5:
cylonEye(40, 500); //cylon eye, but not sure if the pause is working
break;
default: 
// if nothing else matches, do the default 
allColor(strip.Color(0,0,0)); //turn all off
} 
}
//////////////////////////////////////////////////////////////////////
// Stop changing program states. Below are the programs themselves. //
//////////////////////////////////////////////////////////////////////
// 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
}
} 
}  
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);
}
}
void cylonEye(uint8_t swipeSpeed, uint8_t pauseTime) {
if (cylonPause) { //we are on a pause break from swipes
unsigned long currentPauseMillis = millis();
//check to see if we've waited long enough
if ((currentPauseMillis - delayMillis) > pauseTime) { /////////////////////////////// this is not getting called. Why????????????????
// save the last time you checked the pause
delayMillis = currentPauseMillis;
cylonPause = false; //end the pause
}
} else {
//if needed, change directions
if (neoPixelToChange > numPixelsInStrip) {
cylonDirection = false;
}
if (neoPixelToChange < 0) {
cylonDirection = true;
cylonPause = true; //take a break from the swipe
//turn all pixels off
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
delayMillis = millis();
}
//run the swipe
if (cylonDirection) {
cylonUp(strip.Color(255, 0, 0), strip.Color(72, 0, 0), swipeSpeed); // red
} else {
cylonDown(strip.Color(255, 0, 0), strip.Color(72, 0, 0), swipeSpeed); // red
}
}
}
void cylonUp(uint32_t c0, uint32_t c1, uint8_t wait) {
unsigned long currentMillis = millis();
//neoPixelToChange * wait
if (currentMillis - previousMillis > wait) {
//turn all pixels off
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
// save the last time you changed a NeoPixel
previousMillis = currentMillis;
//change a pixel
strip.setPixelColor(neoPixelToChange, c0); //primary color
strip.setPixelColor(neoPixelToChange - 1, c1); //secondary color
strip.setPixelColor(neoPixelToChange + 1, c1); //secondary color
strip.show();
neoPixelToChange++;
}
}
void cylonDown(uint32_t c0, uint32_t c1, uint8_t wait) {
unsigned long currentMillis = millis();
//neoPixelToChange * wait
if (currentMillis - previousMillis > wait) {
//turn all pixels off
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
// save the last time you changed a NeoPixel
previousMillis = currentMillis;
//change a pixel
strip.setPixelColor(neoPixelToChange, c0); //primary color
strip.setPixelColor(neoPixelToChange - 1, c1); //secondary color
strip.setPixelColor(neoPixelToChange + 1, c1); //secondary color
strip.show();
neoPixelToChange--; //is there any way to combine this with cylonUp, since this is the only line that is different?
}
}

Try the Other Sensors

You have many sensors in your kit. They each do slightly different things. Take a look at the product pages, click “Learn” to see the code in action. Here is the list:

Share Your Code

Did you make something unique and fun? Share it with the rest of the group. They might improve on it and send it back to you. Welcome to the maker world.

 

part5-left

 

 

Cover photo by josef.stuefer

Share your thoughts