Ep. 58 - Arduino Advanced Input & Button Control, Debouncing, Counters & Multitasking

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what is going on guys Vlad with EE enthusiasts calm here in today's video we're going to be looking back at the button control in Arduino so a lot of you have been requesting and I noticed as well on the Arduino website that you're having problems sort of controlling the inputs getting different states through your buttons some of you are having trouble just bouncing so we're going to go over a fairly advanced example of what seems on first really simple but essentially what I have here just as a quick demo I have two buttons with an LED and the first button all it's doing is toggling the LED back and forth at full brightness so I'm doing a full digital right on the pen and the second one is actually dimming the LED down and it's cycling through five different states so as I mentioned a lot of you have been asking questions how can you instead of just you know a reading an input how can you toggle through different states and that's exactly what we're going to be going over so essentially we're going to be doing advanced input and button control for the Arduino Before we jump in though I want to quickly mention so there's going to be a couple of links right now on your screen the first one being - the code for this particular tutorial which resides on my github page so feel free to clone for that repository make whatever changes you need you will find all the code right there the second thing I want to mention is a built a very simple patreon page so if you want to support the channel in any way shape or form you are more than welcome to do so the donations are not going to be required we're going to be releasing videos on a regular basis regardless but they do help the production of the channel so everything is appreciated thank you guys and hopefully you enjoy the video all right so let's jump right into the code and I'm going to be walking you through the entire implementation of this we're going to be talking some of the critical points that people often miss first thing I'm doing is essentially declaring that we're going to have two inputs so like I showed you before two buttons which are going to be on pin two and three of the Arduino and I'm then declaring couple of other things so the output 10-4 the LED is going to be 10 the LED state which is what I'm going to be toggling is going to be initialized here and then I proceed with a couple of variables you don't need to pay attention to it that much right now but essentially for every input I have a different state I am keeping the last input state I'm also keeping a set of different flags which I'm going to be explaining later on in the routine input counters so essentially these are just incrementing counters whenever the input is being pressed again for each and every input which we have two of the debounce timer this is going to be used for debouncing at the input as you always should be doing on your buttons and/or other inputs so in the setup function what I have here is a for loop which goes through all of my inputs I can essentially increase this to five obviously change a couple of other things in this routine but I can really easily modify this program to you know take on 10 buttons 20 buttons whatever it might be so the first thing first obviously or you should all be familiar with this instruction so the pin mode whatever pin it is so it's 2 and 3 in my case and it's declaring it as an input this is a very important line which a lot of you have been asking me questions so the the Arduino has a routine so essentially the microcontroller on the Arduino which is def mega 328 has an internal pull-up capability which is initialized through this digital right so if you kind of think about this so you're declaring this pin as an input but then you're digitally writing to it you're writing to that same pin a high which enables the pull-up resistor and if we look at the data sheet of the atmega328 which the reference to which should be on your screen right now you will see that it has internal pull-up resistors of 20 kilo ohms which explains why I don't have a single pull-up on my bread board right now so for those of you who have been wondering why first of all which values to use 20 K is good 10 K is good as well but second of all you do not need extra resistors for your builds when it comes to buttons with the Arduino and with this particular microcontroller so you can enable that with this particular function serial WN again to output a couple of values to our screen no explanations needed and then a last but not least we're initializing the LED in our loop function so what I've done is essentially separated the different segments of the program into three different sort of major categories so we set the input flags which is essentially we get the button presses into our flags and kind of make sure that we do flag the input when it is being toggled then we resolve the input flags so we take care of the logic on the Arduino itself and then we resolve the outputs which means that we based on whatever logic we've calculated and our in this routine we are going to toggle the outputs so let's take a look at the set input Flags routine so in case you haven't seen already or you had some difficulty with the debouncing routines for your programs i'm not going to go too much into details to why i need to devise i've made a couple of videos on that before the links are going to be on your screen right now but essentially this is the debounce routine that you can find in in the file and in your examples of the arduino program and it's fairly straightforward but let's go over it just kind of for for experience so my for loop is essentially just cycling through all of my inputs if you have more than one then you're going to have to go through you know checking every single input one by one to make sure that you do capture all of them reading right so we're doing a digital read on the output so it's either high or low depending on if it's pressed or not also you need to pay attention to the fact that my buttons are in a normal unpressed state they are being pulled high and when I press the button that's being pulled low so depending on what you're expecting in your circuit you should be kind of thinking about that if the reading is not equal to the last one right so if if our current reading is different than as we press the button we are going to store the Milly's the milliseconds that the timer is on the arduino into a register and again i'm going to be reference referencing this on the screen but essentially what this returns is the number of milliseconds since the initialization of the arduino which is extremely extremely important in placing timestamps on your different inputs alright so the next if the milli so that means enough time enough time has passed between the current time and the last debounce time that we've stored right here so if if the button has been pressed for enough time or more time than the debounce delay which was 50 if we refer back to the above so if 50 milliseconds have passed since the since the last time that the output was toggled and if the reading is not equal to the input state right so if if the button is still on the grounded state right if it's still grounded for 50 millisecond we need to record the reading and if if this input state is high so once so once the button is released so think of it like this we are recording at a time and if the time has passed of more than 15 milliseconds and when we release the button we are going to set our flags so the flag for that particular input is going to go too high and if you scroll back up it's initialized to low at the beginning just to make sure that we do capture it right so think of it like this again let me walk you through this so as I press the button if for example if the button bounces within that 50 milliseconds it is not going to go and record this last time it is not going to calculate this last debounce time so it will bounce until 50 at least 50 milliseconds of straight ground have been detected and once you release the button we set our flag right so this is extremely important and then we just update the last input state so what so we can keep on toggling the button so the first question that comes to mind is why do you care about these flags well the flags are a very interesting feature which allow you to essentially have as many inputs as you want and you can record them regardless of the other ones so what is it so in very simple terms what this means is if you were to implement this function with delays or with like wave functions so for example if you say like wait for this to be high then you would be essentially bound to a single button but in this case as soon as you know you press the button you're already in this routine you're sitting in the routine and you're waiting regardless of the other buttons so let me really quickly demonstrate this to you so even though I have the second button pressed I'm still recording the inputs from the first button and once I release the second button the flag gets executed for that particular input so essentially it's not locking up your program it's what you it's kind of pseudo pseudo multi-threaded programming so to speak on your microcontroller that you you fly your input but you're still MA during all of your other like the program doesn't lock up it keeps on monitoring so this is extremely extremely useful for any of your sensors any of your any of your inputs essentially the next routine if you remember scrolling really quickly back up is resolve the input flags so right now flags are either high or low correct there's no kind of in between they're just a simple boolean so they can only be high or low so we're going through all of the inputs and if the flag for that particular input is high we execute a set of logic if it's low this whole routine just doesn't do anything right so if the flag has not been set this entire routine just simply does nothing so let's think let's think about this there's a full of things that we need to address so if the flag is high first of all we count how many how many times the button has been pressed all I'm doing is updating an input counter very simple you've seen it on top here input counter for each and every input we have that right there the second thing is what we're doing is we're updating the LED state so updating the LED state is a function which essentially sold the LED state let's scroll back up the LED state is state is an integer which is initially set to zero but as the as the flag gets toggled we update the LED state but we're also passing a variable which is RI that we create in this for loop so that it knows which input has been price so depending on we're going to see we're going to see it in that function in just a second but depending on which input which button has been pressed we do a different update on the LED and as I mentioned to you earlier the first one is just doing the stalling back and forth the other one is changing the brightness right so we do have to differentiate between the buttons what else so let's let's jump into this routine really quickly alright so the update LED state routine which it takes the input as the argument so if the input is zero which means there is this button alright so if the we can have either input 1 0 or 1 since we have only 2 buttons so therefore is 0 what we're doing is struggling between 0 and 1 what we need to account though for is that if the LED state is 0 right so imagine the LED state can either be 0 or something else so that's at 0 we're going to toggle to a 1 but if it is something else because we're still toggling the LED state with the other button we're going to bring it back to a 0 right so every single time if you're playing with the second button right so the brightness is at some you know random level we want to bring us back to a 0 followed by that we can't our will be zero and one and Underpants on your functionality you can do it in a different way you you know you can keep that state and kind of toggle in-between regardless but I'd like I'd like to bring it back to a zero state the first time a different button is pressed if else--if right so we don't want to make this as an else because we can add different inputs in the future but if the input is equal to one so that means if I'm pressing the first button what we're going to do is essentially cycle through five different states of the LEDs but the way I've done this is actually really interesting right so let me just quickly put some comments in here so for input 0 we have state 0 and 1 right so in your first button all you're doing is toggling state 0 and state 1 so to speak but for inputs 1 you're toggling States to 2 to 6 right so imagine it like this imagine that my LED state can go from 0 to 6 right greater than 5 so imagine so here is what needs to happen so if first of all if the input is 1 right so if this is if this is the button as being pressed if the LED state is 0 or 1 meaning that this is what has been controlled by this button right 0 or 1 or the LED state is greater than 5 right so we've essentially gotten through all of these cycles we're at 6 we want to bring the LED state back to 2 so it's essentially a cyclical loop right so if the input 1 is being pressed right so we're going to go we're going to make our LED state equal to 3 4 5 6 and then it's going to be again 2 3 4 5 6 and excetera right so it's gonna it's going to essentially cycle through those states and you can this is a question that came up a very very many times how can you set you know a predefined number of for your buttons and execute them one by one well this is exactly how you do it right if it's greater than five then you can cycle back to your initial state and you don't need this you know you can have this like one button and you can have a different five states in my case I have seven two which are controlled by the first button if I which are controlled by the second button and you can add more you know you can say that if it's greater than five then this one cycles and then you have another button that essentially continues on the cycle and goes like seven through ten for example for a different state any case if so coming back really quickly to the logic we set to two at the beginning otherwise we're going to cycle so lead state plus plus pretty simple so let's come back to the printer to our main resolved input Flags function so here we have the print string functionality which is essentially I'm going to be showing you this in a second but it's outputting you know which input has been pressed the counters and the number of times that it has been pressed so pretty a pretty simple output function so let's say let's take a look at that really quickly alright so let's take a look at the serial monitor which is essentially just displaying the counter for each and every button so this is my button zero this is my button one and as you can see it's a very simple counter but it's always be balanced everything is really nice and smooth like I've mentioned earlier if I do hold down one of the buttons and keep on pressing the other one because of that flag routine we do not lose any of the inputs we're not waiting for anything there's absolutely no like there's absolutely no kind of interference between the two you can play with these inputs as many times as you want there's no lock ups in the program so very very important to implement your inputs as such if you have them you know for example on a mission-critical project such as a super bot for example you always want to detect you know as soon as possible but you also don't want to lock things up so you want to keep going through your inputs keep reading them and the sort of seeing that as as they scroll through but it's actually very simple serial print for all of our counters what do we have next let's scroll back up and now we have input flags obviously if the input flags have been set to high we've processed them in our function we want to set them back to low right because we've already taken care of the logic and we don't need to do that anymore we're going to be waiting for the next button press so very very simple to implement yet very intricate routine that you guys need to be aware of the next step is going to be resolved outputs so now that we have all the counters all the variables that we essentially need all of our logic has been processed we need to figure out what do we do with the outputs right and this is it is very important to kind of split up your code into these segments because that way it becomes very modular right so right now I can rewrite this routine but I don't really care about like like my led doesn't care about the state of my logic all it cares about is the final output that it receives so essentially like we can decouple these pieces of code and use them in separate routines you know what I mean so like I can take this and use this on like 10 LEDs for all I care in a different program I don't need to rewrite this anymore but anyways let's scroll back down to our resolve outputs so this is again I only have one LED on here but you can have you know different cases for whatever states you choose to update in your logic but as I mentioned before what we have is different cases for the LED state a total of 7 so 0 through 6 and we need to take care of them with I'm doing it with a very simple switch statement you can do it with ifs else ifs if you want to but going through the switch led States so if case is 0 like I've mentioned or 1 we're switching between low and high right so if that state if the button toggles that state from zero to one we're going to be doing a low or a high if the state is between two and six I've chosen honestly arbitrary values or the output which are 30 70 100 155 and a full 255 and notice that we're doing a digital right or an analog right on the same pin so you're not restricted the Arduino doesn't restrict you to using you know if you put on an LED then you don't need to write one or the other so it's very simple to kind of switch up your routine and do very very intricate things in such a way like I mentioned before you can expand this to multiple cases you can expand this to multiple LEDs you can have you know led to state you can make this an array so you can expand this as much as possible and yeah so guys this is pretty much the entire code it will be available like I've mentioned on github so feel free to you know take the code reuse it in whatever way you need make sure to leave me some comments in the section down below make sure to LIKE the video if this is the kind of stuff that you're interested in or make sure to leave suggestions you know like I've mentioned on the other video I'm taking it taking note of some of your suggestions I know you guys want some more advanced stuff at the same time some of you want software hardware so keep them posted I'm going to be making more videos so stay tuned and if you want to contribute there's the patreon link at the bottom as well anyways see you guys in the next video take care bye
Info
Channel: EEEnthusiast
Views: 36,498
Rating: 4.9425588 out of 5
Keywords: EEEnthusiast, Vlad Romanov, Volodymyr Romanov, Arduino, Arduino button debounce, arduino button, arduino button counter, Arduino tutorial, arduino IO, arduino inputs and outputs, arduino button tutorial, arduino programming, arduino multitasking, arduino uno, arduino pull up resistor, arduino led
Id: C_w79mtOAzg
Channel Id: undefined
Length: 21min 35sec (1295 seconds)
Published: Sat May 06 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.