From 7f5340be95f59f74e2a10c425a1e89a6ef071979 Mon Sep 17 00:00:00 2001 From: nhjschulz Date: Sat, 17 Feb 2024 20:42:14 +0100 Subject: [PATCH] Example: BlinkUno now working --- README.md | 8 +++ examples/UnoBlink/README.md | 88 +++++++++++++++++++++++++ examples/UnoBlink/doc/BlinkClass.puml | 4 +- examples/UnoBlink/doc/BlinkOnToOff.puml | 2 +- 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 examples/UnoBlink/README.md diff --git a/README.md b/README.md index 913fcf4..1bc3e1e 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,14 @@ The process() calls are not part of the transition. They show how the delegation of the process action changed as a result of the state transition in between. +## Examples + +The remainder of this document walks through the Mario example to +demonstrate CFSM usage. There is also a working CFSM version of the +Arduino blink sketch worth a look. It is available from +[https://github.com/nhjschulz/cfsm/tree/master/examples/UnoBlink](https://github.com/nhjschulz/cfsm/tree/master/examples/UnoBlink). This minimal example +is suitable as a boilplate for own CFSM based application experiments. + # The Mario CFSM Example In this chapter we use the CFSM pattern to simulate the life cycle of the diff --git a/examples/UnoBlink/README.md b/examples/UnoBlink/README.md new file mode 100644 index 0000000..2b1372e --- /dev/null +++ b/examples/UnoBlink/README.md @@ -0,0 +1,88 @@ +# Arduino Blink with CFSM + +This is a boilerplate code example for CFSM based application. +It is build on top of Arduino and implements a CFSM version of +the "led-blink" sketch, the embedded system version of +"hello world". It build using +[PlatformIO](https://platformio.org/) and configured for +Arduino UNO. But it will run on any Arduino supported platform +with an onboard led by updating ```platform.ini```. + +## Blinking with a State Machine + +The blink sketch toggles a led with a constant frequency on +or off. This can be mapped to two FSM states, the first is +representing "On", the second "Off". The transitions +between the states happen after fixed time intervals, in +your case we use one second. + +To make this simple logic a bit more interesting, we use +different transition methods for going to on or off. + +* The On state is entered based on an event from + the main loop() function. This event is signaled + every 2 seconds + +* The On state remains active for one second and transitions + back to the Off state afterwards. + +![State Diagram](http://www.plantuml.com/plantuml/proxy?src=https://raw.githubusercontent.com/nhjschulz/cfsm/master/examples/UnoBlink/doc/BlinkState.puml) + +## CFSM Blink Example + +The example is based on the Arduino template with a main module +implementing the ```setup()``` and ```loop()``` methods. +It includes CFSM as a library using the lib_deps variable in [platformio.ini](./platformio.ini). + +~~~{.ini} +lib_deps = + https://github.com/nhjschulz/cfsm.git@>=0.1.1 +~~~ + +The following SW architecture got used: + +### Static Structure + +![State Diagram](http://www.plantuml.com/plantuml/proxy?src=https://raw.githubusercontent.com/nhjschulz/cfsm/master/examples/UnoBlink/doc/BlinkClass.puml) + +### Arduino Setup Sequence + +![Setup Sequence Diagram](http://www.plantuml.com/plantuml/proxy?src=https://raw.githubusercontent.com/nhjschulz/cfsm/master/examples/UnoBlink/doc/BlinkSetup.puml) + +### Arduino Loop Transition into OffState + +The sequence starts while CFSM is in OnState: + +![Setup Sequence Diagram](http://www.plantuml.com/plantuml/proxy?src=https://raw.githubusercontent.com/nhjschulz/cfsm/master/examples/UnoBlink/doc/BlinkOnToOff.puml) + +## Arduino Loop Transition into OnState + +The sequence starts while CFSM is in OffState: + +![Setup Sequence Diagram](http://www.plantuml.com/plantuml/proxy?src=https://raw.githubusercontent.com/nhjschulz/cfsm/master/examples/UnoBlink/doc/BlinkOffToOn.puml) + +Note the little difference between the transitions: +* OnState processes the transition inside the process operation. +* OffState does not use the process operation. The state works event based. That's why CFSM instantly returns on the process() request. + +## Running the Example + +The onboard led will toggle on and off after every second +passed when the example got flashed. Serial monitor prints +will print the progress also to a serial port. The +output looks like this: + +~~~ +OnState: enter() +OnState: LED On time has expired ! +OnState: leave() +OffState: enter() +main: turn on time reached +OffState: onEvent(42) +OffState: leave() +OnState: enter() +... +~~~ + + + diff --git a/examples/UnoBlink/doc/BlinkClass.puml b/examples/UnoBlink/doc/BlinkClass.puml index ed8bed1..ade4d08 100644 --- a/examples/UnoBlink/doc/BlinkClass.puml +++ b/examples/UnoBlink/doc/BlinkClass.puml @@ -33,9 +33,9 @@ package "CFSM" { class cfsm_Ctx { +cfsm_init() - +cfsm_transition( enterFunc: cfsm_TransitionFunction) + +cfsm_transition() +cfsm_process() - +cfsm_event( eventId : int) + +cfsm_event() } interface Operations <> { diff --git a/examples/UnoBlink/doc/BlinkOnToOff.puml b/examples/UnoBlink/doc/BlinkOnToOff.puml index 5ba8150..e42e238 100644 --- a/examples/UnoBlink/doc/BlinkOnToOff.puml +++ b/examples/UnoBlink/doc/BlinkOnToOff.puml @@ -11,7 +11,7 @@ activate Led #LightGray Arduino -> Main : loop() Main -> Cfsm : process() Cfsm -> OnState : onProcess() -alt 1second since enter of OnState +alt 1 second since enter of OnState OnState -> Cfsm: transition(OffState) Cfsm -> OnState: onLeave() Cfsm <-- OnState