Alec and Kiri PC

From BenningtonWiki
Jump to: navigation, search

class wiki

Alec's wiki

Kiri's wiki

Introduction/Idea

For our midterm, Alec and I are creating a 18"x18"x18" structure constructed from wood, plastic sheeting, and foamboard. The electronic components will be the Arduino, of course, as well as an Adafruit wave shield and an IR sensor.

Building It

Resources

LEDs in parallel

Pictures

IR component

Resources

Resources for IR code:

-Arduino forum post
-Arduino tutorial

First Attempt

I got the code below off of the internet (on the Arduino Playground); it reads off the IR input to the Serial Monitor and a connected LED:

//define pins. I used pins 4 and 5
#define irLedPin 10          // IR Led on this pin
#define irSensorPin 5       // IR sensor on this pin

int irRead(int readPin, int triggerPin); //function prototype

void setup()
{
  pinMode(irSensorPin, INPUT);
  pinMode(irLedPin, OUTPUT);
  Serial.begin(9600); 
  // prints title with ending line break 
  Serial.println("Program Starting"); 
  // wait for the long string to be sent 
  delay(100); 
}

void loop()
{  
  Serial.println(irRead(irSensorPin, irLedPin)); //display the results
  delay(10); //wait for the string to be sent
}

/******************************************************************************
 * This function can be used with a panasonic pna4602m ir sensor
 * it returns a zero if something is detected by the sensor, and a 1 otherwise
 * The function bit bangs a 38.5khZ waveform to an IR led connected to the
 * triggerPin for 1 millisecond, and then reads the IR sensor pin to see if
 * the reflected IR has been detected
 ******************************************************************************/
int irRead(int readPin, int triggerPin)
{
  int halfPeriod = 13; //one period at 38.5khZ is aproximately 26 microseconds
  int cycles = 38; //26 microseconds * 38 is more or less 1 millisecond
  int i;
  for (i=0; i <=cycles; i++)
  {
    digitalWrite(triggerPin, HIGH); 
    delayMicroseconds(halfPeriod);
    digitalWrite(triggerPin, LOW); 
    delayMicroseconds(halfPeriod - 1);     // - 1 to make up for digitaWrite overhead    
  }
  return digitalRead(readPin);
}

I don't have my camera with me at the time (a grave oversight), but I set up the breadboard as so:

LED plugged into D10 and then ground
IR sensor with ground into ground on one side of the board, sensor into D5, and power into a column on the other side of the board
a 15k resistor plugged into the same column as IR sensor's power, and then into power on that side.

At first I tried this with a 220Ohm resistor, and the IR sensor just sensed the ceiling, or the wall, or whatever I pointed it at. After I switched it out for the 10k, I could see the difference (with a significant lag) on the Serial Monitor if I placed my hand in front of it. However, the LED remained on all the time.

Second Attempt

I then proceeded to modify the code to turn the LED on if the IR sensor sensed anything and off if it didn't. Code below:

//define pins. I used pins 4 and 5
#define irLedPin 10          // IR Led on this pin
#define irSensorPin 5       // IR sensor on this pin

int irRead(int readPin, int triggerPin); //function prototype
int val = 0;

void setup()
{
  pinMode(irSensorPin, INPUT);
  pinMode(irLedPin, OUTPUT);
  Serial.begin(9600); 
  // prints title with ending line break 
  Serial.println("Program Starting"); 
  // wait for the long string to be sent 
  delay(100); 
}

void loop()
{  
  val = digitalRead(irSensorPin);
  if (val == LOW) {
    digitalWrite(irLedPin, HIGH);
  } else {
    digitalWrite(irLedPin, LOW);
  }
  Serial.println(val); //display the results
  delay(10); //wait for the string to be sent
}

The board setup was the same.

