cwr wrote:A common way of handling small embedded applications is with a state machine:Code: Select allwhile (true) {
switch (state) {
case a: do_a()
state = b
case b: do_b()
state = c
case c: do_c()
state = a
}
}
The fundamental problem is that the ESP8266 doesn't like to run continuously. It expects to wake up, do some small task, then go back to sleep again. So the "main loop" idea has to go. Finagling your way around this fundamental fact is a bad idea.
In your example, the do_a(), do_b(), and do_c() functions run continuously, which simply isn't something an ESP is designed to do. What you really want is to trap state CHANGES and have the state change code do the work. So instead of having that main loop and saying things like "state = b ;" when the state changes, instead have "state" be a hidden variable and change it by calling a function like this:
void changeState ( int new_state )
{
static int state = a ;
if ( new_state == state ) return ; // Nothing changed, so no work to do.
state = new_state ;
switch ( state )
{
case a : do_a() ; break ;
case b : do_b() ; break ;
case c : do_c() ; break ;
}
}
This doesn't do exactly what your example does - it only calls a "do_x()" function once, when the state change calls for it rather than continuously as your code does. That's not necessarily what you wanted - but it *is* what you have to do.
So, for example, suppose I want to drive a stepper motor under WiFi control - so my program is sleeping until a TCP packet arrives - that packet calls "changeState" to switch from "state=idle" to "state=spinMotor" or something. But driving a stepper motor isn't a one-time thing, you have to keep stepping it - so the "do_SpinMotor" code has to set up a timer event to cause the ESP to wake up every millisecond (or whatever) to step the stepper motor once....and then go back to sleep again. The "do_Idle" function has to cancel any existing stepper motor timer events.
Tricking the software into doing it the way you imagine is a really bad idea. This is a different way of thinking - but it doesn't prevent you from using a state machine. Quite the opposite, actually. Having a global 'state' makes this style of event-based programming much easier.
The *HUGE* win here is that if you do things like this, the ESP chip will sleep through all of the boring parts of it's day - and your battery life will almost certainly be MUCH higher!