11.07.2015 Views

arduino state machine code examples - Making Things Interactive

arduino state machine code examples - Making Things Interactive

arduino state machine code examples - Making Things Interactive

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

State <strong>machine</strong> for detecting light changes// using a photosensor and a switch, make a device that turns on// different LEDs based on whether the light is staying the same,// getting brighter or getting darker.//// the following <strong>state</strong>s exist// - off// - calibrating// - getting brighter// - getting darker// - staying the same// our <strong>state</strong>s. We could do these with #defines once we've learned// them "static" means this variable's value cannot be changed once// it's set, it's a good way to prevent yourself from accidentally// changing the value in your <strong>code</strong>.static int sOff = 0;static int sCalibrate = 1;static int sBrighter = 2;static int sDarker = 3;static int sSame = 4;// the current <strong>state</strong> we're in at any given time. We want to start in// "off", so we set the variable to sOff when we declare it.int currentState = sOff;// our our photo sensorint photoPin = 0;int startingValue = 0;int currentValue = 0;// how much noise do we allow in the sensor value? This is explained// where we use it.int noise = 5;// our on/off switchint switchPin = 2;// the LEDsint redLed = 9;int greenLed = 10;int blueLed = 11;int statusLed = 13;void setup(){pinMode(photoPin, INPUT);pinMode(switchPin, INPUT);pinMode(statusLed, OUTPUT);pinMode(redLed, OUTPUT);pinMode(blueLed, OUTPUT);pinMode(greenLed, OUTPUT);


}// if we didn't set the initial <strong>state</strong> when we created the variable,// we'd do it here. The initial <strong>state</strong> is "off" or "start" in most// <strong>state</strong> <strong>machine</strong>s, but if you only hvae active/on <strong>state</strong>s, pick an// appropriate starting <strong>state</strong>.//// currentState = sOff;Serial.begin(9600);void loop(){BlinkStatusLed();// Every time through the loop we check the <strong>state</strong> we're in with a// series of if/else if <strong>state</strong>ments. the first thing we do is check// to see if we should be in a different <strong>state</strong>. If not, then we go// ahead and do whatever this <strong>state</strong> says we should do// There probably shouldn't be anything outside of your <strong>state</strong>// <strong>machine</strong> if() <strong>state</strong>ments other than a status marker like// BlinkStatusLed(). If there's something you think should happen// that isn't in the <strong>state</strong> <strong>machine</strong>, re-think your <strong>state</strong> <strong>machine</strong>!// and yes, we could have done this with a switch <strong>state</strong>ment, but we// haven't learned those yet.// STATE OFFif (currentState == sOff) {Serial.println("off"); // from off, the only place we can go is calibrate, and that's // only if the switch is turned on if (digitalRead(switchPin) == HIGH) { currentState = sCalibrate; }}// STATE CALIBRATEif (currentState == sCalibrate) {Serial.println("calibrate"); // first, have we been turned off? if (digitalRead(switchPin) == LOW) { currentState = sOff; } else { // if we're on, calibrate our photosensor // in calibrate, we take one reading every second for a // set number of seconds, then average them and use that // as our starting value to compare against. int val = 0; int numReads = 5;


for (int i = 0; i < numReads; i++) { val += analogRead(photoPin); delay(1000); } startingValue = val / numReads; currentValue = startingValue; // we want to save startingvalue Serial.print("Starting value: "); Serial.println(startingValue); // now that we're done calibrating, change our <strong>state</strong> currentState = sSame; }}// STATE SAMEif (currentState == sSame) { Serial.println("same"); // first, have we been turned off? if (digitalRead(switchPin) == LOW) { currentState = sOff; } else { // light the LED for "same" LightSameLed(); // and reset our <strong>state</strong> SetState(); }}// STATE BRIGHTERif (currentState == sBrighter) { if (digitalRead(switchPin) == LOW) { currentState = sOff; } else { Serial.println("brighter"); LightBrighterLed(); SetState(); }}// STATE DARKERif (currentState == sDarker) { if (digitalRead(switchPin) == LOW) { currentState = sOff; } else { Serial.println("darker"); LightDarkerLed(); SetState(); }}// ERROR: STATE IS INVALIDif ((currentState < sOff) || (currentState > sSame)) {