Now, the IR sensor just sensed everything again (the Serial Monitor didn't change). I'm not sure what the change was, except that it probably has to do with the section of code I got rid of having to do with cycles and Hz and other things I don't understand at the time.

Wave Shield

Resources

-adafruit documentation
-pins (MISO, MOSI, SS, and SCK)

connecting the damn thing

I feel like an idiot because I can't figure out how to connect the shield to the Arduino, but I may as well document my struggles.

So, I've connected +5V and GND, and I've found the MISO, MOSI, SS, and SCK pins on the Nano. In addition, this bit of code:

  
// enable pull-up resistors on switch pins (analog inputs)
  digitalWrite(14, HIGH);
  digitalWrite(15, HIGH);
  digitalWrite(16, HIGH);
  digitalWrite(17, HIGH);
  digitalWrite(18, HIGH);
  digitalWrite(19, HIGH);

from here makes me think that six digital pins (14-19 on whatever Arduino the program is using; probably an Uno or Mega) connect to Analog-In pins 0-6 on the shield, particularly because the shield doesn't have any pins 14-19. However, in the same program, I found this:

 // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

and the Adafruit FAQ says that pins 2-5 are set up for the DAC. So I'm confused as to whether the program is setting up pins on the Arduino or the shield.

Update: So, I connected some things.

And then I disconnected everything because I was worried about destroying things accidentally. Also my code didn't work.

getting the code to work

My current problem: lots of errors, probably about finding things in the library.

This will probably be useful:

Code Snippits that Might Be Useful

Below is code that I wrote, fading an LED depending on the turn of the potentiometer.

//analog in controlling a servo motor out

int LED = 9;

void setup() { 
  Serial.begin(9600);       // initialize serial communications
  pinMode(LED, OUTPUT);
} 

void loop() 
{ 
  int analogValue = analogRead(A0); // read the analog input 
  Serial.println(analogValue);      // print it
  float bright = analogValue/4;
  analogWrite(LED, bright);
  delay(10);
}


And this one is the one where I figured out how to write, not just read, potentiometers. The potentiometer can be hooked up to an outside power source (say, a battery) and the variable "bright" can be be changed as needed (ie in relation to input from the PIR).

const int POT = 9;
int bright = 0;

void setup() {
  pinMode(POT, OUTPUT);
}

void loop() {
  analogWrite(POT, bright);
}


Code that switches between LED strands depending on the PIR reading! I intend to hook up the potentiometers that go between LEDs and batteries to the related pins, rather than the LED strands themselves.

//define pins. I used pins 4 and 5
#define BRAIN 9          // the string of LEDs for "active" viewing
#define SILH 2          // the string of LEDs for silhouette
#define PIR 5       // IR sensor on this pin

int i = 0;

int irRead(int readPin, int triggerPin); //function prototype
int val = 0;

void setup()
{
  pinMode(BRAIN, OUTPUT);
  pinMode(PIR, INPUT);
  pinMode(SILH, OUTPUT);
  Serial.begin(9600); 
  // prints title with ending line break 
  Serial.println("Program Starting"); 
  // wait for the long string to be sent 
  delay(100); 
}

void loop()
{  
  val = digitalRead(PIR);
  if (val == LOW) {
    digitalWrite(BRAIN, LOW);
    digitalWrite(SILH, HIGH);
  } else {
    digitalWrite(SILH, LOW);
    for (i = 0; i <255; i++) { // i starts at 0 and fades in until it's at 255
      analogWrite(BRAIN, i); //set LED to analog brightness?
      delay(10); //for viewing purposes
     }
    for (i = 255; i>0; i--) { //i starts at 255 and fades dn until it's at 0
      analogWrite(BRAIN, i); //led brightness
      delay(10); //again, viewing purposes
    }
  }
  Serial.println(val); //display the results
  delay(10); //wait for the string to be sent
}

Final Code

Uno

//play WAV file when button is held down and loop it
//taken from http://learn.adafruit.com/adafruit-wave-shield-audio-shield-for-arduino/examples
//to setup: wire nano so that it sends power to the Uno's analog0 when PIR == low
//and sends power to Uno's analog1 pin when PIR ==  high

#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"


SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

#define DEBOUNCE 5  // button debouncer

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {14, 15, 16, 17, 18, 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 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end; 
  extern int  *__brkval; 
  int free_memory; 
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end); 
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval); 
  }
  return free_memory; 
} 

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

void setup() {
  byte i;
  
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with ");
  Serial.print(NUMBUTTONS, DEC);
  putstring_nl("buttons");
  
  putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
  
  // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
 
  // pin13 LED
  pinMode(13, OUTPUT);
 
  // Make input & enable pull-up resistors on switch pins
  for (i=0; i< NUMBUTTONS; i++) {
    pinMode(buttons[i], INPUT);
    digitalWrite(buttons[i], HIGH);
  }
  
  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!)  
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  }
  
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);
 
// Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part)) 
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }
  
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
  
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }
  
  // Whew! We got past the tough parts.
  putstring_nl("Ready!");
  
  TCCR2A = 0;
  TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;

  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= 1<<TOIE2;


}

SIGNAL(TIMER2_OVF_vect) {
  check_switches();
}

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

  for (index = 0; index < NUMBUTTONS; index++) {
    currentstate[index] = digitalRead(buttons[index]);   // read the button
    
    /*     
    Serial.print(index, DEC);
    Serial.print(": cstate=");
    Serial.print(currentstate[index], DEC);
    Serial.print(", pstate=");
    Serial.print(previousstate[index], DEC);
    Serial.print(", press=");
    */
    
    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 loop() {
  byte i;

  if (pressed[0]) {
    playfile("ROOM.WAV");
    while (wave.isplaying && pressed[0]) {
      Serial.print(".");
    }
    wave.stop();    
  }
  if (pressed[1]) {
    playfile("BRAIN.WAV");
    while (wave.isplaying && pressed[1]) {
      Serial.print(",");
    }
    wave.stop();    
  }
  if (pressed[2]) {
    playfile("MI.WAV");
    while (wave.isplaying && pressed[2]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (pressed[3]) {
    playfile("FA.WAV");
    while (wave.isplaying && pressed[3]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (pressed[4]) {
    playfile("SO.WAV");
    while (wave.isplaying && pressed[4]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (pressed[5]) {
    playfile("LA.WAV");
    while (wave.isplaying && pressed[5]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
}



// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
  
  // ok time to play! start playback
  wave.play();
}

Nano

//tentative code for midterm
//basic setup: if PIR == LOW:
//silhouettes on and waveshield playing one file on loop
//if PIR == HIGH:
//silhouettes off, brain lights on
//and waveshield playing a different file on loop.
//this is the code for the Nano.

//define pins. I used pins 4 and 5
#define BRAIN 9          // string of LEDs for "active" viewing
//#define SILH 2          // string of LEDs for silhouette
#define PIR 12       // IR sensor on this pin
#include "LPD8806.h"    // for LED strip
#include "SPI.h"       //for LED strip
// Number of RGB LEDs in strand:
int nLEDs = 32;
// Chose 2 pins for output; can be any valid output pins:
int dataPin  = 2;
int clockPin = 3;

// First parameter is the number of LEDs in the strand.  The LED strips
// are 32 LEDs per meter but you can extend or cut the strip.  Next two
// parameters are SPI data and clock pins:
LPD8806 strip = LPD8806(nLEDs, dataPin, clockPin);

const int unoRoom = 5;  // to power the button to the room file on the uno
const int unoBrain = 6; // to power the button to the brain file ont the uno

int i = 0;

int irRead(int readPin, int triggerPin); //function prototype
int val = 0;

void setup()
{
  pinMode(BRAIN, OUTPUT);
  pinMode(PIR, INPUT);
 // pinMode(SILH, OUTPUT);
  pinMode(unoRoom, OUTPUT);
  pinMode(unoBrain, OUTPUT);
  Serial.begin(9600); 
  // prints title with ending line break 
  Serial.println("Program Starting"); 
  // wait for the long string to be sent 
  delay(100); 
    // Start up the LED strip
  strip.begin();
    // Update the strip, to start they are all 'off'
  strip.show();
}

void loop()
{  
  val = digitalRead(PIR);
  if (val == LOW) {
    digitalWrite(BRAIN, 0);
    digitalWrite(unoRoom, HIGH);
    digitalWrite(unoBrain, LOW);
      colorWipe(strip.Color(80,   80,   80), 50);  // white
  } 
  else if (val == HIGH) {
 
    colorWipe(strip.Color(0, 0, 0), 50); //no power
    digitalWrite(unoRoom, LOW);
    digitalWrite(unoBrain, HIGH);
    for (i = 0; i <255; i++) { // i starts at 0 and fades in until it's at 255
      analogWrite(BRAIN, i); //set LED to analog brightness?
      delay(10); //for viewing purposes
     }
    for (i = 255; i>0; i--) { //i starts at 255 and fades dn until it's at 0
      analogWrite(BRAIN, i); //led brightness
      delay(10); //again, viewing purposes
    }
  
  }
  Serial.println(val); //display the results
  delay(15); //wait for the string to be sent
}

void colorWipe(uint32_t c, uint8_t wait) {
  int i;

  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}