Monitoring of Patterns with Arduino Micro

Hi,

I'm trying to program an Arduino Micro to be able to recognise a pattern that is generated from another Arduino board and if the pattern is ever wrong, to take over generating the pattern (basically a redundancy thing). The whole "taking over" part should be plain and simple but I'm struggling with getting the pattern recognition working.

The output pattern I need to monitor is as below and repeats every 30 seconds:

HIGH for 500ms
LOW for 500ms

HIGH for 500ms
LOW for 500ms

HIGH for 1000ms
LOW for 27s

Unfortunately, it's not as easy as using pulseIn() to monitor the incoming signal as I have the Arduino currently running using the TaskScheduler library and don't want to interfere with the timers, if possibly, for fear of under or overrunning times within the library.

All logic in the software is inverted to standard as I'm using a ULN2803A output driver so it inverts the functionality for me as well as providing some drive current for my signals.

So, my project currently works as follows:

In the setup() function, the Arduino sets pin D2 as an input and enables the pullup resistor. It then reads the pin state and if it is still HIGH (by the pullup resistor) it knows it is a "Master" device (the device generating the code without monitoring the other) and if it is LOW (grounded externally) then it knows it is a "Slave" device (the device monitoring the other for wrong pattern generation), like so:

void setup() 
{
  // Inputs
  pinMode(2, INPUT_PULLUP);

  // Outputs
  pinMode(12, OUTPUT);

  // Read CO pin - determine master or slave
  if (digitalRead(D2) == 1)
  {
    isMaster = 1;
    // Enable TaskScheduler task
    Task t1(30000, -1, &outputTask, &runner, true);
  
  } else if (digitalRead(D2 == 0))
  {
    isMaster = 0;
    // Don't enable TaskScheduler task
    Task t1(30000, -1, &outputTask, &runner, false);
  }

  // Delay by 3 seconds
  delay(3000);
}

The outputTask function is as simple as this:

void outputTask(void) 
{
 digitalWrite(12, LOW);
 delay(500);
 digitalWrite(12, HIGH);
 delay(500);
 
 digitalWrite(12, LOW);
 delay(500);
 digitalWrite(12, HIGH);
 delay(500);
 
 digitalWrite(12, LOW);
 delay(1000);
 digitalWrite(12, HIGH);
 
}

I've read through many tutorials for manipulating the Arduino timers and interrupts etc but I'm still trying to wrap my head around the best way to do it. I understand that this is a pretty specific case but any ideas that anyone else has would be greatly received.

Unfortunately, it's not as easy as using pulseIn() to monitor the incoming signal as I have the Arduino currently running using the TaskScheduler library and don't want to interfere with the timers, if possibly, for fear of under or overrunning times within the library.

For the described task that library is absolutely unnecessary. As the signal is extremely slow you can check it also by just using the millis() function to get the current time since startup.

Using delay() calls in cooperative multitasking is not the way to do it.

pylon:
For the described task that library is absolutely unnecessary. As the signal is extremely slow you can check it also by just using the millis() function to get the current time since startup.

Using delay() calls in cooperative multitasking is not the way to do it.

I know that using the delay() function stops the TaskScheduler library from doing its thing, I'm still working on moving the outputTask() function away from it and using the pinned example for multitasking as a basis using the millis() timer.

I'm using the TaskScheduler library to do a couple of other things in the background but I do plan on, like you say, setting up a state machine to see if I can replace the library. Regarding the pattern monitoring, do you think it would be wise to wire it to an interrupt and update any time-referenced variables (such as time high, time low, time since last pattern) from the ISR, or better yet - fire another function from the ISR to update the variables?

He used a naughty word!

Interrupt!

Paul__B:
He used a naughty word!

Interrupt!

I would never! :-X

Regarding the pattern monitoring, do you think it would be wise to wire it to an interrupt and update any time-referenced variables (such as time high, time low, time since last pattern) from the ISR, or better yet - fire another function from the ISR to update the variables?

To give you a short answer: No.

Everything clearly visible to the human eye is definitely slow enough to be simply polled in the loop().

But to act in a timely manner you must eliminate all delay() calls. the BlinkWithoutDelay example sketch shows you the way to do such things.

pylon:
To give you a short answer: No.

Everything clearly visible to the human eye is definitely slow enough to be simply polled in the loop().

But to act in a timely manner you must eliminate all delay() calls. the BlinkWithoutDelay example sketch shows you the way to do such things.

Thanks for the feedback. I am moving away from the delay() calls - I'm still new to the whole "multitasking" aspect so it was a quick and dirty fix as I was building up the software.