Making Things Interactive

May 12, 2008

Filed under: Assignments,Cat Adams,Final Project — catadams @ 12:04 am

The automatic recycling machine is designed to bring a process that is currently only done on an industrial sale, that is, the sorting of recyclables to a smaller and more personal scale. I intend for this machine to be used primarily on college campuses and areas of high traffic. I hope for people to understand the importance of recycling by being more involved in the process.

Overall View of the Recycle-Tron

View of the interior wiring

Video of a glass bottle being recycled

Video of the Recycle-Tron getting angry at someone who doesn’t recycle

Code:

/*
—Automatic Recycling Sorter—
–Making Things Interactive Spring 08 Final Project–
—Cat Adams—
*/

//states
static int Idle = 0; //name for Idle state
static int Excited = 1; //name for Excited state
static int Angry = 2; //name for Angry state
static int BigReward = 3; //name for the post-recycling Big Reward state
static int SmallReward = 4; //name for the post-recycling Big Reward state

//regular ints
int redLED = 2; //red LED connected to digital pin 2
int blueLED = 3; //blue LED connected to digital pin 3
int greenLED = 4; //green LED connected to digital pin 4
int siren = 7; //buzzer connected to digital pin 7
int pir = 8; //pir sensor connected to digital pin 8
int currentState = Idle; //sets the beginning state to Idle
int numberCycle = 0; //sets the number of items recycled to zero

//recycling ints
int servoM = 10; //Metal sorting Servo
int Mangle; //angle at which to turn servoM, set later
int servoG = 9; //Glass-Plastic sorting servo
int Gangle; //angle at which to turn servoG, set later
int switchMetal = 12; //Metal sensing wires
int switchGlass = 11; //Glass-Plastic sorting swtich analog pin 1
int bottlesense = 13; //button switch sensing presence of a bottle
int GAngle2 = 45; //angle for servo to sort out glass (from plastic)
int PAngle = 90; //angle for servo to sort out plastic
int GAngle = 90; //angle to sort glass/plastic from metal
int MAngle = 45; //angle to sort metal
int pulseWidth; //servo variable

