#BB6
ฝัง
- เผยแพร่เมื่อ 10 ก.ย. 2024
- Finite State Machine - Part Two
► PCBWay $5 for 10 pieces www.pcbway.com
This is PART TWO of the Bacon Bytes series on a step-by-step guide on how we can move to a State Machine on the Arduino (or, indeed, any other microcontroller).
► Sketch and more in my GitHub for this video:
github.com/Ral...
To get the most of of this video ensure you have watched PART ONE first which covers the whole multitasking element of a useful State Machine that doesn't include any blocking code (such as use of the delay() 😲 statement).
Link: • #BB5 Moving your Ardui...
We briefly (ever so briefly) touch on theory😲but really concentrate on converting a State Diagram into actual Arduino-speak C++ code. It's far easier than you might think.
Moreover, it ensures your code reflects the State Diagram you draw, thus ensuring excellent robustness in your code.
You know about "enum"s? What about "class enum"s? We cover that too, and why it makes for better, more robust code.
If you really want some in-depth theory, Wikipedia has it covered:
en.wikipedia.o...
Perhaps in a future video we might even talk about Hierarchical State machines 😲
► Sketch and more in my GitHub for this video:
github.com/Ral...
► List of all my videos
(Special thanks to Michael Kurt Vogel for compiling this)
bit.ly/TH-camV...
► If you like this video please give it a thumbs up, share it and if you're not already subscribed please consider doing so and joining me on my Arduinite (and other μControllers) journey
My channel, GitHub and blog are here:
------------------------------------------------------------------
• / ralphbacon
• ralphbacon.blog
• github.com/Ral...
• buymeacoffee.c...
------------------------------------------------------------------
I'm a former college computer science instructor and I found your explanation of finite state machines right on the mark. Well done. Keep up the good work.
Wow, thanks! Moreover, thank goodness prof didn't find any glaring mistakes! 😁
You have to be the best tech hobbyist oriented teacher on TH-cam. Really enjoy all your videos!
Glad you like them!
Ralph, excellent, I applaud you for showing in real time what the end product will be or do and then explaining the process to achieve the end goal. For me, knowing where you are headed helps me to better process the steps, helps me to organize as the steps build to the final goal. So often (even good) instructions show the steps then 💥 the finished product, and the entire time I’m wondering where we’re heading.
Good point you make there, I shall bear it in mind for future videos too.
Ralph, much appreciated.
Been watching TH-cams to get answers for a number of things I’m doing for a project.
Your simple outlook helped me change my methodology on what I’m going to do.
Now I’m going to watch more of your videos to give me possible more ideas.
Glad to help! Yes, I had to modify one of my projects this week that used a finite state-machine structure. It made it much easier to change things (without introducing any weird side-effects).
Great explanation, you won't get very far programming microcontrollers without understanding this!
Indeed. Getting it drawn out on paper makes you (and me) think about all conditions and states too!
I use the library "metro" with arduino devices. It's à good code for little states machines. It's a minimal scheduler for Attmega368.
I'll check that out too, thanks for the heads-up. 👍🏻
Excellent!! Please continue with more videos related to state machines. Thank you!
Thanks, will do!
Back in the mid 1980's I did an Armed Forces Computer Maintenance Course. Everything was coded in binary, using "If, And, Or, Go To, Return" commands. After having a stroke, I finally have time to try and learn to program modern computers. These two lessons have finally opened up modern computer programing to me. Thank-you.
You're most welcome, Fergus. It can definitely make your programs much cleaner and more likely to work!
Not only a great teacher but a great producer too. How long did it take to make this 30 min of pure gold? I think we all agree that we appreciate your effort, time and skill! You did not miss your calling.
Thanks Vic. I do try and make my "productions" watchable as well as useful 😜
A good explanation of a state machine, we used similar process when programming a real time PBX. Using ON HOOK, OFF HOOK, decode DTMF tones etc. many thanks brings back old memories.
Thanks for sharing, just goes to show this is not a new approach.
Thanks so much for the state machine implementation, Ralph. I was able to completely refactor my timing-intensive project so that it runs without any delay() calls at all. One bit of advice I'd pass to your viewers is that for many use cases, you can get a huge amount of utility even with two states; I was able to solve a tricky long-press duplication just by relying on the state machine to bounce any unwanted events that don't conform to the current state.
Fantastic! I'm very happy that your coding has "improved" by using a finite state machine.
Loved that displayState method - not really shown in the video, but a neat way of not spamming your serial monitor
Nothing worse than a gazillion messages spewing out onto the serial monitor. This keeps it nice and clean. 🫧
This really helps me to aspire to coding at another level.
Love the logical flow.
Not sure, for me, the "self descriptive" statements. I was always bad at languages.
I've always felt a bit uncomfortable with, repetitive outputs "Light the 'elevator called' LED", and "Extinguish the LED", now I'm asking myself, why, I guess it's ok. At least, I think they are repeating, if I've read it right.
Thanks Ralph for these videos. Not sure I'll ever get to this level, but they are great to watch, and learn from.
Practice makes perfect, Michael. 😜
Hi Ralph, Yet another great video, it reminds me of the Switch Case I did for my Model Railway which has 10 switch case statements for routes, which are triggered by Reed Swotches under tracks so Loco has a magnet, the Mega I use has most of the Data and Analog pins used, the Case statements switch points and Aspect signals, at the Exit of the route an IR Sensor will hold till last carraige as passed, code is about 1000 lines and the main part I was helped by a member of MERG ...John
That's impressive, John. The advantage of using a State Machine is that if your State Diagram is correct then your code will be too. In your case, pretty essential. 🚂
Ralph, another well done and informative video. One thing, I understand this is just a video on the basics, in a true state machine you should verify that the state has truly changed before moving to the next state. In a case like this, using a timer in an elevator application is not telling you if the state has truly changed and could come down to a safety issue in the real world
Yes, point taken, but I think a Real World elevator program would be considerably more complex than this demo version, including umpteen safety checks!
@@RalphBacon Oh absolutely, there's more safety checks in the real world. Still all those safety fault conditions would have to be satisfied before signaling for a state change.
Thanks Ralph - I definitely caught a few more things watching your videos on FSMs that other videos glossed-over.
Glad you like them!
So years ago a operator would sit on a stool, ask “floor please”, pull some levers, and away we go. Actually a technical job to stop at the correct floor and align the car with the floor. Today that job has been replaced with a $10 Arduino. Years from now the Arduino will be replaced by “telie transport” , you’ll just think of the floor and flash bam you’ll be there. Times change.
It's called "progress", I believe. Whether you want it or not 😮
G'day Ralph. This has been an excellent mini-series, thank you! I think you found a good balance of simplicity/clarity of scenario without being trivial or getting bogged down. Just thought I'd mention the idea (and you kind of implied this in passing) that the indicators (yellow LED and buzzer) could each be encapsulated in their own state machine to handle turning on and off and timing etc and have the main Elevator state machine interact with those. Thanks again for the awesome videos :)
Glad you enjoyed it!
The thing about FSMs is that they can 'explode' quite quickly - yes, that's the official, technical term for when the number of states just gets out of hand and becomes unmanageable. The answer to this is an HSM (Hierarchical State Machine) where State Machines are embedded inside a parent State Machine. This ensures that one FSM doesn't try to do _everything_ by itself.
But that's a whole level that hobbyist Arduinites are unlikely to (want to) get to, IMHO. I don't use FSMs regularly (but would you Adam & Eve it, the project I'm working on now _does_ use one) as the simple approach of calling multiple functions in a time-slicing way that I showed in Part 1 works very well indeed. My ESP32 Web Radio works this way, and that can be very time critical if I don't want the streaming music to stutter (it doesn't).
Yours was the right video at the right time for the project I’m currently on, so many thanks. My way of state machines worked, but yours is a lot neater. Also I’m greatly cutting down on global variables because of you, so thanks again.
I’m trying to cut out ‘else’ in ‘if’ statements, which might be a good idea for a video, if not already done 👍🏾🤓
You're really taking all this on-board, well done Peter and I'm happy it's helping you.
Time management in Arduino is one of the most important topics, but I often find that when people, in the colonies at least, say they need "time management" in their program, they really mean state management and they're using some time (millis()) component to move through states. This is the best demonstration I've found on this topic. Thanks for building and sharing this!
I'm glad you found it useful!
Excellent explanation. Thank you, Ralph. You're a great teacher and your lessons have been invaluable in helping this amateur to bring little projects to life.
Glad it was helpful!
Thanks so much, I needed a simple introduction to state machines and this video is just that. Cheers!
Glad you liked it!
I’m using a state machine to build an automatic dog feeder. I like it because I can continually add complexity pretty easily. I will start with the food already staged in a tube and open it with a servo after a time delay, later I can add a dc motor driven auger to take food out of a hopper and then a pressure sensor as feedback to switch states and turn off the auger once the correct amount of food is in the tube, etc. pretty cool thanks for the explanation
Sounds great! My latest project used a Finite State Machine too, works just fine!
Great lesson Ralph. Opens up all kind of possibilities!!
I hope so! My most recent project was also written using this method and it all works just fine!
This is great! Would love to see a follow up video on more useful things you can do with State Machines. And perhaps other oddities and quirks to be aware of :-)
"...other oddities and quirks..." That's no way to refer to me 😡 how rude 😁
Your tutorials are some of the best out there that I've seen! Thank you for the time and effort you put into these. You have a new subscriber! :)
You're very welcome!
Nice to see you changed to a switch statement for the FSM. I often leave out the break in the switch statements as it can allow several switch states to perform the same action, some states do something different. The default state mops up the rest. Very easy to read.
Next some UML ;-)
UML? Oh, I was going onto Hierarchical State Machines first... 😲😂🤦♂️
@@RalphBacon did the first designs in the new Yourdon structured method (YSM), am i showing my age.
Great video as always, many thanks for sharing.
Glad you enjoyed it!
Thank You! Another key buiiding-block in my programming education. (I now understand why there are no goto statements).
OMG you mentioned the unmentionable! I remember GOTO statements from about 40 years ago in the BASIC language. A pity it was ever invented!
@@RalphBacon For me, it was 50 years ago (in Fortran). RIP 'goto'
Predictability is based on conventions/rules. C and C++ kept the “no goto” a convention, rather than a rule. This allows us to reason about scope and entry/exit of language statements and functions.
In the video, the author also added a “no blocking/no waiting convention”. This is the concept of (voluntary) time sharing, giving an element if multitasking.
Between these conventions, here are the consequences:
* goto breaks the expectations of function entry and exit, control statements. The abstraction breaks down. Some languages removes the jump/goto statement.
* Blocking breaks everyones expectations of time, that execution returns swiftly. The time “precision” is lost and things start to lag/skip events etc, bugs in time. The timing becomes unpredictable, the multitasking abstraction fails. “Preemptive” task switching prevents exclusive access to CPU time.
There are still goto statements, but it is a tool that requires extraordinarily discipline. Such discipline is best handled over to lower levels of abstraction ie the compiler. Some say time sharing is best left to the scheduler.
But note, if you do timeshareing - do not cheat by blocking! Blocking (bugs in the time domain) will bite as the complexity grows.
Thanks it has made so much sense and i feel excited to go and move forward with my code.
Great stuff! I hope it helps you greatly in your future coding.
Excellent video. I was having some difficulty with an esp32 battery powered project. Mapping out the possible states would have been a good idea in the beginning! But now I have fsm in my toolkit I have some fresh ideas. Thanks!
Glad it helped!
Great video, you explain it well, very articulate, can you explain how the random statement works random (3,8) * 1000
Thanks
To use the random number generator, you first need to _seed_ the generator, otherwise you get the same sequence of numbers each time you run the sketch (no true random numbers from a computer).
So, randomSeed(analogRead(A0)) will get some random value from the A0 pin (or other analog pin if you are actually using A0) and "seed" the generator.
Then you specify that you want a number by random(lowest, highest) and you get a number out. The lowest _includes_ the value you specify, the highest _excludes_ it, so random (3,10) means any number from 3 to 9 but not 10. What do you mean, someone screwed up that function? 😂
Multiply by whatever factor (if any) you want, so multiplying by 1000 gets you (in the above example) any an exact multiple of thousands number from 3000 to 9000.
Hi, Thank you very much. you've just saved my life.
Your video helped me so much, I was struggling with a Stepper motor that I had to control without using any library and this motor is a bipolar one, my problem was just that my code works fine because I use millis() function to update the menu on the screen to give how many steps and how much time should this motor run etc...
But when I press the button the motor starts running and my display stops updating, but now it's work completely fine after i used your method with enum class and switch case. Thank you again.
Thanks for the feedback, Ayman MIRI, I'm very glad you got it working.
Thanks for your kindly sharing in precious programming skills🫡
You are most welcome, Amos.
The easiest way to drop into the "default" case is to add in a state to your diagram, add the transitions to your existing states, then forget to implement the actual state. It sounds unlikely, but when you get state machines with dozens (or even hundreds) of states its surprisingly easy!
Yes, I can believe it.
Additionally, in an Hierarchical State Machine the default case can be used to cater for the "next level up" actions in the same way that Windows or JavaScript bubbles up events until they are captured by something (or discarded).
I like your teaching, I did something similar using interrupts, the way you do it is easier to follow the interrupts will ever be. Lee
(fyi, I did not know comments help)
Glad you like the content of this channel, Lee, great to have you on-board. Yes, comments show YT that viewers were engaged and therefore they will offer it to other YT viewers as one of their "suggested" videos. Who knew?
I remember in a Fortran class doing diagrams like yours using diamonds and boxes. I also remember those darn punchcards and waiting in the basement (all computers were in the basement, right ?) for the program to run. There was always some poor guy who would trip on the stairs and the punch cards would go flying in the air.
Those diamonds and boxes were not State Diagrams, they were flowcharts. It's how things were done in the Bad Old Days (probably before electricity ⚡ was invented to run the darn computer).
Oh, and don't mention punch cards to me. Having had to punch a few using a hand punch (with nothing printed on the card to show you whether you had done it right or not) I still have recurring nightmares about them. 😲
Great tutorial Ralph !...cheers.
Thanks for watching!
This is great information, to any 'new' programmer. With Multitask, State machine, and use of Switch statement... and keep it all nice in a flow. Cheers mate.
Glad it was helpful!
Excellent Demonstration
Glad it was helpful!
Great vid as always Ralph. I need to use switch case more often. Spent today writing if, else if, etc. Many times.
Changing the subject...... "enum" ..... How about a series on enum, typedef, struct, class. I know I'd be interested. I've used all except enum, but very rarely as I'm far from proficient at using them. I'm pretty sure that just a short vid from you would have us all understanding them clearly. Just a thought.
Cheers.
Matt.
It's certainly an idea for the Bacon Bytes series, Matt. I shall bear it in mind. 👍🏻
@@RalphBacon Cheers Ralph. You've saved my bacon (pun intended) more than a few times with your clear and consice approach.
Some years back I ran a BBS. In its idle state there was a program looking at what the modem might have to say, and which would hand off to the bbs software if a human caller connected, or perform various other actions if it were another system calling with mail, a request, or whatever. Many different protocols were implemented. I took a brief look at the source code one time, and what I found was a whole slew of different state machines, sometimes nested one within another, before I gave up on trying to understand how things worked to any level of detail. It can really get quite complicated! :-) But it really did work well, handling all sorts of stuff...
State Machine do work but can get out of hand too, if there are too many states. It's called State Explosion and is usually handled by a Hierarchical State Machine (sounds like that's what you had, nested State Machines).
A few ideas for "homework assignments" to practice with state machines:
Have one LED blink SOS in Morse code, while another blinks your name in Morse code. It can be done with two smaller state machines running concurrently, or one larger state machine.
Switch debouncing, where you do something (like toggle an LED) every time the switch is pressed. A good test is to hold the button down longer than the debounce delay. It should wait for the user to release the button (including debounce time) before recognizing another press.
Implement the classic "elevator algorithm" where the elevator goes upwards to pick up and drop off passengers until it runs out of passengers in that direction, then downwards to pick up and drop off more passengers, then upwards again, etc.
Excellent! Let me know when you've completed all that. Lucky that we've got a couple of bank holidays over Easter 😆😂👍
Well done, Ralph, it is a pleasure to learn in such a friendly, pleasant manner.
Thank you, glad you liked it!
I really enjoyed this video.
Thanks Stu, glad you enjoyed it.
Literally tons of use cases I can use this coding technique on. Thanks for the video and happy easter 🙂
Glad it was helpful! Happy Easter 🐣
I just gave this video the 1000th like
Wow! thank you so much, Bill! 👍
I found your channel and its been a great as I learn esp32 in platformio.
Welcome aboard! Yes, I use ESP32s and PlatformIO all the time now. A good combination!
Hello Ralph. Thank you again for a very informative and educational video, you have a great way of explaining coding in a way this neophyte can follow :-D I am looking forward to using your diagram for a project I'm working on and hope I may ask questions of you in the future to point me in the right direction as I continue my journey in coding. Thank you again for a excellent presentation. Be Healthy and Be Safe.
Glad you found it useful, Sal, and good luck with your project 🤞🏻
Excellent work Ralph, and yes you could add lots of extra states into the model but the only I’d argue for strongly would probably be ‘BROKEN’ ... not just because of its ubiquity in daily life but because it introduces a route to the admin-state-machine or ‘Fireman’s key’ world of additional behaviour which, most likely will be being hacked together somewhere else and the protection afforded by FSM’s can be valuable. Keep up the great work 😀👍
I had to chuckle at the thought of a BROKEN state.
What you really want is a Hierarchical State Machine where the "default" case (ie not handled) bubbles up to a higher level and is dealt with there - that would handle the BROKEN state (or any other forgotten state).
A finite state diagram is just the equivalent of a "flowchart" that programmers use when the chains of "if"s get too long, and the "ifs" have too many "else"s. Some programmers code these into a "(current state x input) --> next state" table of functions, and use a "controller" to manage the jumps.
I love the way you say "just the equivalent of..." - as though any Arduino-level coder is going to agree with this statement 🤣 (not because it is wrong but because they will not understand your comment).
As I've said many times before, this channel and its contents are all aimed at newbies and intermediate Arduino coders at best. And that's not to denigrate "bedroom coders" at all, we can't all be pro developers!
@@RalphBacon On the one hand, you have honored me by your comment! Sorry it wrong-way-rubbed you. I honestly thought I was adding constructively to the discourse -- I was not keying in a cheap smart-a$$ retort. Seriously, as I re-read my comment, the only thing I can see that may have been (albeit unintentionalbly) objectionable was my use of the word. "just."
Having said that, YOU owe me an apology. I denigrerate NO-ONE. I am myself a comp-sci teacher. I am NOT a "pro developer." I do NOT post to criticise your content. YOU invoked the idea of a FSM -- not me -- and all I said that that a FSM was nothing esoteric, it was just a way of organizing a flowchart.
😲The trouble with comments is that tone-of-voice and nuances get lost in translation!
As you inferred, I thought your comment was a dig at using an FSM as a glorified flowchart (and maybe, in some ways, it is, as it does control the flow of code execution, after all) but I obviously mistook the intention and tone - *unreserved apologies* to you, Harold.
As one of the "pro developers" I mentioned, I've seen (and been subjected to) many an ivory tower coding methodology; sometimes the current way of thinking, sometimes demanded by my employer as "that's the way we do it here"!
But FSMs can be understood pretty well by most people, including bedroom (aka hobby) coders and can make a huge improvement to not just their code, but the way they have had to _think_ about possible states when drawing the diagram - including, as I have just done with a project, to realise that what I thought was TWO states was, in fact, a SINGLE state!
Anyway, thanks for your contribution; now that I've re-read it in the proper way it most certainly does add to the discussion. 👍
You should always add a "default" to the switch block in case something modifies the memory that the state pointer / variable is at. You can also just "return" from the state machine or switch block adding a break under a return can cause some compilers to moan. The industrial way of doing the "call" function would be a debounced interrupt if they are available. A switch block is also useful if you have a lot of checking and the "if" statements are getting out of control. Very well conveyed information on FSMs, have a like.
Thanks Aaron. You have raised a good reason for always having a "default" case (to be honest I thought they were mandatory but apparently they are optional).
@@RalphBacon Yes they are optional, but any good compiler will raise a red flag, I think it is good to get in the habit of adding a default, I think in BASIC it is "case else".
Fabulous explanation, Ralph ! Thank you so much.
Glad you liked it!
Thanks for the explanation, I think I understand it. I like to program an Arduino for more then just 2 leds which flash. I have written a simple skecth for two photographers who are waiting for a train to enter a platform and then shoot each two pictures with a random pause between the flashes. But watching your explanation for state machine, I like to use more outputs of the Arduino... ;-)) I will give it a go and will try to write these flashes as (finite) states.
Flashing LEDs are all well and good for a visual demo, but most users like yourself will want to do something more useful. Start small, and expand. It's too easy to not spend enough time on drawing out all the possible states and start coding before you're ready! Don't ask how I know this. 🤦♂️
Great video, thanks. This may well be useful for my arduino project. Although I think just what was in part 1 would suffice, I'm not the best programmer so might try and implement it this way. Who knows, I might learn something!
Glad it was helpful! Yes, part 1 is certainly a good step forward, although this video describes a true Finite State Machine (which my latest project also employs).
Of course you get i "LIKE" and a comment.😊😊
Well explained, yet another friday I learn something new.👍👍👍👍
Awesome, thank you!
As it happens I'm coding my Container Bin Lid project using the same sort of model. All working as it should, of course. 😁
@@RalphBacon Of course 🤣🤣
Might be more correct to say concurrently rather than simultaneously.. Nice video, I understand finite state machines but always nice to get a refresher and it's a really good video on the subject.
Fair enough! Concurrently it is! Well, it isn't, but close enough 😁
Well to be concise the Arduino cannot do concurrent processing, it only has a single thread of code execution. You can time slice this to try and make it appear to be concurrent which a Real Time Operating System does (RTOS).
@@TheEmbeddedHobbyist I have done a lot of RTOS programming on various micros, so concurrent is the term I tend to use. It's not 100% accurate in this context but I feel it's more correct than simultaneously. Not to take anything away from the video, which I found interesting and informative and very helpful to people not only learning about Arduino's and embedded programming but more advanced programmers expanding and consolidating their knowledge.
@@Potts1966 According to the Oxford dictionary: Concurrently
Adverb at the same time; simultaneously.
According to Lexico, the word simultaneously means "At the same time". And the word concurrently means "Existing, happening, or done at the same time".
So both are not 100% correct for the describing the action of the state machine or anything performed on a single core microprocessor. I would rest my case if it was on an ESP32, which with some carful programming can run programs concurrently. I say careful as one core still has to perform all the Wifi, Bluetooth operations.
Don’t get me wrong I watch all of Ralph’s videos and find them great. And I think they are great at giving the old grey cell a bit of exercise. But I was just pointing out that with a single execution core nothing can be performed simultaneously or concurrently.
@@TheEmbeddedHobbyist Oh wow! A simple comment gets blown out of proportion! .. LOL. Relax, I think we're all on the same side here. I was associating Ralph's state machines as being similar to multiple threads of execution in an RTOS and while obviously on a single threaded processor they can't execute at the exact same time, they can execute "concurrently" and appear to run simultaneously to an observer. (concurrently being a term I learned from my OU course on operating systems that I still use to this day)
I think we're going to have to agree to disagree here. If you want to post more of your more correct explanation then go for it, I'm out.
waiting so long for part 2 - thank you
So long, Andreas? It's only been a few weeks! But thanks for hanging on 👍🏻
*Pro Tip:* I saw the title for #1 that said 2 parts, so I waited till #2 came out and then watched both. Very well done.
Dropped in here to check out what method you are using to implement a state machine. I have been using PIC MCUs for years but only recently started using the Arduino IDE for ESP32s. When programming PICs in C I usually use a function pointer as a state variable. That way I can change states by setting the state variable to a different function. Each state is represented by a function. Then a switch statement is not needed as the state variable points to the correct function to call. In my opinion the function pointer implementation is simpler to maintain.
You carry on using your function pointer if that works for you, Dan, by all means.😁
But you won't convince me that's the best approach for newbies to the concept (and subsequent programming). Once a developer understands the concepts they may well graduate to your preferred method!
Do you have a code example to show me? I'm interested to learn what you just explain! Thank!
@@12dodo37 I'm not going to post my code here. I respect the response from @RalphBacon . Perhpas some day I will have an example specific to the Arduino IDE amongst my Github repositories. My current code is written in C for a PIC Xpress board and as such would likely only cause confusion here which I don't want to do.
You just managed to show me how ignorant I am about computer coding. Not a criticism at all as I am a self taught hobbyist noob. My difficulties are really defining the state diagram correctly to start with. Often I get half way through and realise I have missed a state or it’s just plain wrong or it’s overly complicated. I hope I a
Yes, getting the State Diagram correct is paramount, Stephen; and getting it wrong is easy too, not that it ever happens to me (cough, cough 😬) like just last week as I coded up my Container Bin Lid project (still incomplete). But I fixed it and I guess we must literally go back to the drawing board, make the changes and then apply those to the code.
Thanks for this video! Many uC applications i've made I've design like a state machine and it has work great to catch bugs and user interaction
Great to hear, Roberto, thanks for posting.
@@RalphBacon thanks to you for doing such informative videos!
Another great and interesting video. It gives me ideas on programming that will eliminate the use of the delay operation. Thanks
Glad it was helpful! I'm even more glad that you are going to ditch the delay() statement 👍🏻
Great stuff.....I need to watch this a couple of more times, then possibly create some other arrangement and see if I can get that to work.
Thanks again. Jeff
Go for it!
Well done, Sir. Endlessly applicable, too.
Thanks, Greg(ory) 😜
Enjoying your coding lessons with theory and examples
Glad you like them!
You can still assign elevatorState with an integer like this:
static elevatorState currState = elevatorState(0); // IDLE
Writing it this way makes it possible to increment states. You could do something like:
int i = 4; // out of range
currState = elevatorState ( i % 3); // loops back around, assigns IDLE state
So even when "i" is out of range from the number of states, it will loop back around and pick a valid state.
Unfortunately, I would consider that using "magic numbers" and is not considered Best Practice.
Using an enum (ideally a class enum) forces you (the developer) to use meaningful state names.
I'm not sure that performing maths on a state is that meaningful, just my 2c worth! But maybe you could write a function to do that, anyway.
Great video, thanks!
Glad you liked it!
Thanks for these lectures :)
Glad you like them!
Awesome video, you help me with a school project, keep it up with these good videos!
Thanks, will do!
Great video. My code readability just went up ten points!
Nice work!
You also need a "doors closing" state and you need to queue calls from multiple floors. Your hardware should have a switch for each floor. Real elevators also need a limit switch to terminate the doors opening state and a safety switch to halt closing. These additions will require additional states and transitions.
Not in this demo, Byron 😉
I did mention a missing state (DOORS CLOSED) at the end that we would just ignore as the "boredom factor" would otherwise assert itself. But it's good to see you're obviously on top of this State Machine malarky!
Hi Ralph. I have been trying to develop an electro-mechanical puzzle game for which I needed to code a state machine without knowing what it actually is. I have relatively little knowledge on Arduino and achived this by if / else routines and functions. At some point, I realized that I need some sort of flag to record which state my system is in, and only then was I able to switch between states. I just wish I knew what it is called before and wathced these wonderful videos before so that it would have been less-painful-two weeks:)) Anyways, at least now I know how valuable this information is, thanks again.
It's actually always good to define a need and then to discover it. Whether that is a particular DIY tool or a coding technique your just KNOW that it is the right thing to use.
So good luck with rewriting your code. It won't take that long because you already know what has to be done. But do spend time on the State Diagram - it's your blueprint for a successful program.
Good comment.
Very good 🤦♂️
You missed "BACK" (!) in the intro.
excellent video as always Mr. Bacon :)
only for the people who were there before
Different video series, different intro!
Thank you so much. You are an excellent teacher.
You're very welcome!
Thanks you are awesome
Thank you too!
That "default" case in the switch statement can come in handy if writing something horribly complicated as it can trap cases that you've forgotten or haven't gotten around to writing yet. Or just don't write the entrance case and let the default pick that one up (though I would consider that sloppy coding).
Yes, the "default" can catch unexpected conditions and should always be implemented just-in-case, even if you are positive you've covered all bases!
I ALWAYS use the default case to raise "unhandled state" or similar exception, it makes that error so much simpler to debug. Never use it as a normal case.
That is a great way to program, when You need go betwin tasks, thanks for.
You're welcome!
Very cool
1. the real reason for the default is to handle errors when you add a new state and forget to add a case for it. The default should log and assert
2. next: event driven state machines....
OMG Event Driven State Machines... as if we haven't got enough on our programming concepts list! But it sounds intriguing so I will check it out 👍
Realistically, aren't all state machines event driven? In microcontroller world, IDLE is an event!
I'm kidding Ralph. This is an awesome tutorial. I know of state machines in circuit logic but wasn't familiar with the c++ data type enum.
Glad you enjoyed it!
err, I'll just get the stairs next time! - seriously it's all good stuff Ralph thanks for another useful video 😃
We all need the exercise anyway! Did you know that in the USA a "lift" company, as it was then known, was so successful in installing their "elevator" brand that a "lift" became universally known as an elevator and they lost their patent to the name! 🤷♂️
Thank you for this series of videos Ralph. They're terrific! I've been doing an Ardiuino unit with my Grade 11s and they're SO Into It!. I showed them tone() on Thursday and you'd think they were Man being given fire by me, Prometeus! The music students immediately grabbed their Bach scores and started programming the kits to play symphonies. What have I unleashed? I'll be showing these two videos to my G12s in a couple of months so the future CS and CE students will have an idea before they get to university.
I'd like a clarification. I use the "lastPressed = millis();" construct in my sketches for detecting button presses, but I define the variable as a global long type. What is the disadvantage of that strategy rather than the static variable defined in loop()? Thanks for helping me understand this. Best wishes, Gord
Using globals (spawn of the devil etc) will, of course, still work. But unless the variable has to be _globally_ available, to several functions, then it has no place in the global namespace. Put it inside the function that needs it.
One "disadvantage" of global variables is that they exist for the duration of the sketch and are thus allocated memory space. Temporary variables only exist for as long as they need to (but not static ones, they exist forever too).
One final aspect to globals. It's an easy cop-out to define a global on the basis that a couple of functions need it. It's better to pass the variable (by reference, ideally) to the functions that require it. It makes the code self-documenting too.
I suppose it's all down to how "tidy" you want the final program to be!
The timing variables should be *unsigned* otherwise at some point they will go negative and the timing comparisons will no longer work as expected
@@Bob_Burton thanks for the insight Bob!
Fantastic video
Thanks! 😃
Hello Ralph thank you for posting this informative and educational (for me) video. Using the enum class as shown in your example I have the Yellow LED on to show power is applied to the Arduino. When the button is press the Yellow LED goes off and begins Blinking the Red LED 6 times using the statement: void blink6times(){ for (int i=0; i
You need to draw a Finite State Machine diagram. That way you will have various circles representing the different states.
The loop then has, for example, a SWITCH statement and executes the code _just for the current state_ .
When the state changes (eg a timeout in your case, so the current state code will change the state to the new one), the loop will execute a different bit of code the next time around.
Make sense or too brief?
Chuck in a few interrupt requests and export the last known state to an EEPROM in the event of a power failure.
arduino has a bit of eeprom that can be used by the programmer
Yes, it can always be restarted in that case (as long as the attached hardware can also be restarted from a particular point).
U.S. 3 light stop lights have two additional states, for when the local central traffic controller is offline. They are flashing red and flashing yellow, which convert the stop light into either a 2 or 4 way stop sign. The flashing yellow like may be used to give one of the cross traffic paths preference, and means no stop required but cross with caution, the stop light is not working.
I just knew someone would tell me that I hadn't covered all bases! As a reward, Jerry, I'll let you write the state machine for all the cases now known about. Should keep you busy for a while!
Excellent! Thanks Ralph!
Glad you liked it!
Very interesting. Thanks.
Glad it was helpful!
Hi, just wanted to say thanks for this video, as always, it's really great. I don't know why or how, but as I'm plodding through my personal coding project, your videos (and Github) lands some form of a gem and that makes me stop and think. This is just a case as I'm working on a PID/BBQ project and I've just started to look at the idea of having different temperature readers; but I need to know the 'state' of the PID/controller as well as the mode in which I'm readings temps (from what type of probe or API). So having 'states' I can clearly define, in English, what and where things are at... I find it quite funny really that your videos keep on moulding my project LOL.
Thanks for these great videos!
If my videos make you stop, think and adjust your approach to coding, my work here is done. Thanks Dav! 👍🏻
Thanks Ralph!
Thanks for your visit!
Great presentation
Thank you!
Hi, this is a very interesting set of videos for beginners, like myself. Thank you. I am struggling to understand how to apply this knowledge to a project that I am trying to finish. I was wondering if you could help me? I want to run on an Arduino Mega a stepper motor and a couple of digital sensors. I am trying to spin the stepper continuously and in the same time check the sensors and somehow it is too slow between the steps of the stepper and don't know how to make the stepper spin without big breaks between the steps. Do you think you could help, please?
You will have to determine how often you must tell the stepper motor "Go!" to turn it continuously, without any stuttering or pausing.
The gap is all the time you have to run other code like sensor reading. If reading sensors is a "blocking" activity, that is, you request, say, a temperature reading but that takes 100mS, well - that's a 1/10th of a second that the stepper motor is not getting any signal from your sketch.
Part 1 of this video showed a way to split your time between various functions using millis(), but if your function tries to read a sensor that then "blocks", there's not a lot you can do about it. Your stepper motor will stop.
An alternative would be to use a "timer task" to keep the stepper motor satisfied whilst your main "loop( )" did other work (like reading sensors). The Timertask runs regardless at a frequency determined by you (eg every 10mS) to keep your stepper motor running smoothly. I did a video on Arduino timers in video #209 (and possibly #210) so you will need to do some research on this.
As you are running on a Mega2560 it will support a task scheduler (RTOS) which I did a video about recently in #244; if you need to continuously hand-hold the stepper motor it would do the job but only you will know if it's beyond your current capabilities.
I am often in an infinite state of confusion🙂
SSQQUUEEEEAAAKKK !!!!
I'm not confused, I'm confused dot com.
Great Tutorial. Thank you for getting this out to us. Just got confused about where to use the ; or : after the state name ie. IDLE: or IDLE;..
In a SWITCH statement, the CASE parts are followed by a colon after the value. Example:
switch (myVar) {
case 1:
//do stuff here
break;
case 2:
//as above including the break statement
otherwise:
What to do if none of the case statements above match
}
Hi, I always use fsm design technique. I prefer quantum-leap qm modeller free software to generate codes and modify them to use both without and with rtos ( freertos, ucosII/III). Another technique that is always used with fsm is event driven programming.
Thanks for sharing! It's certainly a very detailed approach and in case anyone else is interested in using this software, here's the link: www.state-machine.com/qm/
These two videos #BB5 & #BB6 are really critically in my development as an Arduino Robots builder. I learned so much that I will review them and STATIC, Finite State Machine with lots of Non-Blocking tricks. Many comments stating how to do it better but you correctly defend your desire to teach 'beginners'; well advance beginners and intermediate coders using MCUs.
However, I saw that you were reading a port that you set as OUTPUT about which I was completely unaware it was possible; I was not able to find docs supporting this in Arduino reference docs. Lastly, you use Cool Term instead of that built into VSC and PlatformIO; I don't think you call Cool Term from within VSC & POI, Correct?. Care to comment. BTW, Bacon Bytes are an important addition to your channel, well done albeit a bit silly at times - oh you are a Brit!
cheers, mate.
Well, I'm half a Brit, the other half is German but I'm glad you like the videos, that's the main thing. Who said Germans don't have a sense of humour? Or is that my British side? 😜
I don't call CoolTerm from within VSC, it's entirely separate which IMHO is a good thing. Especially if CoolTerm is attached to a separate FTDI Serial-to-USB adapter which then goes directly to the TX and GND of the processor - you never have to Disconnect not even when uploading new sketches via the USB cable.
There are many roads to Rome, but the one I'm treading is hopefully slow enough for beginners to get better (or just to understand the concepts). Yes, all the PROs here will always tell me I could/should have done it differently!
Great video. Very well explained. State machines are sometimes explained very differently on the web, as is the approach to programming it. This has annoyed me a bit in the past. Your video helped me a lot to better understand State Machines. Thanks very much. Now, I wonder if there will come a part 3?
You really are a glutton for punishment, Roman! 😁
@@RalphBacon Don't worry - I think you've probably all said what mattters. I don't expect a third part. You really take your time with your explanations and I really appreciate that. This also sets you apart from many other electronics channels. Keep it up. Regards.
Fantastic video!
Thank you very much!
I learned a lot. Thanks so much!!
You're so welcome!