Navigation Menu

A portfolio for an exhibit designer, planner, interactive designer, developer, artist, coder, optimist, and normally too humble of a guy.

Design

More work »

MCN Workshop Part 6

MCN Workshop Part 6

Posted on Oct 30, 2014 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

Read More

MCN Workshop Part 5

MCN Workshop Part 5

Posted on Oct 30, 2014 in Arduino | 0 comments

On the previous parts, we wired a simple input button and next wired NeoPixels for flashy output. Now we’ll combine both input and output.

Interactions

  1. We will need a fresh blank sketch. Go into the File menu and choose New.
  2. 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);
      }
    }
  3. Save the code on your computer with a filename that makes sense.
  4. 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 buttonneopixel wiring 2
  5. Plug the GEMMA into your computer’s USB port, if it’s not already.
  6. Upload the code. Remember to press the button on the GEMMA before uploading.
  7. After uploading, the GEMMA should be running the code. A soft rainbow pattern will circle.
  8. 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.
  9. 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.

  1. 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                         //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
  2. 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.
  3. 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                         //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
  4. 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?
  5. 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)
  6. 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.
  7. Be sure to save your file as you iterate.
  8. Now we are ready to move onto the final section.

part4-leftpart6-right

 

Cover photo by me. ;-)

Read More

MCN Workshop Part 4

MCN Workshop Part 4

Posted on Oct 30, 2014 in Arduino | 0 comments

On the previous part, we got the GEMMA receiving input from a simple button. Now, we’ll work on only output from the GEMMA to control some fun lights.

NeoPixels

  1. First, unplug the GEMMA from your computer.
  2. Then, take out three alligator clips: yellow, red, and black.
  3. Now, attach the clips as below:
    • Yellow from GEMMA DO to NeoPixels IN
    • Red from GEMMA Vout to NeoPixels PWR
    • Black from GEMMA GND to NeoPixels GND
      NOTE: Be careful when you clip. Only get a small bit of the NeoPixel ring. If you put the clip on too far, it may touch other electronics and short out your circuit.neopixel wiring
  4. With the circuit created, now we move to the code.
  5. Start up a new, blank sketch by opening the File menu and choosing New.
  6. Copy and paste the following 124 lines of code.
    #include <Adafruit_NeoPixel.h>
    
    // constants won't change. 
    #define neoPixelPin 0 //the number of the neopixel pin
    #define numPixelsInStrip 12 
    
    // Parameter 1 = number of pixels in strip
    // Parameter 2 = Arduino pin number (most are valid)
    // Parameter 3 = pixel type flags, add together as needed:
    //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
    //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
    //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
    //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixelsInStrip, neoPixelPin, NEO_GRB + NEO_KHZ800);
    
    // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
    // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
    // and minimize distance between Arduino and first pixel.  Avoid connecting
    // on a live circuit...if you must, connect GND first.
    
    void setup() {
      strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    }
    
    void loop() {
      // Some example procedures showing how to display to the pixels:
      colorWipe(strip.Color(255, 0, 0), 50); // Red
      colorWipe(strip.Color(0, 255, 0), 50); // Green
      colorWipe(strip.Color(0, 0, 255), 50); // Blue
      // Send a theater pixel chase in...
      theaterChase(strip.Color(127, 127, 127), 50); // White
      theaterChase(strip.Color(127,   0,   0), 50); // Red
      theaterChase(strip.Color(  0,   0, 127), 50); // Blue
    
      rainbow(20);
      rainbowCycle(20);
      theaterChaseRainbow(50);
    }
    
    // Fill the dots one after the other with a color
    void colorWipe(uint32_t c, uint8_t wait) {
      for(uint16_t i=0; i<strip.numPixels(); i++) {
          strip.setPixelColor(i, c);
          strip.show();
          delay(wait);
      }
    }
    
    void rainbow(uint8_t wait) {
      uint16_t i, j;
    
      for(j=0; j<256; j++) {
        for(i=0; i<strip.numPixels(); i++) {
          strip.setPixelColor(i, Wheel((i+j) & 255));
        }
        strip.show();
        delay(wait);
      }
    }
    
    // Slightly different, this makes the rainbow equally distributed throughout
    void rainbowCycle(uint8_t wait) {
      uint16_t i, j;
    
      for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
        for(i=0; i< strip.numPixels(); i++) {
          strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
        }
        strip.show();
        delay(wait);
      }
    }
    
    //Theatre-style crawling lights.
    void theaterChase(uint32_t c, uint8_t wait) {
      for (int j=0; j<10; j++) {  //do 10 cycles of chasing
        for (int q=0; q < 3; q++) {
          for (int i=0; i < strip.numPixels(); i=i+3) {
            strip.setPixelColor(i+q, c);    //turn every third pixel on
          }
          strip.show();
         
          delay(wait);
         
          for (int i=0; i < strip.numPixels(); i=i+3) {
            strip.setPixelColor(i+q, 0);        //turn every third pixel off
          }
        }
      }
    }
    
    //Theatre-style crawling lights with rainbow effect
    void theaterChaseRainbow(uint8_t wait) {
      for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
        for (int q=0; q < 3; q++) {
            for (int i=0; i < strip.numPixels(); i=i+3) {
              strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
            }
            strip.show();
           
            delay(wait);
           
            for (int i=0; i < strip.numPixels(); i=i+3) {
              strip.setPixelColor(i+q, 0);        //turn every third pixel off
            }
        }
      }
    }
    
    // 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);
      }
    }
    
  7. Save the code somewhere on your computer with a good filename.
  8. Plug in the GEMMA to a USB port on your computer.
  9. While the red light is pulsing, press the upload button to upload the code. If you don’t do it fast enough, press the physical button on the GEMMA to start the connection and press upload.
  10. Hopefully, the NeoPixels will start to light up in many different patterns. Watch for a bit and try to figure out the different patterns.
  11. If nothing is working, check your circuit to make sure everything is tight. If the computer successfully uploaded the code, it should be running. Try un-plugging the USB cord and then plug it back in.
  12. Enjoy the success of getting the GEMMA to output to the NeoPixels. Next we’ll combine the input and output.