//program for moving the metal servo
void metalPulse(int servoM, int Mangle){
pulseWidth = (Mangle * 11) + 500;
digitalWrite(servoM, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(servoM, LOW);
delay(20);
}

//program for moving the glass/plastic servo
void glassPulse(int servoG, int Gangle){
pulseWidth = (Gangle * 11) + 500;
digitalWrite(servoG, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(servoG, LOW);
delay(20);
}

//program for pulsing just one LED at a time
void PulseOne (int pin) {
for (int i=0; i<=255; i++) { analogWrite(pin, i); delay(2); } for (int i=255; i>=0; i–) {
analogWrite(pin, i);
delay(1);
}
}

void setup(){
pinMode(switchMetal, INPUT);
pinMode(servoM, OUTPUT);
pinMode(servoG, OUTPUT);
pinMode(switchGlass, INPUT);
pinMode(siren, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(pir, INPUT);
pinMode(bottlesense, INPUT);
Serial.begin(9600);
}

void loop(){

//Idle State: all LED’s off, print “Idle” on computer screen
if (currentState == Idle) {
Serial.println(“Idle”);
//turn all the LEDs off (in case a later state does not turn an led off)
digitalWrite(blueLED, LOW);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);

delay(2000);

if (digitalRead(pir) == LOW){ //if the pir sensor is tripped, a person is near and the machine goes into Excited mode
currentState = Excited;
}
else{ //if no one is around, do nothing
currentState = Idle;
}
}
//Excited State: pulse all three LED’s, print “Excited”
if (currentState == Excited){
Serial.println(“Excited”);
delay(2000);
digitalWrite(blueLED, HIGH);
digitalWrite(greenLED, HIGH);
delay(1000);
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
delay(1000);
digitalWrite(blueLED, HIGH);
digitalWrite(greenLED, HIGH);
delay(1000);
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
delay(2000);

if (digitalRead(bottlesense) == HIGH){ //if the bottle-sensing button is pressed, the bottle is either glass or plastic
Serial.println(“glass1”);
for (Mangle=20; Mangle<=105; Mangle++){ metalPulse(servoM, Mangle); } delay (1000); if (digitalRead(switchGlass) == HIGH){ //if the glass/plastic sorting button is pressed, the servo tilts and places the bottle in the glass bin Serial.println("glass2"); for (Gangle=50; Gangle<=95; Gangle++){ glassPulse(servoG, Gangle); } delay (1000); numberCycle++; //add one to the current numberCycle count if (numberCycle <=5) { //if the new numberCycle count is less than 6, go to Small Reward state currentState = SmallReward; } else{ //if the numberCycle count exceeds 5, go to the Big Reward state currentState = BigReward; } } else{ //if the glass/plastic sorting button is NOT pressed, the servo tilts and places the bottle in the plastic bin plastic(); numberCycle++; if (numberCycle <=5) { currentState = SmallReward; } else{ currentState = BigReward; } } } else{ //if the bottle sensing button is NOT pressed if (digitalRead(switchMetal) == HIGH){ //but if the switchMetal circuit is connected, there is a metal can metal(); numberCycle++; if (numberCycle<=5){ currentState = SmallReward; } else{ currentState = BigReward; } } else{ //if neither the button sensing switch or the switchMetal circuit is connected, then currentState = Angry; //the person is not recycling, so the machine becomes angry } } } //Angry State: pulse red LED and print "Angry!!" if (currentState == Angry){ Serial.println("Angry!!"); delay(2000); digitalWrite(siren, HIGH); PulseOne(redLED); digitalWrite(siren, LOW); PulseOne(redLED); digitalWrite(siren, HIGH); PulseOne(redLED); digitalWrite(siren, LOW); delay(2000); if (digitalRead(bottlesense) == HIGH){ //the person has a second chance to recycle... see above for comments Serial.println("glass1"); for (Mangle=20; Mangle<=105; Mangle++){ metalPulse(servoM, Mangle); } delay (1000); if (digitalRead(switchGlass) == HIGH){ Serial.println("glass2"); for (Gangle=50; Gangle<=95; Gangle++){ glassPulse(servoG, Gangle); } delay (1000); numberCycle++; if (numberCycle <=5) { currentState = SmallReward; } else{ currentState = BigReward; } } else{ plastic(); numberCycle++; if (numberCycle <=5) { currentState = SmallReward; } else{ currentState = BigReward; } } } else{ if (digitalRead(switchMetal) == HIGH){ metal(); numberCycle++; if (numberCycle<=5){ currentState = SmallReward; } else{ currentState = BigReward; } } else{ currentState = Idle; } } } //Small Reward: print "Small Reward" and pulse the blue LED then the green LED if (currentState == SmallReward){ Serial.println("Small Reward"); PulseOne(blueLED); PulseOne(greenLED); PulseOne(blueLED); PulseOne(greenLED); currentState = Idle; } //Big Reward: print "Big Reward" and pulse the blue then green then red LED if (currentState == BigReward){ Serial.println("Big Reward"); PulseOne(blueLED); PulseOne(greenLED); PulseOne(redLED); PulseOne(blueLED); PulseOne(greenLED); PulseOne(redLED); currentState = Idle; } } [/sourcecode]

May 6, 2008

PIR trouble

Filed under: Cat Adams,Will Not Count Towards Your Grade — catadams @ 6:42 pm

I have been trying for a long time now to get the PIR sensor from Spark fun (found here) to work, but to no avail. Does anyone have experience with this sensor, or a similar one, and knows a sure-fire way of getting it to work? I’m trying to do a simple digital read and the numbers keep coming out all wonky.

April 30, 2008

Final Writing Assignment: Class Critique

Filed under: Assignments,Cat Adams,Final Writing Assignment — catadams @ 10:54 pm

In attempting to come up with ways to improve the class, I have yet to decide if it should be changed or left the way it is. Foremost in my mind is the loose structure. We are taught some basic coding skills and given some fundamental assignments and then left to our own devices. While some would say this lack of structure provides no basis for learning, I believe this unique environment has allowed for maximum exploration and project development. Of course, this means the students must be motivated.

I disagree with anyone who says there should be a programming prerequisite to this course. The resources are available, be it the professors, other students or the internet. I found that between those three resources, I was able to solve the problems I encountered and learn new skills.

Still, there are a few things I would add. I would require students to find more outside projects to share with the class. This is not to say that I feel the projects we did were limited by any means, but an extra push to get us to find out more about the interactive world could only be a benefit.

I wish there had been other scheduled help time during the week. Near the end of the semester Mark invited us to come to the Code Lab a few times, but I would have liked more regular after-hours help sessions.

One of the most successful things in the course was the appearance of guest lecturers. I thoroughly enjoyed them, especially knowing they were right here at CMU. I hope they present again for subsequent classes.

As an addition to the course, it might be interesting to replace the mid-semester project with a group project, or create a second class for doing group projects. It might also be more feasible that way to use some of the technology available at CMU, such as laser cutters and 3d printers. I also believe the projects created could be even more interesting and amazing than the ones we saw this semester.

Overall the course was a very successful one. While, at its core, it should not be changed, a few additions could easily make it one of the most desirable and popular architecture electives.

March 27, 2008

State Machine Assignment (Assignment 9?)

Filed under: 8: State Machine,Assignments,Cat Adams — catadams @ 12:36 am

For my state machine, I wired and coded the attract and reward states for my recycler (everything except the actual recycling process). I used two button presses for the sensors, which I realize may be a bit simplistic. I have ordered a motion sensor but it did not arrive in time to do this assignment.

I made the mistake of assuming that once I wrote the code and fixed the stupid things like adding a space to an “int” within the code when it was declared without a space, everything would work fine. Also that I would get the wiring right the first time. It might be helpful if we could quickly go over in class why it would be good to declare an int globally. I thought it would be alright to declare it within a certain “for” statement, but eventually discovered I needed to declare it in the beginning of my code with the LED’s and the sensors. Anyway, it works now. In addition to the youtube video, here is an image of my state machine in idle state and excited state.

//states
static int Idle = 0;
static int Excited = 1;
static int Angry = 2;
static int Recycling = 3;
static int BigReward = 4;
static int SmallReward = 5;

//regular ints
int redLED = 3;
int blueLED = 5;
int greenLED = 6;
int angryWait = 0;
int switchPin1 = 9;
int switchPin2 = 12;
int currentState = Idle;
int numberCycle = 0;

//program for pulsing just one LED at a time (to save space later on)
void PulseOne (int pin) {
for (int i=0; i=0; i–) {
analogWrite(pin, i);
delay(1);
}
}

void setup(){
pinMode(redLED, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(switchPin1, INPUT);
pinMode(switchPin2, INPUT);
Serial.begin(9600);
}

void loop(){

//Idle State: all LED’s off, print “Idle” on computer screen
if (currentState == Idle) {
Serial.println(“Idle”);
//turn all the LEDs off (in case a later state does not turn an led off)
digitalWrite(blueLED, LOW);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
if (digitalRead(switchPin1) == HIGH){ //if the switch is pressed, i.e. if a person is detected (I do not have the proper sensor yet…)
currentState = Excited;
}
else{ //if no one is around, do nothing
currentState = Idle;
}
delay(10);
}

//Excited State: pulse all three LED’s, print “Excited”

if (currentState == Excited){
Serial.println(“Excited”);
for(int value = 0 ; value =0; value-=5)
{
analogWrite(blueLED, value);
analogWrite(greenLED, value);
analogWrite(redLED, value);
delay(30);
}
delay(2000);
if (digitalRead(switchPin2) == HIGH){ //if a recyclable is detected, start recycling it
currentState = Recycling;
}
else{ //if nothing happens, the machine gets angry
currentState = Angry;
}
}

//Angry State: pulse red LED and print “Angry!!”

if (currentState == Angry){
Serial.println(“Angry!!”);
PulseOne(redLED);
}
delay (2000);
if (digitalRead (switchPin2) == HIGH){ //if a recyclable is detected
currentState = Recycling;
}
else{ //if nothing happens, assume the person has walked away with a guilt conscience
currentState = Idle;
}

//Recycling: this is the state during which the entire recycling process happens.
//this will have a lot more code for the final
if(currentState == Recycling){
Serial.println(“Recycling”);
numberCycle++;
if (numberCycle <=5) { //self-explanatory currentState = SmallReward; } else{ currentState = BigReward; } } //Small Reward: print "Small Reward" and pulse the blue LED then the green LED if (currentState == SmallReward){ Serial.println("Small Reward"); PulseOne(blueLED); PulseOne(greenLED); currentState = Idle; } //Big Reward: print "Big Reward" and pulse the blue then green then red LED if (currentState == BigReward){ Serial.println("Big Reward"); PulseOne(blueLED); PulseOne(greenLED); PulseOne(redLED); currentState = Idle; } } [/sourcecode]

March 24, 2008

Final Project Proposal

Filed under: Assignments,Cat Adams — catadams @ 11:33 pm

My final project will require several steps continuing from my mid term.

1)debugging of my midterm
2)implementing the state machine [rewarding]
3)fabricating the actual recycler

I will need to use an additional sensor to detect whether a bottle has been dropped into the recycler. Since most of the coding and wiring has been done for the midterm, a significant portion of time will be spent on building the physical recycler.

Schematil Diagram
final-schem.pdf

State Diagram
final-chart.pdf

Parts List:

  • Servo (2)
  • Hall sensor
  • PIR Motion Sensor
  • Push-button switch
  • LED (red, blue, green)

Construction materials:

  • plywood
  • fasteners
  • paint

March 20, 2008

State Machine Assignment

Filed under: 8: State Machine,Cat Adams — catadams @ 11:20 am

The state machine I have designed is the interaction component between my final project (the automatic recycler) and the user. The recycler rewards depending upon how many people have used the recycler that day (implementing counting), or chides the user if they do not recycle.

fsm.pdf

March 6, 2008

Mid-Term Project (Due March 6,2008)

Filed under: 7: Mid-Term Project,Cat Adams — catadams @ 1:44 am

Images/video pending, here is the schematic and code for my midterm project:

Most of the notes for the project can be found in the code itself. The glass/plastic servo works perfectly, but the metal servo keeps jerking between the two values I set for it, probably because the arduino keeps reading the hall sensor
ver and over. I need to write a code for the arduino to read the sensor only once as soon as a bottle is deposited.

midterm-schem.pdfmidterm-schem.pdf


/*

Midterm Project
Automatic Recycler
Cat Adams

NOTES:
--need to tell servos to stay at 0 degrees until a bottle is dropped
--need another sensor to tell if a bottle has been dropped (photosensor/switch/rangefinder)
--need to tell the arduino to read the hall sensor only once (or once a bottle has been dropped)
--when sorting glass/plastic, need to determine a delay time for the switch (after a certain time after glass/plastic has beens sorted from metal, if the button has not been pressed, the bottle is plastic
*/

int HallPin = 12;        //Hall Sensor
int servoMetal = 6;      //Metal sorting Servo PWM pin 6
int servoGlass = 10;     //Glass-Plastic sorting servo PWM pin 10
int switchGlass = 2;     //Glass-Plastic sorting switch pin 2
int statusPin = 13;
int switchVal;           //variable to store switch value (high or low)
int HallVal;             //variable to store Hall Sensor reading (1 or 0)
int GAngle2 = 45;        //angle for servo to sort out glass (from plastic)
int PAngle = 90;         //angle for servo to sort out plastic
int GAngle = 90;         //angle to sort glass/plastic from metal
int MAngle = 45;         //angle to sort metal
int pulseWidth;          //servo variable

void metal(){                            //function for servoMetal to sort metal from glass/plastic
pulseWidth = (MAngle * 11) + 500;
digitalWrite(servoMetal, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(servoMetal, LOW);
delay(20 - (pulseWidth/1000));
}

void glass1(){                          //function for servoMetal to sort glass/plastic from metal
pulseWidth = (GAngle * 11) + 500;
digitalWrite(servoMetal, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(servoMetal, LOW);
delay(20 - (pulseWidth/1000));
}

void glass2(){                         //function for servoGlass to sort glass from plastic

pulseWidth = (GAngle2 * 11) + 500;
digitalWrite(servoGlass, HIGH);
digitalWrite(statusPin, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(servoGlass, LOW);
digitalWrite(statusPin, LOW);
delay (20 - (pulseWidth/1000));
}

void plastic(){                         //function for servoGlass to sort plastic from glass

pulseWidth = (PAngle * 11) + 500;
digitalWrite(servoGlass, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(servoGlass, LOW);
delay (20 - (pulseWidth/1000));
}

void setup()                      //sets all the modes
{

pinMode(HallPin, INPUT);
pinMode(servoMetal, OUTPUT);
pinMode(servoGlass, OUTPUT);
pinMode(switchGlass, INPUT);
pinMode(statusPin, OUTPUT);
}

void loop()

{

HallVal = digitalRead(HallPin);        //read Hall sensor first
if (HallVal == 1){
metal();
}

if (HallVal == 0){                     //if there is no presence of metal then move to glass/plastic sorting functions
glass1();
switchVal = digitalRead(switchGlass); //read switch for presence of either glass or plastic
if (switchVal == LOW) {                //if the switch is pressed, sort for glass
glass2();

}

if (switchVal == HIGH) {              //if the switch is not pressed, sort for plastic

plastic();

}

}

}

February 28, 2008

MidTerm Proposal

Filed under: Cat Adams — catadams @ 1:58 pm

We all understand the importance of the environment, including recycling common items.  But when garbage can are too common and convenient, few of us have a second thought when it comes to tossing a soda can into a black receptacle.  Steps have been made to make recycling more convenient, but it’s far from being an enticing alternative to the garbage can.  My proposal is a 3-in-one recycling receptacle that sorts metal, glass & plastic that regards the user for recycling.

Code: Hall sensor senses presence of metal.

Switch senses weight

Rewards differently depending upon how many bottles have been recycled.

State Sequence:

Attract –> Sort –> Reward –>Attract

Concept Drawings:

Schematic Diagram:
proposal-one.jpg

February 2, 2008

Fridge Entry Detector (Updated)

Filed under: 4: Counting Sensor Input,Cat Adams — catadams @ 10:21 pm

After being informed that I did not actually fulfill the assignment of creating something that counts (although I did learn a bit about photoresistors), I revisited the assignment and added the counting portion.  When the door is opened, and then closed again, a red LED turns on.  The machine counts to three.  (Still haven’t mastered binary yet.  Or mildly understood).


/*
*Sensor Count Assignment
 *Cat Adams
 */

int phoPin = 0; // photoresistor connected to Analog 0
int ledPin1 = 13; //LED connected to pin 13
int ledPin2 = 12;  //LED connected to pin 12
int redPinA = 2;
int redPinB = 3;
int redPinC = 4;
int threshold = 512; //value of at which phoPin switches states, half of greatest value of resistance
int value = 0; //variable to store the value coming from the sensor in Analog 0
boolean isBright = false; //isBright=when phoPin detects light
//false=when phoPin does not detect light
int count = 0;

void setup() {
  pinMode(ledPin1, OUTPUT); //set the ledPin as an Output
  pinMode(ledPin2, OUTPUT); //etc
  pinMode(redPinA, OUTPUT); //etc
  pinMode(redPinB, OUTPUT); //etc
  pinMode(redPinC, OUTPUT); //etc
  Serial.begin(9600);       //set up Serial Library at 9600 bps
  pinMode(phoPin, INPUT);   //sets the photoresistor as INPUT
}

void loop() {

  while (!isBright){             //while isBright is false
    delay(50);
    digitalWrite(ledPin1, HIGH); //green light is on
    digitalWrite(ledPin2, LOW);  //red light is off
    value = analogRead(phoPin);    //read the resistance value from the sensor
    if (value >= threshold) {    //if the value of the phoPin is >512
      delay(50);
      isBright = true;           //go to true state
    }
    Serial.println(value); //computer displays message
  }
  while (isBright){              // will continue looping as long as the condition is true
    delay(50);                   //debouncing
    value = analogRead(phoPin);    //reads resistance value again
    digitalWrite(ledPin1, LOW);  //green light is off
    digitalWrite(ledPin2, HIGH); //red light flashes
    Serial.println("get out of mah fridge"); //computer displays message
    delay(50);
    digitalWrite(ledPin2, LOW);
    if (value < threshold) {     //if the value of phoPin is <512
      isBright = false;          //begin count when isBright returns to false
      count++;                  // count = count+1
    }
  }

  switch (count){                //count state
  case 1:                        // case=if
    digitalWrite(redPinA, HIGH);
    digitalWrite(redPinB, LOW);
    digitalWrite(redPinC, LOW);
    break;                      //tells program not to move onto other cases if case 1 is true
  case 2:
    digitalWrite(redPinA, HIGH);
    digitalWrite(redPinB, HIGH);
    digitalWrite(redPinC, LOW);
    break;                      //tells program not to move onto other cases if case 2 is true
  case 3:
    digitalWrite(redPinA, HIGH);
    digitalWrite(redPinB, HIGH);
    digitalWrite(redPinC, HIGH);
    break;
  default:                      //if case 1,2 and 3 are all false
    count = 0;     //if count reaches four, count resets to 0
    digitalWrite(redPinA, LOW);
    digitalWrite(redPinB, LOW);
    digitalWrite(redPinC, LOW);
    break;                     //tells program not to move onto other cases if default is true
  }

}

&#91;sourcecode&#93;

This little project is used to deter someone from stealing from your fridge.  
While the door is closed, the green light is on.  
When the door is opened and the fridge light is theoretically on, the green light turns off and the red light flashes.  A message displays on the computer screen saying "Get out of mah fridge!"

&#91;sourcecode language='cpp'&#93;

int phoPin = 0; // photoresistor connected to Analog 0
int ledPin1 = 13; //select the pin for the LED
int ledPin2 = 7;
int value = 0; //variable to store the value coming from the sensor in Analog 0

void setup() {
pinMode(ledPin1, OUTPUT); //set the ledPin as an Output
pinMode(ledPin2, OUTPUT);
Serial.begin(9600);      //set up Serial Library at 9600 bps
pinMode(phoPin, INPUT); //sets the photoresistor as INPUT
}

void loop() {
value = analogRead(phoPin);  //read the resistance value from the sensor
if (value <= 700) {          //if there is low light then...
digitalWrite(ledPin1, HIGH); //green light is on
digitalWrite(ledPin2, LOW);  //red light is off
}
else if (value >= 700) {     //if there is extreme light
digitalWrite(ledPin1, LOW);  //green light is off
digitalWrite(ledPin2, HIGH);  //red light flashes
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
Serial.println("get out of mah fridge"); //computer displays message
}
delay(50);
}

January 29, 2008

Blinky Lights!

Filed under: 3: LadyAda Tutorials,Cat Adams — catadams @ 12:14 am

After much grief and to-do (Jet and Lea know my pain), I finally got Arduino to work (as of about an hour ago) and make blinky lights and stuff:

int greenPin = 13;                // LED connected to digital pin 13
int ledPin = 12;

void setup()                    // run once, when the sketch starts
{
pinMode(ledPin, OUTPUT);      // sets the digital pin as output
pinMode(greenPin, OUTPUT);      // sets the digital pin as output
}

void loop()                     // run over and over again
{
digitalWrite(ledPin, HIGH);   // sets the LED on
digitalWrite(greenPin, LOW);
delay(1000);                  // waits for a second
digitalWrite(ledPin, LOW);    // sets the LED off
digitalWrite(greenPin, HIGH);
delay(1000);                  // waits for a second
digitalWrite(ledPin, HIGH);
digitalWrite(greenPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
digitalWrite(greenPin, LOW);
delay(500);
}

Blog at WordPress.com.