Arduino Software Interrupt
Explore the Biggest How To and DIY community where people make and share inspiring, entertaining, and useful projects, recipes, and hacks.
Carl Lewis Vibration Plate Instruction Manual on this page. It is a pity that you leave such a nice comment and the end it by being a jerk. But I’m going to go ahead and approve it because I’m having a good day.
Rather than leave such a dumb comment, it’d actually be useful if you said what you didn’t like about it. If what you don’t like is that it’s a very simple example, that is on purpose; it’s supposed to be the minimum necessary to use pin change interrupts so that people who are just learning don’t get distracted by other parts of the code. Alternatively, you could write a better example to put in the comments and then everybody would win. I’m sorry, I didn’t mean to be nasty. I have been researching pin change interrupts for a while. I’ve read some articles that suggest you have to have a degree in rocket science to use PCIs. Your approach is VERY clear, very simple and truly the best I read.
You make it real easy to understand without calls to weird and wonderful methods to change pin numbers to mask bits etc. Your article shows simply how to switch on the port then switch on the pins. No special macros (sbi/cbi). No calls to libraries. No weird calls to digitalPinToPCMSK and digitalPinToPCICRbit methods. With such a clear and simple approach I was hoping for a solution to my real problem, debouncing switches.
My problem wasn’t/isn’t YOUR problem. I was wrong to expect MY solution in YOUR marvellous article.
I apologise for the second half of my my remark 😦 The first half I still stand by 🙂. The only real way to do that is to keep a record of all the pin states.
Then when the interrupt is triggered, you compare that to the record you have, see which is different and in which direction, and go from there. You’d have to remember to update that record each time the interrupt is called and each time you change a pin. Alternatively, you can use a microprocessor that lets each pin have external interrupts like most 32 bit professors (examples include the teensy and Arduino Due) or a different 8bit chip with more external interrupts like the Arduino mega, which has four. Also, maybe you don’t need to read all of the different types of changes. A lot of applications can be adapted to work by only knowing that there is a change. Finally, if you are using the Arduino Uno or similar that uses the ATmega328 chip, remember that it has 3 ports.
You could set up your interrupts so that each interrupt goes to a pin on a different port. Then, based on which interrupt gets called, you’ll know which sensor triggered it. Actually, I’m going to amend that a bit, but I’ll leave it so that I and others will know the though process I went through. Again, I’m going to assume you’re using an Uno or other 328 chip. Attach each of the sensors to a pion in a different port of the chip like I said in the last comment. However, you don’t have to keep a record of the previous states to know. Since the ISR will only get called when there is a change, you know that the previous state is the opposite of the current state.
So if the ISR gets triggered, you can check to see if the pin is currently high; if it is, that means that it was a rising interrupt. If the pin is currently low, it means that it was a falling interrupt. Also, you might want to do two of them in the hardware interrupts and the third with a pin change interrupt. I understand the disappointment of Louis. I had the same feeling and I’ll try to explain why.
Your excellent article explains in great detail to the (absolute) beginner how things work. When you say ‘putting all of these together’ it looks as if your IDE has stripped out all comments. Like: what is this code supposed do? Complicating factor for beginners like me is that in various steps of your explanation, you use specific pins, ports and routine addresses, but these particular items don’t seem to return in the example code. Hard to grasp why you enable pin 1 and 11 (isn’t that what “PCMSK0 = 0b00000001; // PCINT0 and PCMSK1 = 0b00001000; // PCINT11 ” does?) and then define routines ISR(PCINT0_vect) and ISR(PCINT1_vect), why PCINT1_vect and not PCINT11_vect? You make up quite a bit by helpful replies to comments, so I hope you are inclined to add a bit more comments to the example code, or harmonise the items as explained in the article with the example code. Thank you for writing such a great article!
I do have one question for you. Can I have individual ISRs run for different individual interrupts within a port? Could I have an ISR for PCINT0 (physical pin 14), and another, separate ISR for PCINT1 (physical pin 15), etc. Even though they are all within Port B? I am confused as to whether the PCINT0_vect ISR is running just when PCINT0 is triggered, or when any port B interrupt that happens to be turned on is triggered. I am trying to control 4 encoders with one 328, so I would have 8 inputs that would need to trigger 4 ISRs.