Understanding Arduino Interrupts | Hardware, Pin Change & Timer Interrupts

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today in the workshop we're using interrupts with the arduino we'll learn about hardware pin change and timer interrupts and we'll see how to use them to improve our code interrupts are a great feature and they're easy to use once you know how so pardon the interruption and welcome to the workshop [Music] [Applause] [Music] well hello and welcome to the workshop in today's video we are going to be working with interrupts on the arduino uno although everything we are doing today could also be applied to other arduinos and other microcontrollers because interrupts are a very important concept now we've used interrupts before here in the dronebot workshop quite a few times we've used them within our code and about four years ago i did a video about using those little speed sensors that come with those robot car kits and within that video i gave a detailed explanation of how a hardware interrupt worked but that was four years ago it was buried in another video plus there are other types of interrupts that the arduino uno is capable of and we're going to discuss those today now we're going to break with a bit of a tradition today in most of my videos you'll notice i start off by talking to you about the subject and then we move into an animated explainer that explains a bit more about the subject and then we get into some experiments etc well we're not going to jump into the animated explainer right away today we're going to move right over to the workbench and we're going to hook up an arduino uno to a couple of components we're going to write a sketch that doesn't use interrupts and then we're going to see how we can improve the performance of that sketch by using interrupts so let's head to the workbench and hook up our arduino now here's how we're going to hook up our first demonstration and it's very simple we'll use an arduino uno and we'll also need a momentary contact normally open push button switch we'll require an led you can use any color you want and a dropping resistor for that led i used a 220 ohm resistor but any value from 150 to about 470 ohms would probably work just great now we'll begin by connecting the digital output pin 13 of the arduino to one side of the dropping resistor and we'll connect the other side of the dropping resistor to the anode of the led the cathode of the led will be connected to one of the arduino's grounds digital pin 2 of the arduino will be connected to one side of our push button switch and we'll connect the other side of the push button switch to ground and that's all there is for our wiring now let's go and take a look at a bit of code we can use with this now the first sketch that we're going to run on our simple hookup is a very simple sketch that just creates an led toggle and the toggle will just allow us to press the push button to turn the led on and then depress it again to turn it off it's a very easy sketch and let's just take a look at it we'll start off by defining a couple of variables that represent both the pins that the led and the button are connected to and then we define a boolean that represents the toggle state so when it's false the led will be off when it's true the led will be on now we've got a function over here that we've defined and i'm calling it check switch and it just text the status of the switch and lights the led accordingly so within check switch we do a digital read of the button pin and if it's low we know that the switch has been pressed because the switch is wired so that when we press it it's going to connect the ground to the input and drive it low so we know that it's pressed we're going to put a little delay in there just to de-bounce the switch and that's just to present false triggering and then we're going to go and change the state of our toggle and so we just take the toggle state and we invert it so if it's high we make it low if it's low we make it high and then we write that state over to the led in order to represent our toggle state on the led pretty simple then we go into setup we set up the pin mode for the led as an output and we'll set the pin mode for the button pin and notice that we're using an input pull-up and this prevented us from having to use an external pull-up resistor we'll just use the internal 30k pull-ups that the arduino has and the loop is very simple because all we're doing is we're running our tech switch function so we just continually run check switch and check the status of the switch and drive the led accordingly so let's load this up to our board and take a look at it working and so here's my basic toggle switch setup i've got everything up on a solderless breadboard over here with my led and of course my push button switch and if i press the switch i get the led on and if i press it again i get the led off which is of course the exact operation that i was hoping for so it's a pretty simple sketch in a pretty simple circuit and as it is right now it seems to work so let's go and add something to our sketch and see if it affects the operation of our toggle so here's a slightly modified version of the last sketch and i've only really added a couple of things to it it starts off identically with the same led and switch connections defined in a boolean to represent the toggle state and we also use the same check switch function it hasn't been modified at all in the setup there's one small change and i'm starting the serial monitor over here because i want to use that to monitor something and then in the loop we start off with our check switch as we did before and here's the only change we've made i've added a five second time delay so i'm going to print to my serial monitor when the delay starts then i'm going to delay for 5000 milliseconds which is 5 seconds and then i'm going to print when the delay has been finished and then we'll start the loop and do everything over again so it's a pretty simple little modification but let's go and see if that affects the operation of our arduino so we'll load that up and check it out so now we've got our code loaded up to the board this is the code that's been modified to have the delay at the end of the loop and we'll try our toggle switch again and it doesn't seem to be working very well i'm pressing the button nothing is happening you look at my serial monitor i'm in the midst of a delay it would appear and while i'm in that delay it doesn't look like i can use my toggle switch no it's very difficult to do now some there you go sometimes you can get it to work if you happen to get it between the point where the delay stops and the delay starts but otherwise the toggle switch is pretty well non-functional and so now the circuit that we had working so well before doesn't really work at all and there must be a better way of doing this so as we've seen adding a delay into the loop really messed up our circuit it barely works at all and i think most of you can figure out why that is now of course you wouldn't really be using a long delay for no specific reason in normal code but there are things that will delay your code for example if you've got a dht22 temperature and humidity sensor and you're going to take readings on that in the loop well you've got to give that two seconds in between readings so there's a two second delay right over there you could also be doing something like driving a servo motor in which you have to wait a finite amount of time for the motor to reach his position so there are a lot of reasons why your loop might delay the code another thing about this code is if you think about it it's really a bad way of checking to see if a switch has been pressed i mean this is kind of like the child who's in the back seat of the car during the long distance road trip who every two minutes is saying are we there yet are we there yet are we there yet we're basically doing the same thing with our switch we just keep checking and saying have you been pressed have you been pressed have you been pressed and most of the time the answer is no there has to be a better way of doing something like this hey i just wanted to say that if you haven't subscribed to the youtube channel yet please do so all you have to do is click on the red subscribe button below the video and after you do that also hit the bell notification and as long as you've got notifications enabled on your youtube you'll get notified every time i make a new video by the way about twenty percent of my viewers have notifications enabled so if you're one of the 80 percent who doesn't you might want to go and check your settings okay that was a bit uncalled for but it actually served a point we were interrupted we are in the middle of having a conversation and we are interrupted by someone with a completely different topic now in this particular case the interruption was trivial and probably uncalled for but there are interruptions that can actually be very beneficial to you someone interrupting you to say excuse me but your car is on fire excuse me but there's a piano about to fall on your head those kind of interruptions are the interruptions that you probably would appreciate and you would stop doing whatever you're doing and go and deal with the situation while a microcontroller can do the same thing we can interrupt the microcontroller and what it will do is it'll take everything it's working on it'll save it into registers and then it'll go and take care of our interrupt and that's exactly what we can modify our circuit to do in order to improve it so that during the delay we can still take responses from our switch so let's learn a little bit more about how hardware interrupts work with the arduino in a typical arduino sketch we begin by declaring some variables including the libraries we'll need and perhaps defining a few functions in the setup routine we set pin modes we'll start devices and if necessary we'll run any one-time code that needs to run at the beginning of our sketch after that we enter the loop where we repeat our code indefinitely and within the loop we run the commands in sequence if we look at the sketch that we just ran you can see that we are running two main commands the check switch function which we've defined externally and the delay function we're also running a couple of serial prints as well everything in our loop is run in sequence so it starts off by running check switch while it's running check switch that's the only thing that it's doing our sketch then runs the delay and while it's running the delay that's the only thing it's doing it's not paying attention to the check switch function and of course this is the problem with our sketch that we've induced when it's running delay it's not monitoring check switch and any push button activity then is simply being ignored once it finishes running delay it'll go back and kept the check switch but it only does that momentarily which is why the operation of the switch is so intermittent and unreliable now a better way to accomplish this would be to put check switch in its own function a function that was only called when a hardware interrupt was received in this scenario the delay is still in the loop and it runs continuously if however an interrupt is received everything in the loop is stopped and put aside and the program goes and runs the function that has been called by the interrupt after the running of the check switch function is complete it goes back and runs the delay and this is a much better scenario as it won't miss any presses of our push button if we take another look at the flowchart for our program you can see that we've added another element an isr or interrupt service routine in some programming languages this is called an interrupt handler in this scenario the program runs as normal with our declarations in the start and our setup routines and then everything running in the loop repetitively however if an interrupt is received it breaks the operation from the loop and goes and runs the code in the isr once that's finished it goes back and resumes where it left off in the loop an interrupt service routine is a function that is called whenever an interrupt is received when an interrupt is received the program stops execution and runs the code in the isr the execution in the loop will resume right after the interrupt service routine has finished because it's interrupting the program the isr needs to be very fast there are several commands that can't be used at interrupt service routine functions such as delay serial and millis the interrupt service routine can call other functions but they also need to be very fast the variables used in your isr need to be defined globally as you can't define variables within an interrupt service routine you could also use the volatile declaration for those variables to prevent a compiler error this can occur because the compiler may try to optimize your code as it does not realize that the values of these variables are being modified externally to your sketch today we'll be experimenting with interrupts using the arduino uno and this device has two hardware interrupts pin 2 is interrupt 0 or interrupt vector 0 and pin 3 is interrupt vector 1. now although the uno only has two hardware interrupts this is not true of all arduino boards and here's a chart that shows you the number of interrupts for several different common arduino boards within our sketch we'll use the attach interrupt function in order to attach the interrupt to the interrupt service routine function it has the following parameters the interrupt vector is the interrupt vector number that we wish to use now this is not the pin number it is the internal number used for the interrupt we also need to define the name of the function that we're going to use as an interrupt service routine the final parameter in attach interrupt is the mode parameter and the mode parameter determines how the interrupt is triggered rising indicates that the interrupt is triggered when the input goes from low to high falling is the opposite and the interrupt is triggered when the input goes from high to low low simply means the interrupt is triggered when the input is low and change means the interrupt is triggered when it falls or rises the interrupt vector is of course a very important parameter in the attach interrupt function but it can be a confusing one as it doesn't match the pin number one way to determine the interrupt vector is to use the digital pin to interrupt function which accepts the pin number as a parameter and returns the interrupt vector number we can then modify the attach interrupt function to use the digital pin to interrupt function within it as one of its parameters using digital pin to interrupt is actually the preferred method of coding this the arduino due and zero boards also have an additional high trigger mode that the other boards don't have interrupt vectors have a priority system and only one interrupt service routine can be run at a time if you receive multiple interrupts they'll be executed in order of that priority and so now that we've learned more about hardware interrupts let's go back to our sketch and modify it to use them so here's a revised version of our sketch using interrupts to try to resolve the problem we had with the time delay now we're going to start off in a similar fashion by defining two constants to represent the led and the push button and we have our boolean that represents the toggle state and i don't know if you've noticed this word volatile in front of the boolean in the last two bits of code that was actually optional it wouldn't have made much of a difference but in this code you absolutely need to use it and the reason you need to use this is because toggle state is not going to be modified during the loop and it's quite possible that your compiler will look at it and say well we're not using this variable let's eliminate it and you don't want that to happen now we've got our check switch function it's the same function we had before with one slight modification and the modification is that the small time delay i added for debouncing the switch has been removed from it and the reason i did that is because i'm going to use tech switch as my interrupt service routine as the function that is called whenever i receive an interrupt and delay is one of those functions that you can't use in an interrupt service routine but as it turns out debouncing isn't that much of a problem and i'll show you why in a little bit otherwise kick switch is identical to what it was before it just checks to see if the switch has been pressed and if it is it toggles the toggle state variable and then drives the led accordingly now we go into setup and there's a small difference here in setup we begin with the same pin mode commands we used before and we're also using the serial monitor and here's our difference this is where we attach the interrupt to an interrupt service routine and so we use attach interrupt and then in order to determine which interrupt we're going to use the digital pin to interrupt because that makes it so much easier because we can just specify the actual pin and we'll pass it the button pin now the left next parameter over here which says check switch is the function that we want to call whenever we get an interrupt so check switch is the name of our function over here so this is our interrupt service routine and following means that we want to trigger the interrupt on a falling pulse so on a time when the interrupt goes from high to low that's when it's going to trigger and that's what's going to happen when we press our push button the push button has an internal pull up over here so it's always going to be high but when we press it it's going to go low and that's going to trigger this interrupt now if we go into the loop you'll notice that the only thing we have in the loop is our delay all of the functionality for triggering the led and switching it has been done externally by the interrupt and by this check switch function over here so all that's going to go on in our loop is a delay so let's load this up to the arduino and see if it resolves our issue with the toggle during delay so i've loaded the code with the interrupt up to the board and it's running right now and if you take a look at the serial monitor you'll see that we're in a delay period which we pretty well are always going to be in because the only thing in our loop is the delay function and so now let's try pressing our switch and as you can see we can toggle it on and we can toggle it off and it doesn't matter that the arduino is running a delay at the moment the interrupt is interrupting that it's pushing everything of the delay aside it's servicing that and it's going back to run the delay and so this works very well so as you can see an interrupt is a much better method of connecting a switch up to an arduino than just simply pulling it would be and this is one of the advantages of using hardware interrupts so as we've seen a hardware interrupt was the solution to our dilemma about how to capture the input from a push button when we have a long process like a delay running in our loop and hardware interrupts can be very very useful now on the arduino uno only two pins are hardware interrupt capable and other models of arduinos have a different number of interrupt capable pins but you might want to use more than two pins on your uno for interrupts and there is a way of doing that there is a way that you can use every i o pin on the arduino as an interrupt pin and that includes the analog pins as well and that method is called a pin chained interrupt now a pin change interrupt is not as versatile as a hardware interrupt but it still can be very useful so let's go and learn a little bit about pin change interrupts every i o pin on the arduino uno will support pin change interrupts the atmega328 processor upon which the uno is based has 24 pin change interrupt pins 20 of those pins are available on the arduino uno now as their name would apply a pin change interrupt is activated on a change of state only so it's activated when the input goes low to high or high to low the pins used with pin change interrupts are grouped into ports now all of the pins on the same port will share a pin change interrupt on the arduino uno pin change interrupts are divided into three ports port b port c and port d by the way you've probably noticed that on the uno there's a gap between pins seven and eight and the reason is this is the difference between port d and port b port b is associated with pins 8 through 13. these can also be designated with a port number or a pc int number the pc int number is the one you're going to need in order to mask or unmask that specific pin port c comprises of all the analog pins on the arduino uno remember that the analog pins can also be used in digital i o pins mport d is comprised of 8 pins from pin 0 to pin 7. note that port d also contains the transmit and receive pins as well as the two hardware interrupt pins these can also be used as pin change interrupt pins the first step in using pin change interrupts is to enable or disable the port that you wish to work with this is done with the pin change interrupt control register or the pci cr here is some sample code in which we wish to use port b you'll notice we sent the binary number to the pin change interrupt control register that has a 1 in the bit 0 position as 1 activates port b after selecting the port you wish to use with the pcicr the next step is to enable or disable the pins on that port that you want to use for pin change interrupts you'll do this by modifying the pin change mask and there are three masks one for each of the ports we'll continue our code by using pin d12 which is one of the pins in the port b group in this case we'll change pin change mask 0 and we'll send bit 4 high in order to activate pin d12 and you can see that in this code the third step is to define the interrupt service routine the names of the interrupt service routines have already been predefined for you so you will choose the interrupt service routine that corresponds the port that you are using to continue our code our interrupt service routine will be the isr pcint0 vect as this is the one for port b another register that you should be aware of is the pin change interrupt flag register or the pci fr this register is activated by any change within the pin group after activation it must be reset by writing a 1 to the corresponding register and there is one register for each port you normally don't have to worry about doing this however as it's automatically reset when the associated interrupt service routine has been triggered pin change interrupts are useful but there are some precautions you need to observe when using them remember pin change interrupts are only changed you can't get a low or you can't get a rising or a falling it is only a change and so a push button being pressed will create two interrupts one when it goes down and one when it comes back up keep in mind that since we're using ports it's quite possible to have two or more pin change interrupts on the same port and you'll need to find a way of differentiating to determine which one caused the interrupt a common method of doing this is to use global values to store the previous port values when the interrupt is triggered you can compare the previous values to the current ones to determine which pin is changed you can also use a similar technique for detecting whether it is a high or a low condition that has triggered the port so now let's go and work with pin change interrupts to demonstrate pin chained interrupts we're going to add a couple of components to the arduino uno hookup that we already have aside from the arduino uno will now require two push buttons we'll also need two leds that can be the same color or two different colors and for each led will require a dropping resistor again i'm using 220 ohms but that isn't a critical value we'll begin by connecting pin 11 to one side of a dropping resistor and the other side of that resistor will go to the led's anode we'll attach the led cathode to ground pin 13 will also go to a dropping resistor and then through to the anode of the other led the cathode of that led will also be tied to ground pin 2 will go to one side of one of the push button switches the other side of that switch will be attached to ground and pin 7 will go to the remaining push button switch whose other side is also grounded and this completes the wiring now let's go and take a look at some code we can use for pin change interrupts now the first sketch that we're going to run to experiment with pin change interrupts is simply a sketch that shows you how you read one and we're only going to be using one of our leds and switches for this sketch we'll begin by defining that led and switch so we'll define the led on pin 13 and the push button on pin 7 and as we did in our previous sketches we'll define a volatile boolean called toggle state to indicate the input state next we'll go into the setup and it's the usable things we're going to set the led up as an output and set the switch up as an input using the arduino's internal 30k pull-up resistor now we go and we set up our interrupt and we first modify the pin change interrupt control register or pci cr and we need to tell it that we want to use the pci e2 bit which is bit number three so we write a one to bit number three and that tells us we want to use port d because our switch as a matter of fact both of our switches are on port d next we have the modify the pin change mask for port d in order to tell it which of the inputs we actually want to use as interrupts and we're using pin d7 and that is bit number seven and so we take the pcm sk2 which is the mask for port d and we write bit 7 high and the rest of them low and that tells us we're going to respond the changes only on this particular bit which is pin d7 now we have no code running in the loop because everything is going to run in our interrupt service routine which is over here now the interrupt service routine name has already been predetermined because this is the isr that's going to run whenever an interrupt occurs on port d now in this particular case we only have one interrupt capable on that port so we don't need to worry about determining which pin it came from we're simply going to invert our toggle state and do what we did before write that state to the led now remember though that our interrupt is a change interrupt so we're going to get one when we press the button down and another one when we release it and the input goes back high so the operation might be a bit different at any rate let's load it up to an arduino and check it out and here's our first pin change interrupt demo now of course i've got two switches and two leds wired up but right now i'm really only using one switch so this is the switch on d7 the red one and this is the led on pin d13 and so when i press the switch you'll see the led come on when i release it the led goes off and that's actually the expected behavior because remember a pin change interrupt operates as its name would imply on a change of state and so there's a change of state when i press the button down and bring it from high to low and then when i release the button it goes from low to high because of the internal pull up resistor so there are two changes of state involved here one for button down one for button up so it really just operates like a push button that was wired in series with an led now because of the fact that you may get a little bit of bounce on this and you can't really debounce the circuit because commands like delay and millis can't be used within the interrupt service routine you may get the situation in which it operates in inverted mode you might get a couple of extra bounces here at least i found that out when i was experimenting and so it would stay on and it would turn off when you pressed it down but for the most part it's pretty reliable and uh it seemed there we go i've got it to that state now where it's on now when i press it down it goes off so you will notice that and there are other ways of doing debouncing including within hardware and that's something we'll examine another day but as a demonstration this shows that we're able to activate pin d7 which was not a hardware interrupt pin but use it as an interrupt pin with a pin change interrupt so now let's go and put all of the leds and switches to use in our next demonstration our next pin change interrupt demonstration is going to use both of the switches and both of the leds and of course you'll recall that we have the switches wired to pins d2 and d7 and d2 and d7 both happen to be on port number d so they're going to generate the same interrupt so the purpose of this sketch is to illustrate how we would differentiate between the two inputs to determine whether it came from d2 or d7 now we'll start off by defining the input and output connections to the switches and leds and so that's over here and then we have a couple of volatile booleans that represent the input state so we've got one for d2 state and one for d7 state in this setup we'll set the leds up as outputs and the switches up as inputs using the internal pull-up resistor then we'll go to the pin change interrupt control register and we'll write to bit 3 to indicate that we want to monitor port d and so this is what we've done here exactly as we did in the previous sketch now we need to go to the pin change mask and enable both pins d2 and d7 and that's done by enabling both bit number two and bit number seven and setting them to one so we've set bit number two to one and bit number seven to a one over here on the mask now once again in the loop we have no code because everything is running in the interrupt service routine which is over here this is the one that is called whenever port d has an interrupt now we need to determine whether that interrupt came from pin d2 or d7 and in this design i'm just looking for the interrupt going from high to low so a falling one i'm looking for a low condition on that pin as i'm using this as a true toggle and so i'm going to check out first of all button pin number one which is on port d2 to find out if it's low and if it is low i know this is the one that just got pressed i'm going to invert the state of my boolean i'm going to write that to the led number one and for d7 i do the exact same thing except now i'm reading button pin number two which is d7 and i'm going to use the d7 state boolean and invert it and write to the led pin 2 which is the one on pin 13. and so the operation should be that we should have a toggle and each one independently controlled by a push button although their interrupts use the same port so let's load that to the arduino and check it out so here's our two interrupts on the same port demonstration and i've got the yellow push button driving the yellow led and the red one driving the red led and it works pretty good i can press the yellow to toggle it on press it again to toggle it off do the same with the red i can have one on toggle the other one and off it's pretty good occasionally i get caught up by the debouncing thing but it's relatively stable and so this illustrates that despite the fact that both of these switches are connected to pins that are on the same port port d in this case we can still differentiate between the two different pin change interrupts and respond to them accordingly one way to simplify your work with pin change interrupts is to use a library and there are a few libraries out there for pin change interrupts although many of them are old libraries that are no longer being supported there is one that you can get through the arduino ide however go into tools and then go into library manager and in the library manager filter your search by pin change and if you scroll down to the bottom you'll see one called pin change interrupt by nico hood and this is still a valid library so we're going to go and install it and it's been installed and let's go and take a look at one of the example sketches and here we are pin change interrupt and there's one called pin change interrupt led let's open that one up and take a look at it now there's a lot of the explanation at the top over here it includes the library they define a input port which in this case is going to be pin number seven so this is where you're going to connect the push button to ground uh we're going to set that input as an input with a pull-up and we're going to use the built-in led as an output so it's used pin 13 for the led they've got a function they're going to call that i'll show you in a moment they're going to call it first inside the setup just to make sure it's functional it'll turn the led on and off for a second and then this library uses a similar method to what we use with regular interrupts to attach the pin change interrupt to a function which is going to be like the interrupt service routine so this bypasses the normal operation of pin change interrupts and allows you to use your own function and here's the blink led function itself it just basically turns the led state around it does a digital write to the led of whatever the opposite condition of the led is and this is one way to switch the input of an led i'll be showing you another way to do that in a little while as well and then on the loop again there's nothing to do because everything is being done by the library and the pin change interrupt so let's go and load that up to our arduino and check it out now here's our pin change interrupt library demonstration and this functions identically to the first piece of demo code we did we've got pin d7 the red push button hooked up and pin d13 the red led and when i press down the push button you can see that the led comes on when i release it it comes off because it is working again on a pin change interrupt so it's responding to both the change when it's down and the change when it's up again and it seems pretty stable in some ways it may even be a little more stable than the original demonstration i don't seem to have really much of an issue with debouncing this so this might be a route to go you might also find the library to be a little easier to work with than working directly by putting binary numbers into a number of registers and masks but whatever way you choose to use it i think you'll find that pin change interrupts can open up a lot of possibilities since they'll respond to every single pin on the arduino uno now there's one other type of interrupt that you can use with an arduino uno and it's something called a timer interrupt as its name would imply a timer interrupt is an interrupt that is generated after a predetermined amount of time and this can be very useful in a lot of applications if you have to take a reading of something periodically or if you need to produce an output periodically now you've already used timer interrupts without even knowing it i'm sure you have if you've ever used the pulse width modulation if you've ever used the servo library if you've ever used the tone library while you've been using the arduino's internal timers and because of that you have to be careful when you're using timer interrupt not to use a timer that's being used by another process so let's go and learn a little bit more about timer interrupts the atmega328 chip that powers the arduino uno has three internal timers they're labeled timer 0 timer 1 and timer 2. timer 0 and timer 2 are 8 bit timers whereas timer 1 is a 16 timer the timers are driven by the arduino's internal clock source and the arduino uno uses a 16 megahertz clock oscillator each cycle of the clock is considered to be a tick for the timer and is the minimum amount of time that the timer can time with a 16 megahertz oscillator each tick will be 62.5 nanoseconds long 62.5 nanoseconds is a pretty short period of time so the chip also has an internal prescaler in order to divide the oscillator down by some preset numbers using the prescaler we can divide our 16 megahertz clock down to as low as 15.625 kilohertz which is a time period of 64 microseconds each timer has its own set of bits to determine the prescaler value for timer 0 the cs02 cs01 and cs00 bits determine the value of the prescaler note that it can also be set for no clock source which stops the timers or for an external clock source timer 1 the 16-bit timer is handled the same way as timer 0 except it uses the cs12 cs11 and cs10 bits instead timer 2 which is another 8-bit timer has a limited number of selections for the prescaler you can just simply set it for no clock source or for four different prescaler values note that you can't use an external clock source with time or two an interrupt is generated when a timer reaches a specific value or count in compare match mode that specific value can be stored in the compare match register once the value has been matched the timer will clear or set itself to zero so that it can start over again it can also be operated in overflow mode where an interrupt is generated when the timer overflows its count the timer frequency can therefore be set by changing the value of both the prescaler and the compare match register and this is the formula for doing this clock indicates the clock frequency and notice the addition of the one at the end that is because the compare match register starts with a base of zero and not one using this formula we can determine the value that we need to get a one hertz signal or one pulse per second out of our timer in order to get the compare match register value we can turn the formula around as shown over here so as you can see we arrive at a value of 15624 if we want a one hertz output and we are using a prescaler of 1024. the names for the interrupt service routine functions have already been predetermined for the timer interrupts and these are the names for both the compare match mode and the overflow mode note that the small case x in both of these names would be replaced by the number of the timer so timer 0 timer 1 or timer 2. so now that we know a little bit more about timer interrupts let's write some simple code to put them to use now in this experiment we're going to use timer1 to drive an led and to flash it on and off in other words we're going to be doing the blink sketch and as we're going to be using the led on pin 13 there's no additional hookup required for this experiment because the arduino uno has a built-in led on pin 13. if you still have the demo wired up that we used for hardware interrupts you can use this as well for our demonstration as it has an led on pin 13. so we'll start the code off by defining the connection for that led on pin 13 and then we also define another variable an integer that's going to be the compare match register value which as you recall sets the output frequency of the timer along with the prescaler now over here is our interrupt service routine and as i showed you earlier the name has already been predetermined for us and since we're using comparison mode for timer 1 this is the interrupt service routine that we'll be making use of now we're going to preload our timer with the compare match value when this is called because when this is called our timer has been triggered and is down to zero again so we're going to basically reset it to that value again every time we run this and then we're going to flip the value of the led if it's on we'll turn it off if it's off we'll turn it on and this is an interesting way of doing it we're doing a digital right to the led pin and what we're writing to it is the inverse of the current state of the led pin which is determined with a digital read so that's just another way of flipping the value of the led and it has an advantage in that it's very fast and of course in an interrupt service routine that is very important now we'll go into the setup and we'll set up our led as an output and then we will disable all of the interrupts we don't want an interrupt to occur while we're running the setup we're going to initialize timer1 and you do that by setting these two registers to a value of zero and then we're going to set the compare match a variable now the compare match register value was determined by the formula that it showed you in the explainer for the timers and so for a prescaler value of 256 i came up with a compare match value of 31 to 46 and that will output a frequency of 2 hertz in other words our led is going to turn on and off all within the period of a second that's going to be a period of a half a second on and a half a second off over here and of course you could change that by altering the value or if you wish by changing the prescaler that you're going to use now so we set our timer compare max value to 31 249 value that i determined and then we're going to preload it as we did earlier then we'll set our prescaler up now you remember the prescaler for timer 1 is determined by a number of different bits and in this case bit cs12 needs to be set to a 1 so we're going to set that we don't need to set the 0 bits because they're automatically implied and now we're going to enable our timer for compare mode we could also have enabled it for overflow mode if we wanted to but this sets it into compare mode and then finally we're going to reestablish all of the interrupts now that everything is set up and if we go down into the loop you'll notice there's absolutely nothing everything here is being done by the timer and by the interrupt service routine over here and so there's no code in the loop and yet we'll be able to make a blink sketch without any code in the loop so let's load this up to our arduino and watch it in action and now here's our demonstration fascinating as it might be i'm using the same hookup that i used to the hardware interrupt experiments so you'll note that i still have a push button on my sawdust breadboard although it's not being used in this circuit and we can plainly see that the led is flashing right now and again i think the interesting thing about this is that there is no code in the loop the led is just flashing because it's responding to a timer interrupt and if you have something that you need to do such as sample a sensor on a specific period of time the dht22 sensor for example it needs a sample every two seconds a timer interrupt is an ideal way of accomplishing this so that concludes our look at interrupts i hope that you enjoyed it and more importantly i hope that it's inspired you to start using interrupts in your own code now if you need some more information about interrupts or if you want to grab the code that i use today just head over to the dronebotworkshop.com website where you will find an article that accompanies this video and there's a link right below the video to the article when you're on the website if you haven't yet please sign up for my newsletter is this the way of occasionally getting out to you to let you know what's going on here in the workshop and of course it's free all i need is your email address if you want to discuss interrupts and anything electronic well the best place to go of course is on the dronebot workshop forums and you can join the forum for free and talk to a bunch of like-minded individuals who love to work with electronics and there's information about that below the video and finally although it's been said earlier in the video if you haven't subscribed to the youtube channel please do that i'd be honored to have you as my next subscriber and as i said before just go and click on the subscribe button that's below the video and also click on that bell notification and as long as you've got them enabled you'll be getting a notification every time that i make a new video so until we meet the next time please take good care of yourself and please stay safe out there and we will see you soon here in the dronebot workshop goodbye for now [Music] [Applause] you
Info
Channel: DroneBot Workshop
Views: 91,794
Rating: undefined out of 5
Keywords: arduino interrupts, arduino interrupts tutorial, Arduino uno, arduino tutorial, hardware interrupt, pin change interrupt, timer interrupts, arduino interrupts explained, arduino interrupts example, interrupt, dronebot workshop
Id: wIcC8-g9Lnw
Channel Id: undefined
Length: 48min 17sec (2897 seconds)
Published: Tue May 10 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.