Making Things Interactive

March 27, 2008

wash your hands v2

Filed under: 8: State Machine, Gaku Sato — ponkotsu @ 12:38 am

This is my bathroom rig.  It annoyingly advocates sanitation by locking the door when it senses a flush until it determines that the occupant has washed his/her hands.

wyh-circuit.jpg

The black button on the right is the flush button.  Once that is pressed, the “wash your hands” LED blinks and the door locks via a solenoid deadbolt (behind protodoor).  The occupant’s intent to leave is signified by the doorknob switch (optimally a proximity sensor so no touching is necessary).  Initially it would re-remind the occupant to “wash your hands.”  If the water, which is represented by the potentiometer faucet, is turned more than a specified min threshold, the system registers that the occupant has rinsed his/her hands, but not washed them.  Pushing the which soap button tells the system that soap has been dispensed, but unless the water is running after that, it determines that the occupant is trying to trick the system!  Once the occupant has properly washed, the door unlocks and the “Thanks” LED blinks.

wash your hands!

wyh-statediagram-v2.jpg

int flushpin = 12;
int soappin = 11;
int waterpin = 5;
int lockpin = 8;
int doorpin = 2;
int thankspin = 7;
int washpin = 6;
int rinsepin = 4;
int fakepin = 3;
int state = 0;     // 0=off, 1=on, 2=rinse, 3=soap

void setup()
{
  Serial.begin(9600);
  pinMode(flushpin, INPUT);
  pinMode(soappin, INPUT);
  pinMode(waterpin, INPUT);
  pinMode(lockpin, OUTPUT);
  pinMode(doorpin, INPUT);
  pinMode(thankspin, OUTPUT);
  pinMode(washpin, OUTPUT);
  pinMode(rinsepin, OUTPUT);
  pinMode(fakepin, OUTPUT);
  digitalWrite(lockpin, LOW);
  digitalWrite(thankspin, LOW);
  digitalWrite(washpin, LOW);
  digitalWrite(rinsepin, LOW);
  digitalWrite(fakepin, LOW);
}

void loop()
{
  if(digitalRead(flushpin)==HIGH) {blink(washpin); state=1;}
  if(state>0) {digitalWrite(lockpin, HIGH);}
  if(state==1 && digitalRead(doorpin)==HIGH) {blink(washpin);}
  if(state==1 && analogRead(waterpin)<800) {state=2;}
  if(state==1 && digitalRead(soappin)==HIGH) {state=3;}
  if(state==2 && digitalRead(doorpin)==HIGH) {blink(rinsepin); state=1;}
  if(state==2 && digitalRead(soappin)==HIGH) {state=3;}
  if(state==3 && digitalRead(doorpin)==HIGH) {blink(fakepin); state=1;}
  if(state==3 && analogRead(waterpin)<800)
  {
    digitalWrite(lockpin, LOW);
    blink(thankspin);
    state=0;
  }
}

void blink(int pin)
{
    digitalWrite(pin, HIGH); delay(100);
    digitalWrite(pin, LOW); delay(100);
    digitalWrite(pin, HIGH); delay(100);
    digitalWrite(pin, LOW); delay(100);
    digitalWrite(pin, HIGH); delay(100);
    digitalWrite(pin, LOW);
}

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;
  }

}

State Machine with LEDs and buzzers

Filed under: 8: State Machine, Assignments, Lingshui Wang — lingshui @ 12:31 am

So I made a state machine consisting of 4 LEDs and a buzzer. There are 4 active states, sOff (self-explanatory), sAttract(flash lights quickly to attract passerby to it), sFirst(the first script it will run – which in this case consists of pulsing 4 lights), and sSecond(the second script – composed of pulsing 4 lights and buzzing a buzzer, this state is only activated once state one has been triggered 4 times previously).

Board Layout Picture 1
Board Layout Picture 2
Schematic

Here’s the code:

note: the compiler keeps telling me that “attractScript” was not declared, even though I clearly have it defined underneath void loop as “void attractScript”, what am I doing wrong?


const int sOff = 0;                                                    //set the case states...
const int sAttract = 1;
const int sFirst = 2;
const int sSecond = 3;

int currentState = sOff;                                               //set currentState and nextState
int nextState = sAttract;
int powerPin = 4;                                                      //on and off switch
int rangeFinder = 0;                                                   //sensor to change states
int ledA = 11;                                                         //LEDs
int ledB = 10;
int ledC = 9;
int ledD = 6;
int buzzer = 12;                                                       //buzzer
int firstCount = 0;                                                    //setup counting variables
int secondCount = 0;

