05 – class notes, 12 Sep 2017 — Intro to State Machines

05 – class notes, 12 Sep 2017 — Intro to State Machines

Posting code to the blog

Oops.  This didn’t make it in to my notes for class last Thursday.  One option for posting code to the blog is to use the “CodeColorer” plugin.  For your Arduino sketches switch to the Text tab and use the CodeColoer wrapper with lang=”C”

State Machines

State machines are graphs showing the relationships between various states of a system.  A light switch has a simple state machine of “on” and “off”; the transition happens by using the switch.

Here’s a state machine for a student’s MTI project from a few years ago.  It contains enough detailed information that I was able to OK the final project concept over email: MTI state machine.

Look around your environment for state machines and ask yourself, “How does this work?   How would I implement this?”

In class we looked at a simple state machine in my game that prevents cheating by keeping track of whether or not a button has been pressed and released.  Each player’s button has a state that is set to “YES” when the digitalRead() returns HIGH and set to “NO” when the digitalRead() returns LOW.

/*
The MIT License (MIT)

Copyright (c) 2014 J. Eric Townsend

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/


/*
logic_0

Some examples of logic to make a simple game using state machines.

fastest click. player A and player B click the button as
quickly as possible without holding it down. Light the LED
of the person who is ahead.

Every 25 clicks, start counting again to keep the players in
relative sync

*/


const int playerAPin = 2;
const int playerALed = 3;
int playerAPushed;
int playerACount;

const int playerBPin = 10;
const int playerBLed = 11;
int playerBPushed;
int playerBCount;

const int tieLed = 4;

const int rotateCount = 25;

// another way to use const variables is to define words that you'd
// use while talking about the sketch
const int YES = 1;
const int NO = 0;

void setup() {
pinMode(playerAPin, INPUT);
pinMode(playerALed, OUTPUT);

pinMode(playerBPin, INPUT);
pinMode(playerBLed, OUTPUT);

pinMode(tieLed, OUTPUT);
// make sure we start off with reasonable values, it's a game!
playerAPushed = 0;
playerACount = 0;

playerBPushed = 0;
playerBCount = 0;

Serial.begin(9600);
}

void loop(){

// if either player is over 25, reset them both to 0
if ((playerACount > 25) || (playerBCount > 25)) {
// "||" means "or", if ((this is true) or if (this other thing is true))
playerACount = 0;
playerBCount = 0;
}

// if they are pushing down the button, we need to see if
// they have let go of the button. We use the
// variable "playerAPushed" to keep track of previous state
// of the button
//
// this is the basic idea of a state engine in a few lines of
// code: "What was the previous state of playerA, and how
// will that change our decisions?"
if (digitalRead(playerAPin) == HIGH) {
// if playerAPushed is false, we know they have let
// go of the switch and count this as a new push
if (playerAPushed == NO) {
playerACount += 1;
playerAPushed = YES;
}
// else {
// they are holding down the button and trying to cheat!
// }
}
// but if they are not pressing the button, reset our state
else {
playerAPushed = NO;
}

// same for playerB
if (digitalRead(playerBPin) == HIGH) {
if (playerBPushed == NO) {
playerBCount += 1;
playerBPushed = YES;
}
}
else {
playerBPushed = NO;
}

// here is some code I wrote to help me debug things. I
// can comment it out and save it for future debugging.

// Serial.println("A count, pushed; B count, pushed");
// Serial.print(playerACount);
// Serial.print(" ");
// Serial.print(playerAPushed);
// Serial.print(", ");
// Serial.print(playerBCount);
// Serial.print(" ");
// Serial.println(playerBPushed);

if ((playerACount == 0) && (playerBCount == 0)) {
digitalWrite(playerBLed, LOW);
digitalWrite(playerALed, LOW);
digitalWrite(tieLed, LOW);
}
else if (playerBCount > playerACount) {
digitalWrite(playerBLed, HIGH);
digitalWrite(playerALed, LOW);
digitalWrite(tieLed, LOW);
}
else if (playerBCount > playerACount) {
digitalWrite(playerBLed, LOW);
digitalWrite(playerALed, HIGH);
digitalWrite(tieLed, LOW);
}
else { // it's a tie!
digitalWrite(playerBLed, LOW);
digitalWrite(playerALed, LOW);
digitalWrite(tieLed, HIGH);
}
}

Leave a Reply