take a look at my library interrupt.cpp and interrupts.h located here ZHomeSlice/Arduino_Interrupts
I store functions created in the .ino file and store them for each time the pin change events occur.
see:
InterruptsClass & InterruptsClass::onInterrupt(void (*CB)(uint32_t,uint32_t,uint32_t)){
Int_CB = CB;
return *this; // return Pointer to this class
}
InterruptsClass & InterruptsClass::onPin(int Pin, int InputType, void (*CB)(uint32_t,uint32_t,uint32_t)){
AddPin( Pin, InputType);
PinCB[Pin] = CB;
return *this; // return Pointer to this class
}
then when the pin changes state I run the provided functions
void ISR_Exe(){
_Pins.Port[0] = PIND; // 0-7
_Pins.Port[1] = PINB; // 8-13
_Pins.Port[2] = PINC; // A0-A6
uint32_t _cTime = micros();
_Pins.Port[3] = 1; // Placeholder
uint32_t _Changed = _Pins.All ^ _PCintLast;// doing a ^ between the current interruption and the last one indicates which pin changed
uint32_t _Masked = _Changed & _PinMask;// Has one of the pins we need changed
if(!_Masked)return; //No Data move on
if (Int_CB) {
Int_CB(_cTime, _Masked,_Pins.All); // Callback Function
}
Interupted++;
_PCintLast = _Pins.All; // we memorize the current state of all PINs in group
}
and
void InterruptsClass::PinCallBack(uint32_t Time, uint32_t PinsChanged, uint32_t Pins){
for(byte Pin = 0;Pin<20;Pin++){
if(bitRead(PinsChanged, Pin)){
if (PinCB[Pin]) {
PinCB[Pin](Time,PinsChanged,Pins);
}
}
}
}
my header file is basically this:
class InterruptsClass {
public:
// Interrupts();
uint8_t BitNumber[20] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21}; // Key = Pin Val = Position List of pins that could be used as ping inputs:
static void nothing(void) {};
static void nothing(uint32_t,uint32_t,uint32_t) {};
typedef void (*voidFuncVoidPtr)(void);
typedef void (*voidFunc3u32Ptr)(uint32_t,uint32_t,uint32_t);// Create a type to point to a function.
voidFunc3u32Ptr PinCB[20] = {nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing}; // Key = Pin Val = Position List of pins that could be used as ping inputs:
InterruptsClass & AddPin(uint8_t pin, uint8_t InputType = INPUT);
InterruptsClass & onInterrupt(void (*CB)(uint32_t,uint32_t,uint32_t));
InterruptsClass & onPin(int Pin, int InputType, void (*CB)(uint32_t,uint32_t,uint32_t));
void PinCallBack(uint32_t Time, uint32_t PinsChanged, uint32_t Pins);
bool CheckPin(uint8_t Pin);
InterruptsClass & Timer0Enable();
InterruptsClass & onTimer0(void (*CB)(void));
InterruptsClass & Timer1Enable();
InterruptsClass & Timer2Enable();
// *************************************************************
volatile uint32_t EdgeTime[20]; // Time Storage
// RC Remote
volatile uint16_t RCRemote(uint8_t Pin, uint32_t cTime, uint32_t Pins,bool ValidRC = true);
// Ping
volatile int16_t Ping(uint8_t Pin, uint32_t cTime, uint32_t Pins);
// Encoder
volatile int8_t Encoder(uint8_t ClockPin, uint8_t DataPin, uint32_t Pins,bool HalfStep);
// Switch
volatile int8_t Switch (uint8_t Pin,uint16_t cTime,int16_t debounceTime,bool OnRise);
// Sample Time
volatile uint16_t SampleTime(uint8_t Pin, uint32_t cTime, uint32_t Pins,bool OnRise);
volatile uint16_t DelayTimer(uint8_t Pin, uint32_t cTime, uint32_t Pins,bool OnRise);
volatile int32_t Tachometer(uint8_t ClockPin, uint8_t DataPin, uint32_t cTime, uint32_t Pins);
};
The .ino file setup function looks like this:
void setup() {
Serial.begin(115200); //115200
Serial.println(" testing");
// put your setup code here, to run once:
pinMode(9, OUTPUT);
Interrupt.onInterrupt([](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
sei(); // re enable other interrupts at this point,
Interrupt.PinCallBack(Time, PinsChanged, Pins);
});
Interrupt.onPin(4, INPUT_PULLUP, [](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
if (Interrupt.CheckPin(4)) { // rising
Serial.println(" Pin 4 Rising \t");
} else { // Falling
Serial.println(" Pin 4 Falling \t");
}
});
Interrupt.onPin(5, INPUT, [](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
uint16_t RCTime = Interrupt.RCRemote(5, Time, Pins, true);
if (RCTime) {
Serial.print(" RC Time:");
Serial.print(RCTime);
}
});
Interrupt.onPin(6, INPUT, [](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
unsigned int PingTime = Interrupt.Ping(6, Time, Pins);
if (PingTime) {
Serial.print("Ping \t");
Serial.print(microsecondsToCentimeters(PingTime));
Serial.println("cm");
}
});
Interrupt.onPin(9, INPUT_PULLUP, [](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
Serial.print("Switch \t");
Serial.println(Interrupt.Switch(9, Time, 1000, false));
});
Interrupt.onPin(10, INPUT_PULLUP, [](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
Serial.print("Switch \t");
Serial.println(Interrupt.Switch(10, Time, 1000, false));
});
Interrupt.onPin(11, INPUT_PULLUP, [](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
Serial.print("Switch \t");
Serial.println(Interrupt.Switch(11, Time, 1000, false));
});
Interrupt.onPin(12, INPUT, [](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
EncoderCounter += Interrupt.Encoder(12, 13, Pins, true);
Serial.print("Count ");
Serial.print(EncoderCounter);
Serial.print("\t Encoder \t");
Serial.println(Interrupt.Encoder(12, 13, Pins, true));
});
Interrupt.onPin(13, INPUT, [](uint32_t Time, uint32_t PinsChanged, uint32_t Pins) {
EncoderCounter -= Interrupt.Encoder(12, 13, Pins, true);
Serial.print("Count ");
Serial.print(EncoderCounter);
Serial.print("\t Encoder \t");
Serial.println(-1 * Interrupt.Encoder(12, 13, Pins, true));
});
}
I call the function of the class within the Lambda function
unsigned int PingTime = Interrupt.Ping(6, Time, Pins);
I can only show you examples of my successes as I'm not fully understanding your question.
Z