part3-left

part5-right

 

Cover photo by Adafruit

Read More

MCN Workshop Part 3

MCN Workshop Part 3

Posted on Oct 30, 2014 in Arduino | 0 comments

Now that we know the goodies in our kits, let’s start to put them to work. The first thing we’ll do is get a button to light up—the stereotypical first thing to do with an Arduino. It’s good for us, because it will confirm all the parts are working without having a super complex system yet.

Simple Push Button Light

  1. First, unplug the GEMMA from your computer’s USB port, if you have it plugged in.
  2. Then, open the Adafruit Arduino software, if you don’t have it open yet.
  3. Go under File and choose New. A blank code sketch will open.
  4. Copy and paste the following 48 lines of code into your new sketch.
    /*
     Input Pullup Serial
     
     This example demonstrates the use of pinMode(INPUT_PULLUP). It reads a 
     digital input on pin 2 and prints the results to the serial monitor.
     
     The circuit: 
     * Momentary switch attached from pin 2 to ground 
     * Built-in LED on pin 13
     
     Unlike pinMode(INPUT), there is no pull-down resistor necessary. An internal 
     20K-ohm resistor is pulled to 5V. This configuration causes the input to 
     read HIGH when the switch is open, and LOW when it is closed. 
     
     created 14 March 2012
     by Scott Fitzgerald
     
     http://www.arduino.cc/en/Tutorial/InputPullupSerial
     
     This example code is in the public domain
     
     */
     
    const int buttonPin = 2;     // the number of the pushbutton pin
    const int ledPin =  1;      // the number of the default LED pin
    
    void setup(){
      //configure pin2 as an input and enable the internal pull-up resistor
      pinMode(buttonPin, INPUT_PULLUP);
      pinMode(ledPin, OUTPUT); 
    
    }
    
    void loop(){
      //read the pushbutton value into a variable
      int sensorVal = digitalRead(buttonPin);
      
      // Keep in mind the pullup means the pushbutton's
      // logic is inverted. It goes HIGH when it's open,
      // and LOW when it's pressed. Turn on ledPin when the 
      // button's pressed, and off when it's not:
      if (sensorVal == HIGH) {
        digitalWrite(ledPin, LOW);
      } 
      else {
        digitalWrite(ledPin, HIGH);
      }
    }
  5. From the Tools menu, choose Board, and then Adafruit Gemmaboard
  6. From the Tools menu again, choose Programmer, and then USPtinyISPprogrammer
  7. verify

    The verify button

    Click the small check mark button in the upper left-hand corner of the sketch window. It will verify that the code is accurate. If not, you will see an error message on the bottom.

  8. Save your sketch somewhere that makes sense on your computer with a good filename.
  9. Now get out the GEMMA, the push button, and two alligator clips (one white and one green).button wiring
  10. Clip the white alligator clip to the D2 pin on the GEMMA.
  11. Clip the other side of the white clip one of the metal feet of the button.

    The dashed line represents the electrical connection between the alligator clips and the button. Notice the current cannot flow when the button is not pressed as there is no connection.

    The dashed line represents the electrical connection between the alligator clips and the button. Notice the current cannot flow when the button is not pressed as there is no connection. DO NOT put both clips on the same side of the button.

  12. Now look at the button. The two of the feet connect in a line. This is one side of the button. The other side has a symmetrical line with the other two feet. When untouched, the button stops electricity from flowing from one side to the other. When you press the button, the circuit is completed and electricity flows.
  13. Clip the green alligator clip to one of the feet on the other side of the button.
  14. Clip the other side of the alligator clip to the GND pin on the GEMMA. This stands for ground.
  15. At this point we have the code written and the circuit complete. It’s time to upload the code to the GEMMA. Plug in the GEMMA to your computer’s USB port.
  16. The green power light should be solid. The red light should be pulsing. This is a sign that you can upload code.
  17. By now, the red light is probably not pulsing any more. That means we cannot upload code. First look where the upload button is on the sketch window—the arrow button. Get ready to click this.
  18. First, press the physical button on the GEMMA to start the pulsing red light, opening the door to upload code.gemma button
  19. upload

    The upload button

    Then, quickly, click the upload button on the sketch window. There should be a message at the bottom of the sketch window that the code is first compiling, and then uploading.compiling

  20. If you are having trouble, try unplugging and re-plugging the GEMMA. While it’s pulsing red, click the upload button.
  21. Once it finishes uploading, the GEMMA runs the code.
  22. This one is simple, press the push button you wired. When it is pushed, the red light on the GEMMA should light up. Release, and it will turn off. Try it a few times.
  23. SUCCESS. You have now learned how to copy and paste code, upload code, wire a circuit, and run a program on a microcontroller. Good work. But now let’s do something more flashy. (ugh, groaner pun)