currentState has an unrecognized value! Danger! // print an error Serial.print("BAD STATE: "); Serial.println(currentState); // Now, what should we do? go back to off? same? My personal // preference is to go back to the start <strong>state</strong>, in this case, off. // // if we were using a momentary switch to start things, we'd have // to push the momentary switch again to start the sensor. If // we're using an on/off switch, the <strong>state</strong> <strong>machine</strong> will start up // again if the switch is still in the on position. currentState = sOff;}}void SetState(){// read our photosensor and see if it's darker, lighter,// or the same, then set the <strong>state</strong> accordingly.// we use a "noise" factor when making our calculation so that minor// fluctuations in the signal do not cause the <strong>state</strong> <strong>machine</strong> to change// <strong>state</strong>.int val = analogRead(photoPin);Serial.print(currentValue);Serial.print(" ");Serial.println(val);if ((val -noise) > currentValue) {currentValue = val;currentState = sBrighter;}else if ((val + noise) < currentValue) {currentValue = val;currentState = sDarker;}else {currentState = sSame;}}void LightSameLed(){


}PulseLed(redLed);void LightBrighterLed(){PulseLed(blueLed);}void LightDarkerLed(){PulseLed(greenLed);}void PulseLed(int pin) {for (int i=0; i0; i--) { analogWrite(pin, i); delay(1);}}void BlinkStatusLed(){digitalWrite(statusLed,HIGH);delay(100);digitalWrite(statusLed,LOW);;delay(100);}State <strong>machine</strong> for switching LEDs with a switch// our <strong>state</strong>s. We could do these with #defines once we've learned// them "static" means this variable's value cannot be changed once// it's set, it's a good way to prevent yourself from accidentally// changing the value in your <strong>code</strong>.static int sOff = 0;static int sRed = 1;static int sBlue = 2;static int sGreen = 3;// the current <strong>state</strong> we're in at any given time. We want to start in// "off", so we set the variable to sOff when we declare it.int currentState = sOff;// we need to have somewhere to go when we start, so let's pick redint nextState = sRed;


our on/off switchint switchPin = 2;// the LEDsint redLed = 10;int greenLed = 11;int blueLed = 9;int statusLed = 13;int maxPulse=10;int pulseCount =0;void setup(){pinMode(switchPin, INPUT);pinMode(statusLed, OUTPUT);pinMode(redLed, OUTPUT);pinMode(blueLed, OUTPUT);pinMode(greenLed, OUTPUT);}// if we didn't set the initial <strong>state</strong> when we created the variable,// we'd do it here. The initial <strong>state</strong> is "off" or "start" in most// <strong>state</strong> <strong>machine</strong>s, but if you only hvae active/on <strong>state</strong>s, pick an// appropriate starting <strong>state</strong>.//// currentState = sOff;Serial.begin(9600);void loop(){BlinkStatusLed();// Every time through the loop we check the <strong>state</strong> we're in with a// series of if/else if <strong>state</strong>ments. the first thing we do is check// to see if we should be in a different <strong>state</strong>. If not, then we go// ahead and do whatever this <strong>state</strong> says we should do// There probably shouldn't be anything outside of your <strong>state</strong>// <strong>machine</strong> if() <strong>state</strong>ments other than a status marker like// BlinkStatusLed(). If there's something you think should happen// that isn't in the <strong>state</strong> <strong>machine</strong>, re-think your <strong>state</strong> <strong>machine</strong>!// and yes, we could have done this with a switch <strong>state</strong>ment, but we// haven't learned those yet.// STATE OFFif (currentState == sOff) {Serial.println("off");// from off, the only place we can go is calibrate, and that's


}// only if the switch is turned onif (digitalRead(switchPin) == HIGH) {currentState = nextState;}// STATE REDif (currentState == sRed) {Serial.println("red");}// first, have we been turned off?if (digitalRead(switchPin) == LOW) {currentState = sOff;nextState = sBlue;}else {PulseLed(redLed);}// STATE BLUEif (currentState == sBlue) {Serial.println("blue");// first, have we been turned off?if (digitalRead(switchPin) == LOW) {currentState = sOff;nextState = sGreen;}else {PulseLed(blueLed);}}// STATE GREENif (currentState == sGreen) {if (digitalRead(switchPin) == LOW) {currentState = sOff;nextState = sRed;}else {Serial.println("green");PulseLed(greenLed);}}// ERROR: STATE IS INVALIDif ((currentState < sOff) || (currentState > sGreen)) {// currentState has an unrecognized value! Danger!// print an errorSerial.print("BAD STATE: ");Serial.println(currentState);// Now, what should we do? go back to off? same? My personal// preference is to go back to the start <strong>state</strong>, in this case, off.


}//// if we were using a momentary switch to start things, we'd have// to push the momentary switch again to start the sensor. If// we're using an on/off switch, the <strong>state</strong> <strong>machine</strong> will start up// again if the switch is still in the on position.currentState = sOff;nextState = sRed;}void PulseLed(int pin) {for (int i=0; i=0; i--) {analogWrite(pin, i);delay(1);}}void BlinkStatusLed(){digitalWrite(statusLed,HIGH);delay(100);digitalWrite(statusLed,LOW);;delay(100);}

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!