When I call RTCZero getEpoch() at the moment an external device is sending a serial message over the rs232 port, one or more charecters are lost. I assume that for some reason interrupts are blocked by RTCZero inplementation.
I encountered this problem at the SodaqONE and some time back on the Autonomo too (not 100% sure however, it’s a while ago).
The commit bd4d27f pulled the fix I submitted in March. However, this wasn’t released properly until the end of July.
The correct code should look like this now:
The issue was that if you tried to read the CLOCK register while it was in the middle of a synchronisation, it would stall the bus and block all interrupts until the synchronisation was complete. The fix calls a synchronisation request, and waits for it to complete, before reading the CLOCK register. Additionally, the CLOCK register is read in a single operation now instead of piecewise.
What does your interrupt routine look like (ISR). While, the SAMD platform does support nested interrupts, an interrupt routine will block any other interrupts of equal or lower priority.
The SERCOMs in UART mode use an interrupt when new data is received. That interrupt copies the data into the appropriate buffer. If the interrupt is blocked for long enough, a new character will have arrived, meaning the old character is lost.
I am using the standard SodaqONE Serial instance that is connected to the TX and RX pins of the ONE. Not sure which driver/interrupt routines are behind.
However, it is clear that I still miss characters due to the interrupt being blocked too long.
I assume that the hardware defines the interrupt order/priority?
Oh, sorry I thought you were using the RTC interrupt as well.
The SERCOM NVIC priority is set on line 687 of cores/arduino/SERCOM.cpp. I’m fairly certain that the set value resolves to 0, which is the highest priority level (Samd21 supports 4 priority levels).
Perhaps we can test a few things.
First, could you try commenting out line 371 of RTCZero.cpp.
You will receive an incorrect epoch value, but I’m curious if it is the read operation that is at fault.
You could also try, separately, commenting out the synchronisation request on line 369 of RTCZero.cpp.
Please find below. Make sure that you use a different source that sends that data. Using the Serial.PrintLn() will not cause problems as it is synchronous, so all bytes are sent before the rtc.getEpoch(); is called.
Axel
#include <RTCZero.h>
#define CONSOLE_SERIAL SerialUSB
#define ENABLE_READER 1
RTCZero rtc;
static int cnt = 0;
// the setup function runs once when you press reset or power the board
void setup()
{
while ((!SerialUSB) && (millis() < 10000)) {
// Wait 10 seconds for the debugSerial
}
delay(1000);
pinMode(ENABLE_READER, OUTPUT);
digitalWrite(ENABLE_READER, HIGH);
Serial.begin(19200);
rtc.begin();
CONSOLE_SERIAL.println(String("Starting"));
}
// the loop function runs over and over again until power down or reset
void loop()
{
rtc.getEpoch();
if (Serial.available())
{
String test = Serial.readStringUntil(0x0d);
CONSOLE_SERIAL.println(test);
}
}
If you are willing to send your whole sketch to me, I can try testing it to see if there is some other issue.
You can email me at: gabriel at sodaq dot com
The issue was eventually tracked down and is related to using the VisualMicro plugin for VisualStudio.
Building the and programming the board via the Arduino IDE resolved the issue.
The exact cause of the issue, while using VisualMicro, is not yet known.