Search code examples
c++classarduinomicrocontrollerisr

How to Choose Function Based on Loop Iterator


Part of my problem in finding a solution here is likely that I don't know the correct terms for what it is I am asking. For that, I beg forgiveness in advance.

For a microcontroller, I have a list of pins I wish to initiate at the same time. Each has it's own ISR, and calls the same member of a class for each instance but with a pin number as an argument.

I am trying to attach each pin in the array to its corresponding ISR but I would like to choose which ISR by the pin's index. This is Mailer Code™ and likely does not compile but I believe it's enough to get the idea:

#define PIN1 4
#define PIN2 9
#define PIN3 10
#define PIN4 8
#define PIN5 12

PinAct *pPinact; // Pointer to Counter class

static ICACHE_RAM_ATTR void HandleInterruptsStatic1(void) {
    pPinact->handleInterrupts(1);
}

static ICACHE_RAM_ATTR void HandleInterruptsStatic2(void) {
    pPinact->handleInterrupts(2);
}

static ICACHE_RAM_ATTR void HandleInterruptsStatic3(void) {
    pPinact->handleInterrupts(3);
}

static ICACHE_RAM_ATTR void HandleInterruptsStatic4(void) {
    pPinact->handleInterrupts(4);
}

static ICACHE_RAM_ATTR void HandleInterruptsStatic5(void) {
    pPinact->handleInterrupts(5);
}

class PinAct {
    public:
        PinAct() {};
        void handleInterrupts(int);
}

void PinAct::PinAct() {
    int actPins[] = {PIN1, PIN2, PIN3, PIN4, PIN5};
    for (int i = 0; i <= sizeof(actPins); i++) {
        pinMode(actPin[i], INPUT)
        attachInterrupt(digitalPinToInterrupt(KEG1), HandleInterruptsStatic + i, FALLING);
    }
}

void PinAct::handleInterrupts(int pin) { // Bubble Interrupt handler
    // Do something with pin
}

The goal is to actually make the attachInterrupt(digitalPinToInterrupt(KEG1), HandleInterruptsStatic + i, FALLING); work, choosing which ISR by virtue of the index i.

I need to make other decisions about whether or not to assign the ISR, so concatenating the ISR name to be assigned is desirable.


Solution

  • attachInterrupt(/* ... */, HandleInterruptsStatic + i, /* ... */);
    //                                              ^^^^^
    

    In order to select the function you want to call at runtime depending on some integer index i you can use an array of function pointers:

    typedef void (*FunctionPointer_t)(void);
    FunctionPointer_t functions[] = {
        HandleInterruptsStatic1,
        HandleInterruptsStatic2,
        // ...
      };
    
    // to use:
    functions[i]();