JeremyBlum.com

v3.1

Tutorial 10 for Arduino: Interrupts + Debouncing

| 148 Comments

This video was featured on Hackaday.com on 3/8/2011
This tutorial was featured on the official Arduino blog on 3/9/2011

Interrupts are an extremely useful, yet often feared element of microprocessors. Interrupts allow you to run a program, while still being able to react to asynchronous input from the outside world. On many platforms they can be confusing to implement, but the arduino makes it easy! In this week’s episode, I’ll show you how to use a hardware-debounced button to activate a hardware interrupt on the arduino. I’d suggest you go check out episode 2, where I initially introduced button debouncing, if you haven’t already. I won’t be covering timer interrupts in this episode, since I recently wrote an extensive blog post about using them. Enjoy the video!

EDIT: You can find a great run-down of debouncing techniques and problems here: http://www.ganssle.com/debouncing.htm (Thanks Jope)

 

You can download the files associated with this episode here:

GNU GPL License Distributed under the GNU General Public (Open-Source) License.
Please Attribute and Share-Alike.

148 Comments

  1. Oh my God, don’t tell me, this is the last one. It will be great, to produce more, far more. E.g. interface with sensors, other hardware, 3 wire display etc. I know, that all is on arduino.cc website, but to have it on video is far more fun… Best regards from Slovakia.

  2. Pingback: Beginner concepts in electronics and Arduino - Hack a Day

  3. Great job. Debouncing is something everyone get bitten by early. Your tutorial is the best at explaining the problem and at explaining the hardware solution. Look forward to more tutorials after you break.

  4. Pingback: Beginner concepts in electronics and Arduino | Boomeroo Web Resources

  5. Good luck with your classes!
    If you ever produce other arduino videos, I look forward seeing them.
    Maybe you’ll be the Forrest M. Mims III for the 21st century.

  6. Hey Jeremy!
    The series is great! It’s very informative and helpful.
    Looking forward for some more of these…
    I learned a LOT!

    I have 2 questions please…
    What about having more than 2 buttons (each connected to an interrupt pin)?
    I’m sure there’s a way to connect more than 1 button to 1 interrupts (using keypads and so), am I right?
    How can that be done?

    The other question is if there is a way of having more than 2 interrupts (is that needed at all, once you can connect more than 1 button to an interrupt?)
    I know that in some programming there is something called “interrupt extender” but don’t know more than that.

    Looking forward for your answer.

    Thank you very much in advance!
    Golan

    • The arduino uno only supports 2 external interrupts. The mega can support up to 5. If you need more, you’re probably better off using a platform that supports it natively. The The MSP430 supports interrupts on all inputs.

  7. Pingback: Must-See Beginner Tutorials For Arduino | dev.SquareCows.com

  8. Why is the Schmitt trigger needed? Why isn’t the capacitor smoothed input adequate for hardware debouncing?

    • Technically, you can do without the schmitt trigger. I just wanted to show how it can be used to “straighten-out” a signal. Plus I wanted to invert it anyways (also for the purposes of illustration).

  9. Thank you for your contribution to the community. The videos in your series were of very good quality. The material from each was well presented, in an easy to follow fashion. A valuable resource indeed.

    Cheers!

  10. Pingback: Must-See Beginner Tutorials For Arduino | inmotion.pt

  11. Pingback: hackaholicballa - Beginner concepts in electronics and Arduino

  12. Nicely done, Jeremy. As an older Engineer I appreciate you younger ones taking the time to share with us all. When I was in college we were using Watfor & Watfiv and card readers. I do a little prgramming with AutoLISP in my Engineering practice so your programing was not difficult to follow.

    I have a client wanting me to put together for him a model train car that will have a turrent activated as it goes by sensors and fire a rotating “gattling gun” (nerf darts). I hope to use the Arduinos to accomplish this. Not sure about which way to go with the sensors.

    Best of luck in your classes!

    • Sounds like a cool project! There’s a few ways you could accomplish this. One cheap and easy way may be to use simple IR LEDs and phototransistors. The LEDs would shine on the phototransistors when the train goes by, and the train would know to start firing nerf darts.

  13. well first of all gotta congratulate the excellent tutorials arduino,: P I finally begin to understand electronics. I would like to make a suggestion, create a tutorial with the ethernet shield, with web interface php server for example to control the temperature and light in a room and can turn a heater.
    Sorry my poor english.

  14. Pingback: Electronics-Lab.com Blog » Blog Archive » Tutorial 10 for Arduino: Interrupts + Debouncing

  15. Hi,

    a very good guide to debouncing can be found here:

    http://www.ganssle.com/debouncing.htm

  16. Man this is awesome. I am used to programming the 68HC11 microcontroller, and everything that you did here would be a gigantic chore! Setting up interrupts and keeping track of the stack, manually configuring registers and having to use jump statements to control program flow rather than loops.

    I just ordered an UNO and I am waiting for delivery. This looks uber awesome. Thanks for the tutorials

    • I’ve recently been doing some assembly level MSP430 programming, and handling all this kinda stuff is certainly a huge pain. Gotta love the simplicity of the arduino.

  17. Great videos! Just would like to know what specific Schmitt trigger you were using, I need to do hardware debouncing because I’m using a interrupt. What is the specific product number and where did you purchase it? Thanks in advance Jeremy!

    -Scott

  18. Hi About Timer interupts.
    is there a chip or sorcet that givse a pulse 10 Hz to an not 10.00000001 Hz .

    so that i we make a Acurit Clock ClockFunction.
    outing that 10 Hz to a interrupt on a pin where the pin is connectet
    ?????????????????????????????????????????????????
    volitail int tenthofsec=0;
    volitail int secunds=0;
    volitail int minuts=0;
    volitail int hour=0;
    void setup(){
    attachinterrrupt( 0 , countTime , Fallng);
    }
    void loop(){
    displayTime();
    }
    void countTime (){
    tenthofsec++;
    if (tenthofsec==10) {
    tenthofsec=0;
    secunds++;
    }
    // secunds
    if (secunds==60) {
    secunds=0;
    minuts++;
    }
    // minuts.
    // and so on…….
    }

    void displayTime() {
    // display the time on perhaps 7 segmant display or something.
    }

  19. Hej Jeremy, many thanks for your easy anderstanding and clear way to illustrate your tutorials, I have great plesure of seeing them . But your debounce circuit migt weld a small pushbutton or reed contact because you short the capacitor , so please add a small resitor ex. 100ohm in serial with
    the pushbuuton.

    Best regards , and keep up your studying and show us some more in your spare time onely.
    Jan

  20. Hi Jeremy,

    Great tutorials.
    But i have a I2C RFID reader YHY502ATG with a pin which drops low wen i place an RFID chip in front of it.
    When i use a readdigital it works perfectly. but i don’t want to check the ports everytime i loop. because there are HW interrupts
    But when i connect that pin to my hardware interrupt it won’t work.

    Kind regards

    Johan

  21. o btw i my hardware interrupt trigger works but the RFID reader isn’t anymore while its started from the interrupt.

    • Are you sure the interrupt pin is setup correctly as an input? That might explain why the RFID stops working when hooked up to a different pin. You might also want a pull-up resistor.

  22. Hi Jeremy – The arduino is a fantastic project and your tutorials are wonderful.
    Many years ago (well over 20!) I worked on embedded systems in 8048 and 8051. It was really hard work to make them do anything at all!

    I gave up that strand of my career a long time ago and I’m now coming back to it purely for FUN and really having a great time, thanks to the arduino project and your tutorials.

    Thanks again
    Neil

  23. Great tutorial Jeremy, I think this should help me with my current problem of turning on and off the +5V to a 7-segment CA display as right now it works, but not all the time. Since I don’t have a schmitt trigger, I will try just the resistor and capacitor as you have suggested to others.

  24. Hey Jeremy, great tutorials! They definitely cleared up a lot for me. I was wondering if you by any chance know of any good tutorials for software debugging. I’m currently working on a project using two interrupts and I’m getting very bad bouncing. You should know that my software is very time sensitive. Any help would be appreciated. Thanks

  25. Thanks for the great tutorials Jeremy! I have a problem with the hardware debouncing though… It only works when i have the serial port enabled in the code and the SerialPrint command in tne beginning of the loop to monitor the state of the button. Just like in your .pde on this tutorial. if i delete these two lines and make the code identical to that of the switch2.pde from your second tutorial, then it doesn’t work well. Do you have any idea why this happens? I don’t see why the state of the serial port should affect it…

    • That is strange indeed. Are you using the same resistor and capacitor values that I used?

      • Yes, the values are the same, but maybe they are not correct for the specific switch i’m using. The debouncing circuit might not work properly (doesn’t actually give the switch enough time to stop bouncing), but maybe enabling serial communication puts just enough “strain” on the arduino so that there is an ever so slight delay in reading the switch that acts kind of like debouncing. I’m using a button, similar to those that are on the arduino itself. I’m thinking that I should probably find an oscilliscope and actually measure how long the bouncing lasts, so i can do the math and find appropriate resistor and capacitor values. I had tried reading the signal with an oscilliscope using a little switch from a PC case (the ones for power and reset), but it turned out that it already worked perfectly without bouncing…

  26. What is the program that you are using for the circuit diagrams at 10:20 in your tutorial?

  27. Great work Jeremy!

    Definitely the best Arduino tutorials that I have come across.

    I have a question about using a piezo sensor as a vibration detector.

    Here is the scenario:

    Utilizing the piezo sensor that has a magnet attached to it and mounted on a sheet of metal I want to be able to detect the presence of vibration. I’d like to be able to set a range that I can use to filter out low level vibrations based on comparing the analog value to a value I set in a variable. If the sensor detects vibration within my trigger range I will increment a counter variable and compare the count to another variable.

    I’d prefer to utilize an interrupt to trigger the event but I’m not sure what my best approach would be.
    Should I output the piezo through a Schmitt trigger and have the output of the Schmitt trigger go to int0 or int1 and then based on voltages do my filtering?

    I’ve played around with different sketches and the piezo does work the way I need it to work but I need to clean up the piezo’s output so I can work with more consistent values.

    Sketches that I’ve used for testing.

    http://www.arduino.cc/en/Tutorial/KnockSensor

    http://arduino.cc/en/Tutorial/Calibration

    Regards

    Bob

    • Have you tried implementing a low-pass filter to remove some of the higher-frequency noise? That might allow to care care of your issues in hardware alone. I explain one in my 14th episode.

  28. Jeremy,

    The information you have put together is excellent and the video are very easy to understand. I am very new to the Arduino world but it seems like the information is very user friendly. With that said I would like to see if you or someone on your blog can help me with some Arduino code. Here is a brief description of what I am trying to do.

    Basically I want to use the programming flexibility of the Arduino to make a dynamic analog signal conditioner. There will be two input signals V1 and V2 and they range from 0v – 5v with a center or neutral point if 2.5v. I have a motor controller that has the ability to have analog input devices like a potentiometer or an analog joystick. The input signals are 0v-5v DC with a 2.5v center point. When the analog device is calibrated correctly it is easy to achieve the 0v-5v DC.

    I would like to add some of the following functions to the signal before sending it to the motor controller.
    1: Change the original signal voltage to allow for adjustment like min or max setting with a 2.5v center
    2: Change one axis input based on the second axis input like a limitation filter. (i.e. if axis one goes higher axis two is limited)
    3: Change the original signal voltage using an acceleration or deceleration algorithm
    4: Change the original signal voltage using a spike filter so that unwanted spikes are filtered out.

    As an added feature I would like to be able to select the code used by changing a set of dip switches to go from one set of code to the other without uploading new code to the Arduino each time I need to change the signal condition.

    I am asking for any help or suggestions for code samples or for a complete subset of code.

    Thanks in advance for any help or suggestions.

  29. Jeremy, these are EXCELLENT!

    I am new to Arduino, but have a long background in assembler programming. When the interrupt routine ends, where does the code go back to. In asm when an interrupt occurs, the current program counter (PC) is pushed to the stack. At the end of the interrupt routine if you execute a return the PC is pulled from the stack and the program picks up where it was. If you don’t want that to happen there are asm instructions to adjust the stack and you would jump to some other place you code.

    I don’t know how to control the code at the end of the interrupt routine. Can you give me some guidance on this.

    • As with assembly, the program will jump back to wherever it was previously in the code upon the completion of an interrupt routine. Naturally, some actions are atomic, so it might not be as easy to trace the exact stack pointer location as you can with assembly.

  30. Fantastic compilation of videos & your understanding of electronics ( & associated crafts ) is obviously very good.
    I love everything about your presentations.
    Content, manner, approach.
    Good stuff!

  31. Just wanted to say thanks for providing such clear and detailed tutorials. It has really helped me bridge the gap between my programming and electronics backgrounds; which until now have been completely separate. I’ve watched all of your tutorials and I can’t wait to dive in when my Uno arrives in the mail.

    Quick question: Why are there only 2 external interrupts accessible through the Arduino Uno when the ATMega328 MCU supports 24?

    I only ask because I plan to eventually address at least 3 interrupts through an ATTiny48 which I want to program through the Uno… But now I’m not sure if this is possible.

    • It just has to do with the way they decided to write the Arduino IDE. They sacrificed some functionality to make it easier to use. You can still access the interrupts by programming in C directly.

  32. Pingback: Working of Interrupts in Atmega8L

  33. “You can still access the interrupts by programming in C directly”
    Any info on this?

  34. Cheers for the tutorial. Well explained and got my project moving forward.
    Thanks.

  35. jeremy, great video. thing is, i don’t want to spend twenty minutes learning to hardware debounce an arduino interrupt. is there a transcript?

  36. I am interested in using both Interrupts – Int0 and Int1. Would the schematic be the same? Essentially, I am putting two resistors + capacitors in parallel between Vcc – 5vin on the Arduino Uno board and Gnd.

  37. Thank you for this series. It’s been very helpful. Thankfully, I was able to cobble together a Schmitt trigger with a 555 circuit. This post [1] made that dead simple. Granted it’s more work than I originally wanted to do, but I’m glad it’s done.

    [1] http://www.allaboutcircuits.com/vol_6/chpt_8/2.html

  38. I am doing this kind of game. http://www.youtube.com/watch?v=qn-h0GaQcj8
    I was thinking using interups for reading buttons and regular code for display and lights.
    But 2 interrupts of atmega8 makes me use of diodes, all connect to int0 and other input line. But on 328 i dont have problems?
    I have 74hc14 on buttons input. I have made same on commodore 64 and now redo it on arduino.
    Does this make any sense?

  39. Your voltage graph is wrong when u press the button voltage will go to zero immediately the button released profile is correct. if you want this profile you drew on the paper then u have to put a resistor in series with the switch to ground.

    BMac

  40. Is there another platform or IDE I can use instead of the free ARDUINO one. My son and I are just starting with the Arduino, we both use to program with turbo pascal.
    love your site

  41. Hi jeremy first of all thank you for making this series I’m a little new to the arduino and I ran into a problem I’m using a normaly open leaf action switch and whenever I implement your code modifide to the trigger and use a potentiometer to control brightness I can switch between leds but when I adjust the brightness and switch to the next one they all swithc to that brightness I’m going to reply my code can you please help?

  42. int greenLED = 11;
    int redLED = 10;
    int blueLED = 9;
    int nullLED = 6;
    int rightButton = 0;

    int potentiometer = 0;
    volatile int selectedLED = greenLED;

    void setup(){
    pinMode(2, INPUT);

    pinMode(4, OUTPUT);
    digitalWrite(2, HIGH);

    digitalWrite(4, LOW);

    pinMode(greenLED, OUTPUT);
    pinMode(redLED, OUTPUT);
    pinMode(blueLED,OUTPUT);
    pinMode(nullLED, OUTPUT);

    attachInterrupt(rightButton ,swap , FALLING);

    }
    void swap(){
    if (selectedLED == greenLED)
    selectedLED = redLED;
    else if (selectedLED == redLED)
    selectedLED = blueLED;
    else if (selectedLED == blueLED)
    selectedLED = nullLED;
    else
    selectedLED = greenLED;

    }
    void loop (){

    int pos = analogRead(potentiometer);
    int brightness = map(pos, 0,1023, 0, 255);

    analogWrite(selectedLED, brightness);

    }

    i hope im doing it the same as you did maybe just a novice mistake though

  43. It’s possible to blink 2 LED in different delay time by using interrupt functions?

  44. Hi,

    once i design my circuit using arduino Board. how to implement in my own circuit.?? i mean can we disconnect from arduino an use as seperate circuit??i hope u understud my question??

    Thnx

  45. Wonderful series. Makes Arduino even easier.

    I have a 2 phase project and I need help!

    First- I want to momentarily change the state of a LED by clicking a button using interrupts. (That part was easy enough thanks to you video)

    But I can’t figure out my part two. I want the state of the LED to change permanently if I hold the button down for 10 sec.

    So let says my LED is OFF. I press the button on the LED is ON as long as I press the button and it turns OFF when I let go the button, but if I hold the button for more the 10 sec I want the LED to stay on. After that since now the LED in ON, I want the button to turn the LED OFF when pressed. Do know if I’m clear?

    Or maybe interrupts are not the best thing for this job?

    Thanks for any help.

    • Put a while loop in the interrupt that measures the time button is depressed. Then do the change if it a momentary click.

      or you can use millis() to measure the time between the rising and falling interrupt.

      T0 = millis();
      While (digitalRead(Pin) == HIGH) {}
      dT = millis() – T0;

      if (dT > 8000)

      etc

  46. I was wondering if you could do a video on how to read a Microprocessor Timing Diagram… I have a project where I want to interface an Arduino (UNO R3 and Mega ADK R3) with a Dallas RTC DS12887. It would be very useful (if not imperative) to understand the signal timing… but I can’t find a good reference to help me learn how to read them. :(

    thanks.

  47. Here’s a push button debouncer I thought I’d try.
    https://www.jameco.com/Jameco/Products/ProdDS/321736.pdf

    I don’t think I’d need to do anything with software it I used this, right?

    Tony

  48. Thanks Jeremy. This was great. I started using Interrupts for my project a few weeks ago but have been getting inconcsistent results. I am using the button as a start/stop on a timelapse for a remote camera trigger. Basically I have two Reed switches (first one for half button press on the camera shutter for focus and the second for full button press). In the main loop I use the outputs to take a picture every 5 seconds. The button is used to start and stop the triggering, this allows me to set everything up, push the button to start shooting, and whenever I want push the button again to pause the shooting.

    One thing I am unclear about is when I have a delay() operation in the main loop, is it interrupted by the Interrupt function? The problem I run into is that if I want to take a shot every 10 seconds I want to use a delay(10000). But if that is not interruptable then I need a different mechanism to catch the button press. I want to avoid making my own “interruptable” delay() function.

    Thanks again.

    Derek

  49. Jeremy,
    Great tutorial, but I have one issue with the way you describe the debounce circuit. When you close the switch the voltage at the Schmitt-Trigger input goes ‘instantly’ to zero. The short circuit around the cap has zero resistance so the RC constant is zero. The circuit works because as the switch bounces between closed and opened the voltage goes instantly to zero, but then tries to rise slowly when the switch bounces open and RC = .1 sec. This repeats for each narrow bounce. The Schmitt-Trigger ignores the little slow voltage rises near zero because they don’t have time to get above 0.8 V, until the switch stops bouncing and settles at zero.

    On the other side of the coin, when you move the switch from closed to open, the voltage rises slowly (RC = .1 s) to 5V. Here you must have a Schmitt Trigger because if the voltage rises slowly in the TTL undefined region from 0.8 V to ~2.4 V the inverter will have an undefined state at the output, i.e. Low OR High. A Schmitt Trigger is not sensitive to the slowly rising input, whereas a slowly rising input on a regular TTL input, e.g. a 7404, would go nuts at the output.

    Thanks, looking forward to more tutorials. Kevin H.

  50. Thanks for your videos, Jeremy. You have a real talent for explaining difficult concepts clearly. Do you have experience using the Arduino hardware interrupts to read quadrature encoder signals from DC motors? I’m trying to display the encoder counts on the serial monitor as the motor spins, but the serial monitor is not showing any output so I’m trying to figure out the problem. Can you explain the limitations of the hardware interrupt sampling rate as well as how quickly the serial monitor can display data? I think either of these could be my problem but I’m not sure.

    • Yes, I have done that before. Try breaking this up into parts. First, you’ll want to make sure your hardware interrupt is actually triggering. Set up the interrupt to turn on an LED when triggered, and manually trigger it using a push button or a wire. Once that’s working, hook up the quadrature. IF that sitll works, then try using the Serial monitor. This will give you an idea of the failure point.

    • Yes, I have done that before. Try breaking this up into parts. First, you’ll want to make sure your hardware interrupt is actually triggering. Set up the interrupt to turn on an LED when triggered, and manually trigger it using a push button or a wire. Once that’s working, hook up the quadrature. IF that still works, then try using the Serial monitor. This will give you an idea of the failure point.

Leave a Reply

Required fields are marked *.


This site uses Akismet to reduce spam. Learn how your comment data is processed.