Page 1 of 1

The joy of Finite State Machines

Posted: Tue Jan 05, 2021 8:48 am
by clanger9
While pondering options for my Vehicle Control Unit, I stumbled across the concept of Finite State Machines. Forgive me if this is already common knowledge, but somehow I missed this in my engineering training...

My worry was that as I added layers of complexity to the VCU, it would get to the point that unexpected things could start to happen. I'm sure we've all struggled to make sense of nested if...then...else statements. At the same time, the concept of a finite state machine was difficult to get my head around (and it seemed unnecessarily complicated). I thought I'd share here what I've learned, in case it's useful for anyone else grappling with the same thing...

Here's a simple example: my bike has a side stand.

When the side stand is down, I want:
  • The side stand light to come on
  • The charger to be (conditionally) enabled
  • The throttle to be held at zero
When the side stand is up, I want:
  • The side stand light to go out
  • The charger to be disabled
Beginning with just the side stand light, here's how I'd normally achieve this on an Arduino:

Code: Select all

const int stand_light_pin = LED_BUILTIN; // Use on-board LED 
const int stand_switch_pin = 2; // Switch is connected to earth on pin 2

boolean stand_switch_state = false;

void setup() {

  pinMode(stand_light_pin, OUTPUT);
  pinMode(stand_switch_pin, INPUT_PULLUP);

}

void loop() {

  stand_switch_state = digitalRead(stand_switch_pin);
  switch( stand_switch_state) {
    case true: digitalWrite(stand_light_pin, HIGH); break;
    case false: digitalWrite(stand_light_pin, LOW);
  }
}
It works, but things will get complicated very quickly. Debugging will be a challenge.
Here's the same functionality using the Automaton finite state machine library:

Code: Select all

#include <Automaton.h>

const int stand_light_pin = LED_BUILTIN; // Use on-board LED 
const int stand_switch_pin = 2; // Switch is connected to earth on pin 2

Atm_led stand_light; // create a LED output machine
Atm_button stand_switch; // create a button input machine

void setup() {

  Serial.begin( 115200 ); // for debugging output

  stand_light.begin( stand_light_pin ); // start the LED machine
         
  stand_switch.begin( stand_switch_pin ) // start the button machine
    .onPress( stand_light, stand_light.EVT_ON ) // send an ON event to the LED machine
    .onRelease( stand_light, stand_light.EVT_OFF) // send an OFF event to the LED machine
    .trace( Serial ); // log events to serial console
}

void loop() {
  automaton.run();
}
The finite state machine code seems to make much more sense to my simple engineering brain. Plus, you get easy debugging over the serial console. 8-)

If you're still unconvinced, check out this fuel gauge example.

If this is useful for anyone, I'll post some more musings as I develop the VCU...

Re: The joy of Finite State Machines

Posted: Tue Jan 05, 2021 10:24 am
by Greenbeast
clanger9 wrote: Tue Jan 05, 2021 8:48 am
If this is useful for anyone, I'll post some more musings as I develop the VCU...
Please do, I've played a bit with state machines on arduino, espresso machine and kennel door automation (both currently mothballed)

Re: The joy of Finite State Machines

Posted: Tue Jan 05, 2021 10:25 am
by DaveH
Nice one, I didn't know someone had done an FSM library for Arduino. This will come in useful.

Re: The joy of Finite State Machines

Posted: Tue Jan 05, 2021 7:01 pm
by clanger9
Glad this is of interest :)
Here's a high level VCU diagram for starters (that's all I have so far).
Dart VCU schematic.png
I'll post code/updates as I work through this...

Re: The joy of Finite State Machines

Posted: Fri Jul 30, 2021 9:28 pm
by LRBen
How did you get on with the finite state machines?
I just started my VCU coding today and it got complicated very quickly once I started to work on the charging process. I haven't even begun on reading canbus messages yet.

Re: The joy of Finite State Machines

Posted: Tue Aug 03, 2021 7:55 am
by clanger9
Not much progress lately. Still playing around with CANbus...

Re: The joy of Finite State Machines

Posted: Tue Aug 03, 2021 3:37 pm
by LRBen
Fair enough. I've made a start on the canbus side now, I don't think it will be all that bad in the end. My Canbus is pretty limited in my build to start with though. Just OI inverter and OI BMS talking to the teensy. About 2 canbus IDs.

Re: The joy of Finite State Machines

Posted: Tue Aug 03, 2021 7:44 pm
by clanger9
The main change to my design is that the "power" and "range" displays will now be CANbus instruments. The VCU will send motor power messages over CANbus to a (modified) analogue rev counter containing a stepper motor and the battery management system will send the state of charge to a 4-digit 7-segment red LED display inside the original ammeter shell. It will show a simple 100 -> 0.0 number. Temp gauge will be original, driven via PWM signal from the VCU. That way, I can keep all of the dashboard exactly as I imagine it might have looked in the late '80s... 8-)
IMG_0885.jpeg

Re: The joy of Finite State Machines

Posted: Tue Aug 03, 2021 8:48 pm
by LRBen
Nice, I'm a big fan of keeping the aesthetics as original as possible. I'm planning not to add anything to mine and just use temporary displays for anything more than what the original dash can display.

I'm currently stuck figuring out how to handle more than one Canbus ID, just found your github for the dart though and that's proving very helpful!

Re: The joy of Finite State Machines

Posted: Tue Aug 03, 2021 8:56 pm
by clanger9
Glad the GitHub is useful. I really need to add some more stuff to it...
My plan is to build the CANbus instruments using Teensy 3.2 boards. Not the cheapest solution, but they are tiny, easy to use and have on-board CAN. Space is going to be tight in that little ammeter ;-)