part2-leftpart4-right
Cover photo by Ali Kholi

Read More

MCN Workshop Part 2

MCN Workshop Part 2

Posted on Oct 30, 2014 in Arduino | 0 comments

Now let’s dig in. You should now have a hardware kit in you hands. Let’s take a look at what is inside.

kit

GEMMA microcontoler

At the heart of our project lies the microcontroller. The GEMMA is a tiny arduino compatible microcontoller. It’s small size and small cost allows us to do fun things. For more information, see the complete guide here. Notice the USB port, battery port, various gold pins around the oustside labeled things like D2 (for digital 2), and a small black push button.

NeoPixel Ring

This is a ring of small lights that we can control individually to produce nearly any color in the visible spectrum. It’s pretty fun. There is also a great guide on how to use them.

Input Devices

There are a few different devices that we can use to record input to the GEMMA. This includes a simple push button, and two vibration sensors of different sensitivities (fast and slow), and a piezo.

Accessories

There are a few other goodies in the kit too:

  • A USB cable to connect the GEMMA to the computer
  • A battery holder that will hold two coin batteries. But you don’t need to use this at the same time as the USB cable in plugged into the computer. The computer can power the device too.
  • A bunch of alligator clips provide a quick and easy way to connect electrical circuits as we build our system. Eventually, once we have the circuit we want, we will use a more permanent system such as solder or conductive thread.

