Good morning all. I need to use a Due to decode a DCF77 stream coming from a GPS time source. So basically the latter generates a current-loop signal at 1 baud where each leading edge is aligned with a UTC second and the time data is encoded as variable pulse widths over a 60s period. I know there is an Arduino library to do this so it shouldn't be a great problem. However the Due is also performing other tasks, in particular handling another 1pps (nominal) pulse stream from a mechanical clock.
So my question is, what demands does the DCF77 library put on the processor? I assume that the pulse input raises an interrupt on the leading edge and an internal timer is used to decide the incoming pulse length. If I am using another interrupt to handle the local pulses with another associated timer what interrupt priorities are needed to ensure the DCF77 decoding works correctly?
Sounds like you need the Due to react to 2 or 3 events/edges per second. It's internal clock is 84 million edges per second. The load is tiny.
Hopefully the DCF77 library is well written with short interrupt routines. Just make sure your own interrupt routines are also short. Don't use delays or print to serial monitor or anything complex in the interrupt routines.
In my view, interrupt service routines should be short and sweet. But they always take a (relatively) shocking amount of time to save registers and restore them later; I'm not familiar with the processor on your board, it might be less of an issue compared to AVR based boards.
You can aks yourself if your really need an interrupt to monitor the pin connected to the mechanical clock? After all, it's a very slow signal and loop() can read that pin hundreds (if not thousands) of times in a second.
Not necessarily; use while-loops and for-loops wisely, don't use delay(), consider finite state machines if necessary.
Below is the blink-without-delay example combined with a state-chance detection to demonstrate. There is no debouncing implemented.
/*
bwod related
*/
// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN;// the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const long interval = 1000; // interval at which to blink (milliseconds)
/*
mechanical clock related
*/
const uint8_t clockinputPin = 2;
void setup()
{
Serial.begin(115200);
while(!Serial);
Serial.println("starting");
pinMode(clockinputPin, INPUT_PULLUP);
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop()
{
bwod();
readClock();
}
/*
blink without delay (literal copy of the example)
*/
void bwod()
{
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
void readClock()
{
static uint8_t lastClockState;
// get current state of clock pin
uint8_t currClockState = digitalRead(clockinputPin);
if (currClockState != lastClockState)
{
lastClockState = currClockState;
Serial.print(millis());
Serial.print(" > ");
Serial.println(currClockState);
}
}