Pin Change Interruptions ISR | PCINT | Arduino101

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we have another arduino 101 tutorial in the previous two videos we have seen how to control the internal comparator and how to control the output and the input pins using registers for more speed and better code today we will see how to use the pin change interruptions which are the interruptions vectors how to trigger one what registers we need to use and why interruptions will make the code so much better i will try to give you some good examples so you'll understand better the advantages of interruptions so get your arduino open the ide and let's get started [Music] video sponsored by glc pcb consider using their main service for pcp manufacturer for only two dollars for five pcbs of any color together with that you can also order the stencil for using solder paste this is made out of stainless steel and could last for thousands of pcbs in this way you can solo your components easily and create perfect prototype pcbs the order process is so simple just upload the gerbers to jcpcb.com select the pcb settings mark that you also want the stencil and place the order in a few days you'll receive the products what's up my friends welcome back with the arduino we have two types of interruptions the int for external hardware interruptions and the pcint for pin change interruptions today we'll take a look at these last ones the pin change interruptions and we'll leave the hardware interruptions for a future video now the hardware interruptions are very limited for example on the arduino uno only pins 2 and 3 could trigger a hardware interruption but on the other hand the pc int interruptions don't act over just one pin but over a group of pins better known as a port so as you remember from the last video the arduino uno is using the atmega328 microcontroller and if you remember this was its pin out and we have three ports the port b port c and port d we have a few registers that control the interruptions of these ports but first what is an interruption you should already know that the arduino code is sequential running in series meaning that till one instruction is not over we can't execute the next instruction for example in this code here we run three functions and we also read some inputs from some buttons the first function will read the temperature from a thermocouple the second function calculates some pid values and the third function applies the pd result to some analog outputs to control a heater between these functions we read the state of two pins connected to some push buttons since the arduino code is sequential it's quite obvious that function 2 won't run till function 1 is not over and function 3 won't run till function 1 and 2 are over if we press the push button while function 1 is still running using these lines of code we won't detect that the button was pressed because the digital read won't run till function 1 and 2 are done so how could we change a variable that is used in function 3 for example while we are still running function 1. for that we use interruptions when an interruption is triggered that will pause the code in that exact moment and take it to the interruption vector and here we run the code for that interruption which could be anything and when this is over we get back to the code and keep going from that same exact moment using pc int if activated each time an input changes its value from high to low or from low to high an interruption will be triggered so another difference between pc int and the hardware interruption is that we can set the pc in to be detected on low or high or on rising or falling edge as we do with hardware interruptions it will only trigger when the pin changes its value and it doesn't matter if it's from high to low or from low to high we can activate or deactivate pc int associated to one group of pins using the pcicr register standing for the pin change interrupt control register we use the first three bits of this register where bit 0 is the pci 0 bit 1 is for pcie 1 and b2 is for pcie 2. this pci bits represents the pin change interruption enable bit so if we set this bit to 1 interruptions for that group will be activated and if we set it to a 0 well interruptions are disabled pci 0 controls the group of pins from pc in 0 to pc in 7. if we take another look at the arduino port map we can see that those interruption pins are connected to the digital pins from d8 to d13 which are bit 0 to 5 from port b pcie 1 controls the group of pins from pcent 8 to pc in 14 and those correspond to the analog pins of the arduino a0 to a5 and finally pcie 2 controls the group of pins from pc16 to pc in 23 and these correspond to digital pins of the arduino d0 to d7 now setting a pc in bit to a 1 it means that that pin will trigger interruptions setting that bit to a 0 it means that that pin won't trigger interruption on the pin change the pc in bits are controlled by the pcmsk register precisely by the pcmsk register 0 1 and 2. so now knowing this how do you think we can set pin d5 for example to trigger an interruption on pin change well pin d5 corresponds to the pc in 21 and pc in 21 is from the pcie group too so first we need to set the pcicr register to this value with the one on b2 so pcie 2 group could trigger interruptions then we set the pcmsk2 register to 0 0 a001000 so we set the bit for the pc in 21 to high so now digital pin d5 will trigger interruptions each time the input changes its value now here we have some other examples from different other pins or if you want you can enable interruptions for multiple pins at the same time with no problems ok so at this moment we know how to set the pins to be able to trigger interruptions but as you remember when the interruption is triggered we pause the main code and we jump to the interruption vector where we execute the code for that interruption so what is this interruption vector well each of the three groups of pins will have an isr or interrupt service routine this is a loop in the code then when the interruption flag is triggered it will execute for that in the code we define the isr and then we add a vector in this case we have three vectors pc int 0 vector for pins from d8 to d13 pc int 1 vector for pins from a0 to a5 and pci and d2 vector for pins from d0 to d7 so in the example before we have set digital pd5 to trigger interruptions so we have to add a code for the pc into vector isr so in the code after or before the void loop we add these lines this is the interruption loop for port d so between these brackets we can add our interruption code once these lines are executed the interruption flag will go back to 0 and this length of code won't run again till another interruption for pd5 is triggered to sum everything up and better understand let's see a full example let's say that we have this code i have two push buttons connected on pins d4 and d5 of the arduino i also have a temperature sensor connected to the square c port and in the code we use this function to read the temperature then we have a second function that creates a pid value each time we press one of the push buttons we can increase or decrease the set point of the pid algorithm we also have a third function that will apply the pid result to a pwm pin in order to control a mosfet connected to a heater we know that each function will last a few milliseconds to run so it's quite obvious that if i press a push button while any of the functions are still running we might not detect that the button was pressed so for that in the setup loop we now add these lines of code as before so now pins 4 and 5 could trigger interruptions then we go below the void loop and we add the routine for the interruption vector 2. now we take the digital red lines from the code and now we place those in the interruption part actually for more speed as you remember from the previous tutorial instead of using digital read we can directly use the p in port so we have register control but that is up to you so now for sure each time that i press a button we will go to the is routine and read the digital value of the buttons we exit the isr and get back to the rest of the code okay now let's see some things that you should have in mind if you set for example pins 4 and 5 which are from the same port to trigger interruptions without consulting which pin created interruption you can't possibly know which one of the two pins trigger the isr if pin 4 made the interruption we go to the isr vector 2. if pin 5 made the interruption we also jump to the isro vector 2. that's why when using the pc interruptions from the same port we must always consult which pin changes value to detect that we must store the previous value using a global variable and compare that each time you should do the same if you want to detect the rising or the falling edge of an input by knowing the previous and the actual state of a pin we can detect when it passes from high to low or from low to high another thing to have in mind when we are inside of an interruption the rest of the interruptions are on pause that means if one pins triggers an interruption and just in a few moments a different pin triggers another interruption while we are still running the first interruption routine the second interruption won't trigger in conclusion we must make the isr routine as fast as possible so what i recommend you is to just change some values of the variables in the isr routine and then let the rest of the calculations the decisions and so on to be made in the void loop in this way the interruption is as fast as possible and on the same reason if an interruption is too long remember that during interruptions the rest of the code is also on pause so what if you are controlling the position of a step motor for example so if the interruption is too long maybe the motor already reached the end of its track but you can't stop its rotation yet till the interruption is over so that will result into something bad another thing to have in mind is that if you use interruptions with buttons sensors and so on you should consider applying the bounce as you already know on a state change the pin could oscillate for a brief moment before going stable so because interruptions are very fast instead of just one push of a button it could trigger an interruption on each oscillation so consider applying the bounce another thing during the execution of an interrupt the arduino does not update the value of the millis and the micros function so the execution time of an isr is not counted and the arduino will have some lag you could use the millis and the micros function to count the time between two interrupts but during the interruption the time is not updated so what i want to say is that you can use for example the millis function like this inside of the isr but have in mind that this value would be the value that it had the time the interruption was triggered as a consequence the delay function does not work neither because it's based on the operation of the millis function the micros function will update its value within the isr but it will start giving inaccurate time measurements past the 500 microseconds range as a result the delay microseconds function works in that time range although we should not use it because we should not introduce delays in the isr one last thing using cli and se we can stop or resume all global interruptions inside of our code there are some people who place the cli before the code of the isr and the cee at the end of the code of an is routine but i've already told you that during an interruption all global interruptions are automatically disabled so there is no need of using cli or the se but only if you need to re-enable them inside of the isr to allow for nested interrupts to be serviced while inside of your isr you can use the see to enable interrupts although this is not recommended and it could result into desynchronization so now guys you should know how to set up the pin change interruptions please see all the examples below on electrons.com for more details and also check the data sheet of that mega chip stay tuned for more arduino 101 videos soon i hope that you have learned something new if so maybe give a like to this video and consider subscribing if my videos help you consider supporting my work on patreon so thanks again and see you later guys hey guys electrolubs here this is the end of the video and thank you very much for supporting my channel and watching my videos and maybe even subscribe to this channel and i would like to give a special thank you to all our patrons for supporting my work supporting my tutorials and if you also consider supporting me just check my patreon on patreon slash electronoop select any tire that you want and like that you'll be able to see my videos before the youtube release you can get in touch with me with comments or questions and by the way i'm also on facebook instagram twitter also our website electrons.io so if you make an account you will be able to post your projects your tutorials teach others your work and also use the forum for our for the questions and all the doubts that you have thank you once again for supporting this channel for giving a like to this video and also by subscribing and supporting me on patreon.com keep up you guys
Info
Channel: Electronoobs
Views: 56,498
Rating: undefined out of 5
Keywords: pcint, Arduino, tutorial, register, class, interrupt, pin change, vector, ISR, IRQ, push buton, pin state, input, code, example, interruptions
Id: ZDtRWmBMCmw
Channel Id: undefined
Length: 14min 19sec (859 seconds)
Published: Sun Dec 13 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.