part1-left

part3-right

 

 

Cover photo by Adafruit

Read More

MCN Workshop Part 1

MCN Workshop Part 1

Posted on Oct 29, 2014 in Arduino | 0 comments

Welcome to the MCN workshop Dabble with Microcontrollers. This is the first post in a series that we will use during the workshop.

First, we need to download the software we’ll use to code later in the workshop. It’s a little tricky, but once it’s done, you should be able to run all the code we are using today. You will need administrative rights on your computer to install.

 

Adafruit Arduino Software

We will need a program to develop code. Download the Adafruit Arduino Software. Full instructions are here.

For Mac:

  1. Download the application
  2. Unzip it
  3. Move it to your applications folder
  4. Try opening the programcant-open-from-web
  5. If you are running a newer version of OS X, you will need to change your security settings so that this program downloaded from the internet will run on your computer. Follow the instructions on the Adafruit site.system-preferences
    open-anyway
  6. You may be asked to install a version of Java. Go ahead and click “More Info” to go to the website, download, and install.java
  7. You may also be asked to allow incoming connections from the program. Go ahead and choose allow.

For Windows

  1. Things may be a bit more interesting with Windows.
  2. First, we need to install the drivers for GEMMA. Full instructions here. Download Windows XP/Vista/7 drivers here or Windows 8 drivers here. Unzip them to a temporary place you know, like the desktop.
  3. Plug-in the GEMMA and you should get this screen. If not, use the device manager to update the driver.drivers
  4. Click “Browse” to find the folder we unzipped on the desktop. Make sure you choose to include subfolders. Then click “Next.”drivers2
  5. You may get a security warning. You should be ok to choose “Install this driver software anyway.”drivers3
  6. After a little bit, you should get a message that the driver was successfully installed. Click “Close.”Screenshot_2
  7. Now, download the software
  8. Unzip it
  9. Rename the unzipped folder from “windows” to something more useful, such as “Arduino Adafruit”foldername
  10. Move the folder to your programs folder C:\Program Files (x86)\. You may get a permissions pop-up message. Choose “Continue.”userights
  11. Try opening the program C:\Program Files (x86)\Adafruit Arduino\arduino.exe
  12. Make a shortcut to this program if you would like.

NeoPixels Library

We will all need to do this step, regardless of the operating system.

We will be using some fancy flashing lights, called NeoPixels. You will need the code library. This part should work the same on all three platforms.

  1. Find the download button on Github

    Download the library on this page

  2. Look on the right side of the page at the bottom of the column, for the button labeled, “Download Zip”.
  3. Save this file to a temporary place on your computer, like the desktop.
  4. Rename the folder to not have any dashed, only underscores

    Rename the folder to not have any dashed, only underscores

    Unzip the folder and rename it, “Adafruit_NeoPixel”. Notice there are no dashes, only underscores.

  5. Now open the Arduino program.
  6. Choose Sketch >> Import Library >> Add Library…
  7. Navigate to the “Adafruit_NeoPixel” folder and click “Choose”
  8. This will save the library to the proper location on your computer. To make sure it worked, go to Sketch >> Import Library and look for “Adafruit_NeoPixel” in the contributed list at the bottom
Adding the library to the software

Adding the library to the software

 

part2-right

Cover photo by John Nussey

Read More