void setup()
{
  pinMode(powerPin, INPUT);                                            //setting rangefinder, power pin, LEDs and buzzer
  pinMode(rangeFinder, INPUT);
  pinMode(ledA, OUTPUT);
  pinMode(ledB, OUTPUT);
  pinMode(ledC, OUTPUT);
  pinMode(ledD, OUTPUT);
  pinMode(buzzer, OUTPUT);
  Serial.begin(9600);                                                  //begin serial library at 9600 baud
}

void loop()
{
  switch(currentState)                                                 //start state machine
    {
      case sOff:                                                       //state "off"
      Serial.println("off");
      firstCount = 0;                                                  //reset counters for both state 1 and state 2
      secondCount = 0;
      if (digitalRead(powerPin) == HIGH)                               //when power pin is on....
      {
        currentState = nextState;                                      //proceed away from sOff and onto sAttract
      }
      break;
      case sAttract:                                                   //state "attract"
      Serial.println("attract");
      if (digitalRead(powerPin) == LOW)                                //if power pin is off...
      {
        currentState = sOff;                                           //turn off state machine
        nextState = sAttract;
      }
      else if (analogRead(rangeFinder) <= 50)                          //however if someone activates the machine...
      {
        currentState = sFirst;                                         //proceed to first state
      }
      else
      {
        attractScript();                                               //otherwise continue attracting passerby
      }
      break;
      case sFirst:                                                     //state "primary"
      Serial.println("first");
      if (digitalRead(powerPin) == LOW)                                //check power is on
      {
        currentState = sOff;
        nextState = sAttract;
      }
      else if ((firstCount == 4) && (analogRead(rangeFinder) <= 50))   //if state "primary" activated 4 times previously
      {
        currentState = sSecond;                                        //proceed onto state "secondary"
      }
      else if ((firstCount < 4) && (analogRead(rangeFinder) <= 50))    //if state "primary" activated less than 4 times
      {
        PulseLed(ledA);                                                //proceed with state "primary" scripts
        PulseLed(ledB);
        PulseLed(ledC);
        PulseLed(ledD);
        firstCount ++;						                           //count times state "primary" has been triggered
        secondCount = 0;					                           //reset state "secondary" count
      }
      else							                                   //if passerby leaves before state "secondary"
      {
        currentState = sAttract;                                       //return to state sAttract
      }
      break;
      case sSecond:                                                    //state "secondary"
      Serial.println("second");                                        //check if power is on
      if (digitalRead(powerPin) == LOW)
      {
        currentState = sOff;
        nextState = sAttract;
      }
      else if ((secondCount == 1) && (analogRead(rangeFinder) <= 50))  //if state "secondary" has been activated
      {
        currentState = sFirst;                                         //proceed back to state "primary"
      }
      else if ((secondCount < 1) && (analogRead(rangeFinder) <= 50))   //if state "secondary" hasnt' been activated
      {
        PulseLed(ledA);                                                //proceed onto secondary script
        PulseLed(ledB);
        PulseLed(ledC);
        PulseLed(ledD);
        buzzerScript();
        secondCount ++;						                           //start "secondary" count
        firstCount = 0;						                           //reset "primary" count
      }
      else
      {
        currentState = sAttract;                                       //if passerby leaves, go back to sAttract
      }
      break;
      default:                                                         //if default state is activated, then error
      Serial.println("ERROR: default state");
      currentState = sOff;
      nextState = sAttract;
      break;
   }
)
void PulseLed(int pin)                                                 //set pattern for pulsing LEDs
{
  for (int i=0; i<=255; i++)
  {
    analogWrite(pin, i);
    delay(4);
  }
  for (int i=255; i>=0; i--)
  {
    analogWrite(pin, i);
    delay(4);
  }
}

void attractScript()                                                   //set light pattern for state "attract"
{
  digitalWrite(ledA, HIGH);
  delay(500);
  digitalWrite(ledA, LOW);
  digitalWrite(ledB, HIGH);
  delay(500);
  digitalWrite(ledB, LOW);
  digitalWrite(ledC, HIGH);
  delay(500);
  digitalWrite(ledC, LOW);
  digitalWrite(ledD, HIGH);
  delay(500);
  digitalWrite(ledD, LOW);
}

void buzzerScript()                                                    //set script for how buzzer works
{
  digitalWrite(buzzer, HIGH);
  delay(2000);
  digitalWrite(buzzer, LOW);
  delay(500);
}

« Previous Page

Blog at WordPress.com.