There are a number of posts trying to get at versions of this question, by passing parameters, using multiple functions & volatile globals, etc.
So I'm guessing the answer to this question is "Not easily".
Asking anyway just in case: Is it possible for an ISR called by an interrupt to "know" which GPIO triggered it?
So something along these lines
void setInterruptDynamically(int &thisGpio) {
attachInterrupt(thisGpio, ISR, CHANGE);
}
void IRAM_ATTR ISR() {
int thisGpio = SomeArduinoNativeCodeThatKnows();
// Then HTTPClient to POST thisGpio / digitalRead(thisGpio) to a remote device.
}
@UKHeliBob That part, sure. Goal here: A single ISR that can be triggered by multiple interrupts attached to different GPIO, and which can report that info to a remote machine.
Assuming that you somehow manage to find a way for multiple pins to trigger the same ISR, then the obvious way for the ISR to determine which pin caused the trigger is to examine the state of the trigger pins
I have never used them beyond a quick experiment some time ago but have a look at pin change interrupts and see whether they have anything to offer
Something else to consider. Do you need to use an interrupt at all ? What is the application ?
interrupts should be short... I would not make an http request from within the ISR...
write one ISR per pin, each setting up a volatile flag to a known value and in the loop check the flag.
if multiple ISR could be triggered hyper rapidly, you'll need one flag per ISR so that you can have a memory of what got triggered when you come back after your HTTP request
interrupts should be short... I would not make an http request from within the ISR...
Duly noted. Out of curiosity, what are the consequences of going too long?
write one ISR per pin, each setting up a volatile flag to a known value and in the loop check the flag.
Can do, of course, but was hoping to avoid it -- from a JavaScript perspective (with not a whole lot C++ experience) it seems uneconomical / messy to create a bunch of ISRs that are almost all the same, but not quite.
Regarding volatile flags, a question: How do those not result in memory leaks? Again, I'm not super familiar with C++ and how it handles garbage collection, but my intention of capturing the GPIO pin & value using variables private to the ISR is based on JavaScript-style memory handling. Does the fact that volatiles are stored in RAM, not a storage register, make a difference here?
Do you need to use an interrupt at all ? What is the application ?
My impression is that an interrupt is necessary, but happy to be corrected.
Application is this: MCU is connected to 6 buttons. Push a button toggle a light. The lights are not connected to the MCU. They are controlled by a Linux machine running a server (on the same LAN). So the goal is to have the MCU receive a button push, report that press to the server, and let all toggling be handled by the server machine.
Depending on your microcontroller, some services might be disabled when you are inside an ISR context and other interrupts might be blocked so millis() for example might no longer be running
If this is for buttons pushed by humans then no need for interrupts at all. Using a button library will make it easy.
You create a single ISR for each interrupt. Some of these routines may call a common handler and pass the invoking pin to it. I wonder how you could make that easier by class objects with a built-in pin number in each instance.
On AVR controllers the use of multiple attachInterrupt() for essentially the same purpose is very uneconomical. Instead use a PCINT that can handle up to 8 pins in a single ISR.
Before using a buttons library I tested using @sterretje's suggestion first: just polling the pins.
This worked fine when the MCU was connected to/powered by a USB on a Mac.
Code is designed to send a message to the server when the button is pressed, then lock the button until it's let up, and all was working perfectly.
But when I disconnected from the USB and powered it directly from a 5VDC power supply the whole thing failed: All the buttons were triggering repeatedly. Plugged it back into the USB, and all worked well again.
Any reason why buttons should behave differently depending on the power source?