Skip to main content
1 of 3

Multiple Time-Sensitive Tasks

I'm using an Arduino Leonardo and need to perform two time-sensitive tasks like this:

// Task 1 - Gets executed once a second (1Hz)
// Execution of task needs approx 70ms
   task1(); //Sending a message via Serial

// Task 2 - Gets executed 50 times a second (50Hz)
// Execution of task need a few micros
   task2(); //digitalWrite

As you can see, the problem is, that task one needs very long for execution and therefore task2 is executed too late to send a 50Hz signal. I'm not sure how, but I think there must be a way to give task 1 higher priority to interrupt task 2?

Thanks in advance! :)

Just for completion, here is my (not so clean) code:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 6); //232_TX,232_

int triggerFreq = 10;
unsigned long timestamp_pps;
unsigned long timestamp;
unsigned long triggerStartTime;
const unsigned long dt_pps = 1000000; //micros
const unsigned long dt_trig = 1000000/triggerFreq; //micros
unsigned long ts_pps_high;
unsigned long ts_pps_low;
unsigned long ts_msg_high;
unsigned long ts_msg_low;


unsigned long i_pps = 0;
unsigned long i_trig = 0;

int hh = 04;
int mm = 51;
int ss = 00;
unsigned int pos = 2307;
bool msg;
bool trigMsgSent;


void setup() {
  // put your setup code here, to run once:
  pinMode(11, OUTPUT); // PPS
  pinMode(12, OUTPUT); // Indicator of msg_sent
  pinMode(13, OUTPUT); // FPS
  Serial.begin(9600);
  mySerial.begin(9600);
  triggerStartTime = micros();
}

void loop() {
  // ================== Part for the GPS Simulation ==================
  timestamp_pps = micros()-triggerStartTime;
  if (timestamp_pps>= dt_pps*i_pps+350000)
  {
    pos += 1;
    digitalWrite(12,HIGH);
    i_pps +=1;
    if (ss == 59)
    {
      ss=0;
      if (mm==59)
      {
        mm=0;
        hh+=1;
      }
      else mm+=1;
    }
    else ss+=1;

    ts_msg_high = micros();
    mySerial.print("$GPRMC,");
    if (hh<10) mySerial.print(F("0"));
    mySerial.print(hh);
    if (mm<10) mySerial.print(F("0"));
    mySerial.print(mm);
    if (ss<10) mySerial.print(F("0"));
    mySerial.print(ss);
    mySerial.print(".000,A,3015.");
    mySerial.print(pos);
    mySerial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");
    
    // Print Debug Messages
    digitalWrite(12,LOW);
    ts_msg_low=micros();
    Serial.print("PPS at: ");
    Serial.print(ts_pps_high);
    Serial.print("\t PPS low after: ");
    Serial.print(ts_pps_low-ts_pps_high);
    Serial.print("\t MSG high after: ");
    Serial.print(ts_msg_high-ts_pps_high);
    Serial.print("\t MSG low after: ");
    Serial.print(ts_msg_low-ts_pps_high);
    Serial.print("$GPRMC,");
    if (hh<10) Serial.print(F("0"));
    Serial.print(hh);
    if (mm<10) Serial.print(F("0"));
    Serial.print(mm);
    if (ss<10) Serial.print(F("0"));
    Serial.print(ss);
    Serial.print(".000,A,3015.");
    Serial.print(pos);
    Serial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");
  }
  else if (timestamp_pps>=dt_pps*i_pps+100000)
  {
    digitalWrite(11,LOW);
    if (msg==true)
    {
      msg = false; 
      ts_pps_low = micros();
    }
    
  }
  else if (timestamp_pps>=dt_pps*i_pps)
  {
    digitalWrite(11,HIGH);  
    if (msg==false)
    {
      msg = true;
      ts_pps_high = micros();
    }
  }
  // ================== Part for the FPS Trigger ==================
  timestamp = micros()-triggerStartTime;
  if (timestamp>= dt_trig*i_trig+2000)
  {
    digitalWrite(13,LOW);
    i_trig +=1;
    trigMsgSent = false;
  }
  else if (timestamp >=dt_trig*i_trig)
  {
    digitalWrite(13,HIGH);
    if (trigMsgSent == false)
    {
      Serial.print("FPS at: ");
      Serial.println(micros());
      trigMsgSent = true;
    }
  }
  
}