I want to use the ZS-042 RTC Real Time Clock module to capture milli seconds from my sensor readings. I have read multiple forums that say it is possible, but no one gives real guidance. Can anyone help me with the required code to obtain milli seconds? I cannot figure it out. This link gave me some guidance as well: timer - How to get millisecond resolution from DS3231 RTC - Stack Overflow
I suspect not. You need to read the datasheet yourself, rather than have some clown on StackOverflow tell you what he thinks he read. The DS3231 datasheet clearly tells you on p13 that it offers a 1Hz output on the first option, not 1kHz, so I believe you can forget about that. Note, however, that Arduino has its own millisecond facility. I assume you need proper real time, hence the RTC, so you might get a result combining the two. This means an Arduino clock controlled by the 1Hz square wave from the RTC.
ZS-0542 is merely a breakout board for the DS3231.
It's not clear what you want to do. Could you explain in more detail?
In any case, I think you might be able to combine the RTC with the Arduino's millis() function to produce useful results. The DS3231 can be set to produce a 1Hz square wave, which will go low at the beginning of each second. You could use that as a FALLING interrupt on D2, and record the millis() value when that interrupt occurs. Then you could compare that to the millis() value when you read your sensors. But it's not clear if that's what you want to do.
I need to know the exact time the sample was taken when my system is not hooked to my computer. That means I only can use the on board clock or external. External is better since if power goes out then I will not lose time, but the RTC does not record down to milli seconds from what I understand easily
But I need to record the entire time shown. My understanding is I have 2 options. The on board RTC or an external, but not sure how to get the milli seconds time as well
OK. I think Sherman is saying much the same as I was. The 1Hz square wave from DS3231controls Arduino's loop time, where millis gets a restart and the event gives you the count from there.
This cannot be something new....
You would use the RTC's square wave output to trigger an interrupt on its falling edge. The interrupt service routine would update the seconds count (plus minutes and hours if seconds rolls over to 60), and also record the millis() value. That marks the beginning of the second. Then when you do your sensor reading, you get the millis() value again, and the difference is the number of milliseconds that have elapsed since the second began.
But the RTC by itself can only provide the time to the second.
I guess I'm one of those guys but, in the absence of better advice from Sherman, try aquiring
thou=millis at the start of the loop, and
thou=millis-thou at the event
This code is printing the current time and temperature in Fahrenheit no problem, but the time in milli seconds is not going up even when I have the SQW wired to pin 32.
I have currently wired:
GND to GND of Esp32
VCC to 3.3V of Esp32
SDA to Pin 21 of Esp32
SCL to Pin 22 of Esp32
SQW to Pin 32 of Esp32
Here is the code and output below:
Code:
#include "RTClib.h"
RTC_DS3231 rtc;
int interrupt_pin = 32;
int current = 0;
int milliseconds = 0;
void IRAM_ATTR function()
{
milliseconds = millis() - current;
current = millis();
}
void setup() {
Serial.begin(9600);
rtc.begin();
pinMode(interrupt_pin, INPUT_PULLUP);
attachInterrupt(interrupt_pin, function, FALLING);
// Set the time to 11:30 AM
rtc.adjust(DateTime(__DATE__, __TIME__));
rtc.adjust(DateTime(0, 0, 0, 11, 20, 0)); // Set the desired time here
}
void loop() {
DateTime now = rtc.now();
// Display time
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.print('.');
Serial.print(milliseconds);
float temperatureC = rtc.getTemperature();
float temperatureF = (temperatureC * 9 / 5) + 32; // Convert Celsius to Fahrenheit
Serial.print(" ");
Serial.println(temperatureF);
}
What Arduino board has an external interrupt on pin 32?
Variables changed in an ISR (Interrupt Service Routine) should be declared volatile.
Ones should use an interrupt guard when reading multi-byte variables that are changed in an ISR. Copy the value of the variable and work with the copy. If one does not use the interrupt guard, an interrupt can change the value of the variable during the read resulting in corrupted data.
For example:
noInterrupts();
long isrVariableCopy = isrVariable;
interrupts();
// use isrVariableCopy for any further operations
Next bug will be here. Occasionally you'll get corrupted data. Should be.
noInterrupts();
unsigned int copy = milliseconds;
Interrupts();
Serial.print(copy);
And really those variables holding milliseconds should at least be unsigned lest you end up with negative times. Really they should be unsigned long, but it's not strictly necessary unless you want to keep time for a long time.