Close

ANTIRTOS library test: delayed functions with parameters

aleksei-tertychnyiAleksei Tertychnyi wrote 09/27/2024 at 14:46 • 5 min read • Like

Here below is easy to repeat ease LEDs test, utilizing one of the classes on the ANTIRTOS library, classes are in depended, so you may use one you need. See simulation here: Simulation in wokwi.com 

The ANTIRTOS is a broad use library, not only for the Arduino,  use it where ever you want! It is native C++.

Example run on Arduino Nano (including everything, no any external library include needed):

// HERE IS ONE OF ANTIRTOS CLASSes below : del_fQP (see the rest desc. on https://github.com/WeSpeakEnglish/ANTIRTOS )
/// @brief delayed functional pointers queue with parameters
template <typename T>
class del_fQP {
private:
    int first;
    volatile int last;
    int length;
    unsigned int time;
    typedef void (*fP)(T);
    fP * FP_Queue;
    fP * del_FP_Queue;                  // delayed functions
    bool * execArr;                     //is need to be executed?
    unsigned int * execTime;            //execution time arr 
    T* PARAMS_array;
    T* delayed_PARAMS_array;
    int push(void (*pointerQ)(T), T parameterQ);
    
public:
    del_fQP(int sizeQ);
    ~del_fQP();
    int push_delayed(void (*pointerQ)(T), T parameterQ, unsigned int delayTime);
    void tick(void);
    int pull();
};

template <typename T>
del_fQP<T>::del_fQP(int sizeQ) {
    FP_Queue = new fP[sizeQ];
    del_FP_Queue = new fP[sizeQ];
    execArr = new bool[sizeQ];
    PARAMS_array = new T[sizeQ];
    delayed_PARAMS_array = new T[sizeQ];
    execTime = new unsigned int[sizeQ];
    last = 0;
    first = 0;
    time = 0;
    for(unsigned int i = 0; i < sizeQ; i++){
      execArr[i] = false;
    }
    length = sizeQ;
}

template <typename T>
del_fQP<T>::~del_fQP() {
    delete[] FP_Queue;
    delete[] del_FP_Queue;
    delete[] PARAMS_array;
    delete[] delayed_PARAMS_array;
    delete [] execArr;
    delete [] execTime;
}

template <typename T>
int del_fQP<T>::push(void (*pointerQ)(T), T parameterQ) {
    if ((last + 1) % length == first) return 1;
    FP_Queue[last] = pointerQ;
    PARAMS_array[last] = parameterQ;
    last = (last + 1) % length;
    return 0;
}

template <typename T>
int del_fQP<T>::push_delayed(void (*pointerQ)(T), T parameterQ, unsigned int delayTime) {
bool fullQ = true;                                              // is Queue full?
     for(unsigned int i = 0; i < length; i++){
      if (!execArr[i] ){
       del_FP_Queue[i] = pointerQ;                              // put function pointer into exec queue 
       delayed_PARAMS_array[i] = parameterQ;                    // put parameter into exec queue    
       execArr[i] = true;                                       // true flag for execution
       execTime[i] = time + delayTime;                          //calc execution time, no worry if overload
       fullQ = false;
       break;
       }
  }
  if (fullQ) return 1;
  return 0;
}

template <typename T>
void del_fQP<T>::tick(void){
  static unsigned int i = 0 ;  //uses in search cycle every tick
   for(i=0; i < length; i++){
     if(execTime[i] == time)
      if(execArr[i]){
       push(del_FP_Queue[i],delayed_PARAMS_array[i]);  // bump into normal queue part of delayed Queue
       execArr[i] = false;
     }
   }
  time++;
}

template <typename T>
int del_fQP<T>::pull() {
    fP pullVar;
    if (last != first) {
        T Params = PARAMS_array[first];
        pullVar = FP_Queue[first];
        first = (first + 1) % length;
        pullVar(Params);
        return 0;
    }
    else {
        return 1;
    }
}
//////////////////////////////////////////// HERE THE SIMLE TEST BELOW//////////////////////////////////
typedef 
struct pinOut{ // structure (index - pin number, logic - 1/0 = ON/OFF)
  int index;
  bool logic;
} pinout ;

del_fQP<pinout> Q1(8); // maximum 8 function pointers with parameters in queue

void writePin(pinout cmd){ // write a pin true =- ON
  
  digitalWrite(cmd.index, cmd.logic);

}

void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);

  TCCR1A = 0x00;  //Normal Mode
  TCCR1B = 0x00;  //TC1 is OFF
  TCNT1 = 0;
  OCR1A = 6250;  //0.1s delay; prescaler 256
  bitSet(TIMSK1, OCIE1A);   //local intterupt is active
  TCCR1B |= bit(CS12);   //Start TC1 with prescale 256
  
  // here putting 8 pointers to functions, parameters and delays needed

  Q1.push_delayed(writePin,{12,true},20); //yellow led ON after 2 sec. (0.1*20 = 2 seconds)
  Q1.push_delayed(writePin,{12,false},30); //yellow led OFF after 3 sec.
  Q1.push_delayed(writePin,{13,true},50); //red led ON after 5 sec.
  Q1.push_delayed(writePin,{13,false},80); //red led OFF after 8 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 0.1 sec
{
  TCNT1 = 0;
  OCR1A = 6250;
  Q1.tick(); // execute tick method for make delayed functionality works
}
Like

Discussions