Clarification needed on Atmel "Pin Change Interrupt" concept - Page 1
Forum section: electronics / general

author: VinzC
author_rank: Frequent Contributor
timestamp: September 22, 2016, 12:14:34 pm
content: Hi all.In my current project I need to implement a double software counter that counts pulses from a Hell effect sensor installed on a window motor. The microcontroller unit is an AtmelATmega64M1. So I (sort of) stumbled upon thePin Change Interruptsystem and was about to use it but — unless I missed something, which is always possible — I think there is a catch: both my signals come from port pinsB6andB7. The data sheet indicates pinsB0throughB7are all bound to the same Pin Change Interrupt Flag, i.e.PCIF0inPCIFR. In short there's no way to identify which *pin* has changed state.In my case even though I'd use an interrupt I'm not guaranteed to not miss pulses nor to not account more than once for a given pulse. Say if pinB7changes right after pinB6and the latter hasn't I have no way to know what pin state changed*, which completely ruins the convenience of having an interrupt. In such cases, I instead must track individual pin changes — which can occur in a usual poll loop — and not use an interrupt at all.My question: is my analysis [of Atmel Pin Change Interrupt concept] correct or is there anything I have missed?*If there's no pin change tracking in place.

author: wraper
author_rank: Unknown
timestamp: September 22, 2016, 12:24:39 pm
content: You should also consider such thing. If the signal from the hall sensor is so fast that you cannot catch it by interrupt routine, that is interference and not real signal.

author: Psi
author_rank: Super Contributor
timestamp: September 22, 2016, 12:36:17 pm
content: The atmega clock speed needs to besignificantlyfaster than the signal changes you want to detect.You want to have enough wiggleroom to complete the entire interrupt handler (with room to spare) before the signal might change.Once you have that you can simply check all the pin states to figure out which caused the PCINT.

author: dannyf
author_rank: Super Contributor
timestamp: September 22, 2016, 12:38:01 pm
content: In the isr, have a static variable that reads the state of the pins, which you need to clear the flag anyway.Easily done.

author: VinzC
author_rank: Frequent Contributor
timestamp: September 22, 2016, 12:47:18 pm
content: Thanks a lot guys for your hints but you've missed the point. My question is *not* about how I can handle a signal from a Hall sensor (I shouldn't have mentioned it in the first place, that was informational only). My question is about Atmel Pin Change Interrupt mechanism: are my deductions correct?Now as for the sensor, what I have *not* mentioned is that the signal comes from aMAX9621, which handles all parasitics, ESD, interferences and level shifting so that the maximum frequency the MCU would receive is about300 turns per second[EDIT:70turns per second, measured] and there's one pulse per turn, so largely enough time for the MCU to handle that.

author: madires
author_rank: Super Contributor
timestamp: September 22, 2016, 01:39:47 pm
content: You've missed PCMSK0 (Pin Change Mask Register 0), which allows you to set the pins being watched, i.e. which pins will trigger the interrupt. In your case, you would enable B6 and B7. So you just have to check for two pins. Another way would be to move one signal to another port with its own pin change interrupt.

author: VinzC
author_rank: Frequent Contributor
timestamp: September 22, 2016, 02:26:28 pm
content: Quote from: madires on September 22, 2016, 01:39:47 pmThat was indeed what I understood: I need to watch both B6 and B7 in the same interrupt. That is precisely what to me turns out to be "impractical" (well, annoying at least) because I have to keep a global variable with the state of those pins, which would have been avoided if there was only one interrupt per pin. And I need to watch both pins at the same time because both motors can run simultaneously.Quote from: madires on September 22, 2016, 01:39:47 pmThat's what I've just done: I swapped a few pins and now I'm using INT2 and INT3, one for each motor.

author: westfw
author_rank: Super Contributor
timestamp: September 22, 2016, 07:20:33 pm
content: QuoteYour understanding is correct. With pin change interrupts, you GET the ability to watch many more pins, but your ISR has to figure out which pins changed in which direction, usually by comparison against saved status in a global variable.It's not that bad. Given the usual relative speed of internal execution (microseconds) vs external events (milliseconds), and "typical" applications (quadrature decoding, keypads, etc) that more-or-less ensure "non-simultaneous" events, it's pretty easy, even.

author: janoc
author_rank: Super Contributor
timestamp: September 22, 2016, 09:56:15 pm
content: Quote from: VinzC on September 22, 2016, 12:14:34 pmWhy not use an actual timer/counter with external clock for this instead?That has also the advantage that you are very unlikely to saturate the MCU with interrupt requests if the Hall sensor produces a lot of pulses.ISRs are quite expensive - unless your sensor spins really slowly, you are bound to start missing pulses at some point, moreover the MCU wouldn't be doing anything else but servicing interrupts.

author: Rerouter
author_rank: Super Contributor
timestamp: September 23, 2016, 02:43:49 am
content: I would also suggest using a hardware timer / counter module in the micro,however to give you a ballpark for what you can manage if you did time slicing (e.g. change the mask in slices for the interrupt), on a 328p i was able to manage counting via interrupt and updating an LCD with the reading to 128,000 pulses per second before things started hanging, in this case the interrupt only incrementing a 16 bit variable to keep the time as short as possible,For reciprical counting (which involved timestamping with a 32 bit variable), i could manage about 15Khz before it began to lock up, but by that point i had almost no resolution.

author: VinzC
author_rank: Frequent Contributor
timestamp: September 23, 2016, 09:53:21 am
content: Quote from: VinzC on September 22, 2016, 12:14:34 pmQuote from: janoc on September 22, 2016, 09:56:15 pmGood point. Fact is both existing timers on that MCU are already busy for something else. And as I said in an earlier post: 300 pulses per second (measured) is far from overwhelming the MCU:Quote from: VinzC on September 22, 2016, 12:47:18 pm

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: September 23, 2016, 07:41:23 pm
content: Quote from: VinzC on September 22, 2016, 02:26:28 pmThat be annoying foryou, but in some applications it's a boon. Pin change interrupt is commonly used with keypads, where having to set up a separate handler for every key would be a pain.

author: max_torque
author_rank: Super Contributor
timestamp: September 25, 2016, 06:45:34 pm
content: There are two important questions you need to answer / understand:1) What is the shortest amount of time between two pulses for any single pin2) What is the shortest amount of time between two pulses occuring on EITHER pin.In case 1), your MCU needs to be able to service it's interupt before another one arrives on that pinIn case 2), what your MCU needs to handle depends on if truly simultaneous interupts can occurBTW, just because you are using a timer for one purpose, doesn't necessarily prevent it being used by other hardware, such as the Input Capture channel.........