Created
July 3, 2016 11:05
-
-
Save tinkerspy/6ca5ad01e9a3477658b32c1b36e4bad9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Atm_trafficlight.h" | |
/* Add optional parameters for the state machine to begin() | |
* Add extra initialization code | |
*/ | |
Atm_trafficlight& Atm_trafficlight::begin( int pin_g, int pin_y, int pin_r ) { | |
// clang-format off | |
const static state_t state_table[] PROGMEM = { | |
/* ON_ENTER ON_LOOP ON_EXIT EVT_TIMER_G EVT_TIMER_Y EVT_TIMER_R EVT_NEXT EVT_GREEN EVT_YELLOW EVT_RED ELSE */ | |
/* GREEN */ ENT_GREEN, -1, EXT_GREEN, YELLOW, -1, -1, YELLOW, -1, YELLOW, RED, -1, | |
/* YELLOW */ ENT_YELLOW, -1, EXT_YELLOW, -1, RED, -1, RED, GREEN, -1, RED, -1, | |
/* RED */ ENT_RED, -1, EXT_RED, -1, -1, GREEN, GREEN, GREEN, YELLOW, -1, -1, | |
}; | |
// clang-format on | |
Machine::begin( state_table, ELSE ); | |
this->pin_g = pin_g; // Save the pins | |
this->pin_y = pin_y; | |
this->pin_r = pin_r; | |
pinMode( pin_g, OUTPUT ); // Set the pin modes | |
pinMode( pin_y, OUTPUT ); | |
pinMode( pin_r, OUTPUT ); | |
timer_g.set( -1 ); // Initialize the timers | |
timer_y.set( -1 ); | |
timer_r.set( -1 ); | |
return *this; | |
} | |
/* Add C++ code for each internally handled event (input) | |
* The code must return 1 to trigger the event | |
*/ | |
int Atm_trafficlight::event( int id ) { | |
switch ( id ) { | |
case EVT_TIMER_G: | |
return timer_g.expired( this ); | |
case EVT_TIMER_Y: | |
return timer_y.expired( this ); | |
case EVT_TIMER_R: | |
return timer_r.expired( this ); | |
} | |
return 0; | |
} | |
/* Add C++ code for each action | |
* This generates the 'output' for the state machine | |
* | |
* Available connectors: | |
* push( connectors, ON_CHANGE, 0, <v>, <up> ); | |
*/ | |
void Atm_trafficlight::action( int id ) { | |
switch ( id ) { | |
case ENT_GREEN: | |
digitalWrite( pin_g, HIGH ); | |
push( connectors, ON_CHANGE, 0, 0, 0 ); | |
return; | |
case EXT_GREEN: | |
digitalWrite( pin_g, LOW ); | |
return; | |
case ENT_YELLOW: | |
digitalWrite( pin_y, HIGH ); | |
push( connectors, ON_CHANGE, 0, 1, 0 ); | |
return; | |
case EXT_YELLOW: | |
digitalWrite( pin_y, LOW ); | |
return; | |
case ENT_RED: | |
digitalWrite( pin_r, HIGH ); | |
push( connectors, ON_CHANGE, 0, 2, 0 ); | |
return; | |
case EXT_RED: | |
digitalWrite( pin_r, LOW ); | |
return; | |
} | |
} | |
Atm_trafficlight& Atm_trafficlight::automatic( int g, int y, int r ) { | |
timer_g.set( g ); | |
timer_y.set( y ); | |
timer_r.set( r ); | |
return *this; | |
} | |
/* Optionally override the default trigger() method | |
* Control how your machine processes triggers | |
*/ | |
Atm_trafficlight& Atm_trafficlight::trigger( int event ) { | |
Machine::trigger( event ); | |
return *this; | |
} | |
/* Optionally override the default state() method | |
* Control what the machine returns when another process requests its state | |
*/ | |
int Atm_trafficlight::state( void ) { | |
return Machine::state(); | |
} | |
/* Nothing customizable below this line | |
************************************************************************************************ | |
*/ | |
/* Public event methods | |
* | |
*/ | |
Atm_trafficlight& Atm_trafficlight::next() { | |
trigger( EVT_NEXT ); | |
return *this; | |
} | |
Atm_trafficlight& Atm_trafficlight::green() { | |
trigger( EVT_GREEN ); | |
return *this; | |
} | |
Atm_trafficlight& Atm_trafficlight::yellow() { | |
trigger( EVT_YELLOW ); | |
return *this; | |
} | |
Atm_trafficlight& Atm_trafficlight::red() { | |
trigger( EVT_RED ); | |
return *this; | |
} | |
/* | |
* onChange() push connector variants ( slots 1, autostore 0, broadcast 0 ) | |
*/ | |
Atm_trafficlight& Atm_trafficlight::onChange( Machine& machine, int event ) { | |
onPush( connectors, ON_CHANGE, 0, 1, 1, machine, event ); | |
return *this; | |
} | |
Atm_trafficlight& Atm_trafficlight::onChange( atm_cb_push_t callback, int idx ) { | |
onPush( connectors, ON_CHANGE, 0, 1, 1, callback, idx ); | |
return *this; | |
} | |
/* State trace method | |
* Sets the symbol table and the default logging method for serial monitoring | |
*/ | |
Atm_trafficlight& Atm_trafficlight::trace( Stream & stream ) { | |
Machine::setTrace( &stream, atm_serial_debug::trace, | |
"TRAFFICLIGHT\0EVT_TIMER_G\0EVT_TIMER_Y\0EVT_TIMER_R\0EVT_NEXT\0EVT_GREEN\0EVT_YELLOW\0EVT_RED\0ELSE\0GREEN\0YELLOW\0RED" ); | |
return *this; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <Automaton.h> | |
class Atm_trafficlight: public Machine { | |
public: | |
enum { GREEN, YELLOW, RED }; // STATES | |
enum { EVT_TIMER_G, EVT_TIMER_Y, EVT_TIMER_R, EVT_NEXT, EVT_GREEN, EVT_YELLOW, EVT_RED, ELSE }; // EVENTS | |
Atm_trafficlight( void ) : Machine() {}; | |
Atm_trafficlight& begin( void ); | |
Atm_trafficlight& trace( Stream & stream ); | |
Atm_trafficlight& trigger( int event ); | |
int state( void ); | |
Atm_trafficlight& onChange( Machine& machine, int event = 0 ); | |
Atm_trafficlight& onChange( atm_cb_push_t callback, int idx = 0 ); | |
Atm_trafficlight& next( void ); | |
Atm_trafficlight& green( void ); | |
Atm_trafficlight& yellow( void ); | |
Atm_trafficlight& red( void ); | |
Atm_trafficlight& begin( int pin_g, int pin_y, int pin_r ); | |
Atm_trafficlight& automatic( int g, int y, int r ); | |
private: | |
enum { ENT_GREEN, EXT_GREEN, ENT_YELLOW, EXT_YELLOW, ENT_RED, EXT_RED }; // ACTIONS | |
enum { ON_CHANGE, CONN_MAX }; // CONNECTORS | |
atm_connector connectors[CONN_MAX]; | |
int pin_g, pin_y, pin_r; | |
atm_timer_millis timer_g, timer_y, timer_r; | |
int event( int id ); | |
void action( int id ); | |
}; | |
/* | |
Automaton::ATML::begin - Automaton Markup Language | |
<?xml version="1.0" encoding="UTF-8"?> | |
<machines> | |
<machine name="Atm_trafficlight"> | |
<states> | |
<GREEN index="0" on_enter="ENT_GREEN" on_exit="EXT_GREEN"> | |
<EVT_TIMER_G>YELLOW</EVT_TIMER_G> | |
<EVT_NEXT>YELLOW</EVT_NEXT> | |
<EVT_YELLOW>YELLOW</EVT_YELLOW> | |
<EVT_RED>RED</EVT_RED> | |
</GREEN> | |
<YELLOW index="1" on_enter="ENT_YELLOW" on_exit="EXT_YELLOW"> | |
<EVT_TIMER_Y>RED</EVT_TIMER_Y> | |
<EVT_NEXT>RED</EVT_NEXT> | |
<EVT_GREEN>GREEN</EVT_GREEN> | |
<EVT_RED>RED</EVT_RED> | |
</YELLOW> | |
<RED index="2" on_enter="ENT_RED" on_exit="EXT_RED"> | |
<EVT_TIMER_R>GREEN</EVT_TIMER_R> | |
<EVT_NEXT>GREEN</EVT_NEXT> | |
<EVT_GREEN>GREEN</EVT_GREEN> | |
<EVT_YELLOW>YELLOW</EVT_YELLOW> | |
</RED> | |
</states> | |
<events> | |
<EVT_TIMER_G index="0" access="PRIVATE"/> | |
<EVT_TIMER_Y index="1" access="PRIVATE"/> | |
<EVT_TIMER_R index="2" access="PRIVATE"/> | |
<EVT_NEXT index="3" access="PUBLIC"/> | |
<EVT_GREEN index="4" access="PUBLIC"/> | |
<EVT_YELLOW index="5" access="PUBLIC"/> | |
<EVT_RED index="6" access="PUBLIC"/> | |
</events> | |
<connectors> | |
<CHANGE autostore="0" broadcast="0" dir="PUSH" slots="1"/> | |
</connectors> | |
<methods> | |
</methods> | |
</machine> | |
</machines> | |
Automaton::ATML::end | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Automaton.h> | |
#include "Atm_trafficlight.h" | |
Atm_trafficlight trafficlight; | |
void setup() { | |
// Serial.begin( 9600 ); | |
// trafficlight.trace( Serial ); | |
trafficlight.begin( 4, 5, 6 ) // Pins 4, 5 & 6 | |
.automatic( 5000, 2000, 5000 ); // Green 5s, yellow 2s, red 5s | |
} | |
void loop() { | |
automaton.run(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the code from the Machine Building 2 tutorial:
https://github.com/tinkerspy/Automaton/wiki/Machine-building-tutorial-2