#define fQ(q, Q_SIZE) \
volatile int q##_last = 0; \
int q##_first = 0; \
void (*q##_Queue[Q_SIZE])(void); \
int q##_Push(void (*pointerQ)(void)) { \
if ((q##_last + 1) % Q_SIZE == q##_first) \
return 1; /* Queue is full */ \
q##_Queue[q##_last++] = pointerQ; \
q##_last %= Q_SIZE; \
return 0; /* Success */ \
} \
int (*q##_Pull(void))(void) { \
if (q##_last == q##_first) \
return 1; /* Queue is empty */ \
q##_Queue[q##_first++](); \
q##_first %= Q_SIZE; \
return 0; /* Success */ \
}
#define del_fQ(q, Q_SIZE) \
int q##_time = 0; \
void (*q##_del_fQueue[Q_SIZE])(void); \
int q##_execArr[Q_SIZE] = { 0 }; \
int q##_execTime[Q_SIZE]; \
fQ(q, Q_SIZE) \
int q##_Push_delayed(void (*pointerF)(void), int delayTime){ \
int q##_fullQ = 1; \
for (int i = 0; i < Q_SIZE; i++) { \
if (!q##_execArr[i]) { \
q##_del_fQueue[i] = pointerF; \
q##_execArr[i] = 1; \
q##_execTime[i] = q##_time + delayTime; \
q##_fullQ = 0; \
break; \
} \
} \
return q##_fullQ; \
} \
void q##_Tick(void){ \
for (int i = 0; i < Q_SIZE; i++) { \
if (q##_execTime[i] == q##_time) { \
if (q##_execArr[i]) { \
q##_Push(q##_del_fQueue[i]); \
q##_execArr[i] = 0; \
} \
} \
} \
q##_time++; /* Increment time */ \
} \
int q##_Revoke(void (*pointerF)(void)){ \
int result = 1; \
for (int i = 0; i < Q_SIZE; i++) { \
if (q##_del_fQueue[i] == pointerF) { \
q##_execArr[i] = 0; \
result = 0; \
} \
} \
return result; \
}
//////////////////////////////////////////// HERE THE SIMLE TEST BELOW//////////////////////////////////
del_fQ(Q1,4); // maximum 4 function pointers in delayed queue
void writePin(){ // write a pin true =- ON
static int cont=10;
static int logic = 0;
static int counter = 0;
if (logic)
logic = LOW;
else
logic = HIGH;
digitalWrite(cont/2,logic);
cont++;
cont%=26;
if(cont < 10 ) cont = 10;
Q1_Push_delayed(writePin,1);
}
void revokeTest(){
Q1_Revoke(writePin);
}
void setup() {
// put your setup code here, to run once:
for(int i=5; i< 13; i++)
pinMode(i, OUTPUT);
TCCR1A = 0x00;
TCCR1B = 0x00;
TCNT1 = 0;
OCR1A = 62499; // Set OCR1A to 62499 for a 1-second interval
bitSet(TIMSK1, OCIE1A);
TCCR1B |= bit(CS12); // Use prescaler of 256
Q1_Push_delayed(writePin,1); // period 1 sec.
Q1_Push_delayed(revokeTest,100); //revoke after 100 sec.
}
void loop() {
// put your main code here, to run repeatedly:
Q1_Pull(); // pull from the queue
}
ISR(TIMER1_COMPA_vect) // timer interrupt ticks one per 1 sec
{
TCNT1 = 0;
OCR1A = 62499;
Q1_Tick(); // execute tick method for make delayed functionality works
}