Posted in Arduino | 0 comments

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