I have a DS3231 RTC module and I am trying to read time off of it using my Arduino UNO through I2C. I'm using the sample code provided with the library but it doesn't seem to work.
The only thing I get out of the serial monitor is this:
20165-85-165 25:165:165
Temperature=254
I was getting the same thing with another RTC module as well and my guess (which probably isn't true) is that they might have overflown though there doesn't seem to be a reset pin.
#include <DS3231.h>
#include <Wire.h>
DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
byte year, month, date, DoW, hour, minute, second;
void setup() {
// Start the I2C interface
Wire.begin();
#define oneTime
#ifdef oneTime
Clock.setSecond(50);//Set the second
Clock.setMinute(59);//Set the minute
Clock.setHour(11); //Set the hour
Clock.setDoW(5); //Set the day of the week
Clock.setDate(31); //Set the date of the month
Clock.setMonth(5); //Set the month of the year
Clock.setYear(13); //Set the year (Last two digits of the year)
#endif
// Start the serial interface
Serial.begin(115200);
}
void ReadDS3231()
{
int second,minute,hour,date,month,year,temperature;
second=Clock.getSecond();
minute=Clock.getMinute();
hour=Clock.getHour(h12, PM);
date=Clock.getDate();
month=Clock.getMonth(Century);
year=Clock.getYear();
temperature=Clock.getTemperature();
Serial.print("20");
Serial.print(year,DEC);
Serial.print('-');
Serial.print(month,DEC);
Serial.print('-');
Serial.print(date,DEC);
Serial.print(' ');
Serial.print(hour,DEC);
Serial.print(':');
Serial.print(minute,DEC);
Serial.print(':');
Serial.print(second,DEC);
Serial.print('\n');
Serial.print("Temperature=");
Serial.print(temperature);
Serial.print('\n');
}
void loop() {ReadDS3231();delay(1000);}
Having the same problem here, it turns out that the DS3231 communication can get unsynchronised with the microcontroller due to different events. Seems like the cryptic output is coming from that, at least here debugging with a DS3231 connected to an ESP8266 Arduino.
Following the datasheet specification:
The I2C interface is accessible whenever either VCC or VBAT is at a valid level. If a microcontroller connected to the DS3231 resets because of a loss of VCC or other event, it is possible that the microcontroller and DS3231 I2C communications could become unsynchronized, e.g., the microcontroller resets while reading data from the DS3231. When the microcontroller resets, the DS3231 I2C interface may be placed into a known state by toggling SCL until SDA is observed to be at a high level. At that point the microcontroller should pull SDA low while SCL is high, generating a START condition.
And inspired on their official application note 3506
Using the ESP8266 and using their I2C implementation. You can get macros functions on how to access the SDA and SCL pins bitwise. Here is one implemented reset function based on the official example for the 8051.
#define SDA_LOW() (GPES = (1 << SDA))
#define SDA_HIGH() (GPEC = (1 << SDA))
#define SCL_LOW() (GPES = (1 << SCL))
#define SCL_HIGH() (GPEC = (1 << SCL))
#define SDA_READ() ((GPI & (1 << SDA)) != 0)
void resetRTC() {
pinMode(SDA, INPUT_PULLUP);
pinMode(SCL, INPUT_PULLUP);
do {
SDA_HIGH();
SCL_HIGH();
if (SDA_READ()) {
SDA_LOW();
SDA_HIGH();
}
SCL_LOW();
} while (SDA_READ() == 0);
}
This is working fine and seems to solve the problem
A more simple solution would be calling Wire.status()
, it also seems to work.
Wire.status();
I'm not sure if for all cases. This method is doing checks for status and for one case it calls twi_write_start()
which has some similarities with the function resetRTC()
above.
In case you want to implement a similar function for that ATMEL Arduino you will need to look into the bitwise implementation to manipulate SDA and SCL on Arduino I2C core.