Hi everyone. I am currently trying to understand interrupts and ISRs, and I have a question.
Let's say I have multiple sensors that need to be checked for a certain condition (FALLING). All the sensors are similar, but they can fall at different times and different conditions need to be checked when they do.
Since ISRs do not accept arguments, I am thinking that you have to create an ISR for each sensor, like:
do you have enough external interrupts for that? a UNO would have only 2 (pin 2 and 3) for example.
if your arduino supports this, you could use a pinChange interrupt on a whole PORT. then in the code of the ISR you'd look at what has changed since last time and find which sensor(s) got triggered
// global data
volatile uint8_t previousPinStates = 0;
volatile uint8_t changedPins = 0;
// PinChange interrupt service routine
ISR(PCINT2_vect) {
// Read the current states of all pins in group (PD7:0)
uint8_t currentPinStates = PIND;
// Calculate the changed pins
changedPins = currentPinStates ^ previousPinStates;
// Update the previous pin states
previousPinStates = currentPinStates;
}
if the loop() you could have something like
noInterrupts();
uint8_t changedPinsCopy = changedPins;
changedPins = 0;
interrupts(),
if (changedPinsCopy != 0) {
// something changed find the bits set to 1 will tell you which one flipped
}
Ok, after doing some research as jremington suggested, I believe we have changed topics.
I was initially asking about regular hardware interruptions, and not pin change interruptions. If I need to detect a falling signal, it would be much simpler to used INT instead of the PCINT suggested here.
As I understand it, the using PCINT would only benefit me by augmenting the amount of pins that I can use for interruptions, but it really does not simplify declaration nor does it reduce the amount of functions I have to create.
Am I interpreting things correctly? I am very new to this PCINT concept, so I may be way off.
Maybe - maybe not. Even if it is possible, it may make sense to not reduce the number of functions and declarations for reasons of faster code, more readable code, more efficient programming, etc.
It will for a large part depend on the actual situation. What sensor, what do you have to do when there's an interrupt, how to tell them apart, are they all the same or different sensors, etc.
I do understand this, but what I am trying to reduce is the amount of functions needed to handle said interruptions. In other words, if I have 5 interrupt pins, I must declare 5 IRSs and set each interrupt pin manually (as opposed to, for example, setting 5 pins as INPUT using the for loop and an array), and using a signle IRS wich parameter as you would a simple function.
I am not 100% sure, but I think that using PCINTs does not differ from INTs in this regard.
I do not think that having 5 functions doing the same thing would be efficient programming, since any change in the IRS must be made X amount of times depending on the number of INTs that you have.
Then have those ISRs call a function with appropriate parameter so your generic handler knows which one it is that called (just keep in mind to keep those functions short as you're still in the ISR).
It looks plausible, I can test it from under the umbrella here.
The only problem I can anticipate is missing some pin changes, not sure, but a fix for that woukd be to have the ISR only be able to set bits in a byte indicating activity on the corresponding pins, then…
...in the loop, observe those set bits, handle them however you need and also acknowledge having done by clearing the bit for a pin that changes and you've done handing.
Usually an interrupt means something has to be taken care of, but you have never disclosed what that something might be. Do you need to read from a register in that sensor or what? If so, that could be a single function with the address of the device passed to a single function.
That is a good idea, but I would still have to declare all 5 ISRs manually and also set all 5 pins to handle interrupts individually, unlike normal pins.
This sounds like I am complaining, I'm not, I am simply trying to understand if this is possible or if I am forced to keep doing this manually and individually for each pin and ISR.
Yes, but as I understand it, #7 is simply describing how to set up a PCINT and find which pin suffered a change. There is nothing in there about initialization and unification of the ISRs.
There is nothing in particular. In my code I am simply testing the functionality, I have 5 sensors, and 5 ISRs, each ISR is called when the signal drops and the state of each sensor is set to one, simulating a real action.
I'm just trying to gain a deeper understanding of interrupts.
you could decide to either walk through the bits set to 1 in changedPins within the interrupt context to call your unique function which would take then a PIN number argument, solving your initial issue
that function would be executed still in the initial ISR context and thus you would not get other interrupts and it will be dealt with 'just in time'
alternatively as I mentioned, you could pick up the changedPins within the loop and deal with them in the main application context, outside interrupts.
you might want to add a bit of business logic as you only want a FALLING trigger and I capture the CHANGE. So you might require to maintain the previous state and check if the change pertains to a falling pulse or rising pulse before calling your function