I've made a template file for the Arduino main program that uses the libraries and functions that we have so recently been discussing:
http://www.etantdonnes.com/DATA/Arduino/template/template.ino
As you know, the Arduino system shields you from some of the nitty gritty by requiring only two methods:
- setup() -- runs once at the beginning of time (after a reset);
- loop() -- is run repeatedly thereafter;
// the setup routine runs once when you press reset:Where those methods are declared like this:
void setup()
{
MessageTask_init(); // init the message system
RunTask_init(); // init the output system
ADCTask_init(); // init the input system
return;
}
/** Do whatever necessary to initialize the message system
*/
void MessageTask_init()
{
// everyone uses comms
Serial.begin( 9600 );
// set message terminator to newline for text input
Serial.setMsgTerm('\n');
return;
}
// a global system state, just for Sudhu...
// actually... to keep track of what the system is doing
word runState;
/** Do whatever necessary to initialize the system output devices.
*/
void RunTask_init()
{
// set output modes on pins
pinMode( BPIN, OUTPUT );
// initialize running state
runState = 0;
return;
}
/** Do whatever necessary to initialize the system input devices.
*/
void ADCTask_init()
{
// set input modes on pins
pinMode( APIN, INPUT_PULLUP );
// start the ADC interrupt cycle
analogRead( 0 );
return;
}
A word about runState ... I insist on keeping track of the internal system state in order to execute sequences of behaviors and respond appropriately to inputs. So each of my programs has a global state variable which is manipulated by all the Task functions. The use of this will be more apparent if/when we get to the actual Variations Too code, but Sudhu was always teasing me about it so he gets credit here....
The loop() function does two things. Look for messages and post the MessageTask, and then do a pass through the scheduler's list of things to do. If any Tasks are ready to run, they get executed here, and then the scheduler() returns, allowing loop() to return, which then repeats itself. Note that interrupts will execute (except for brief elisions) throughout this, so new functions may be entered on the Task list at anytime.
// the loop() routine runs over and over and again forever:
void loop()
{
// see if we have a new message and post the receive task
postTask( 0, MessageTask, nMsg );
// execute the schip task scheduler
scheduler(); // schedule the world
return;
}
The actual tasks that will be executed are declared like this:
/** Task posted when there is a serial input messageAnd the rest is, as they say, just implementing stuff....
* @param nmsg -- ignored...
*/
void MessageTask( word nmsg )
{
// read the message string including '\n' terminator
// and execute user functions
return;
}
/** Posted from ADCTask to do something with new sensor values
* sState -- condensed bitmap of stuff that happened
*/
void RunTask( word sState )
{
// look at run and sensor States and do appropriate stuff
return;
}
/** Task posted when ADC averaging gets a new set of values.
**/
void ADCTask( word numADC )
{
// rummage through input stuff and set flag bits in sState
// execute RunTask(sState) after 0 millis (like real soon now)
return;
}
We'll talk about some of that stuff anon.
No comments:
Post a Comment