Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I can't get DS3231 RTC to work

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);}
like image 378
Ege Feyzıoglu Avatar asked Nov 10 '22 02:11

Ege Feyzıoglu


1 Answers

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.

like image 60
calmar Avatar answered Dec 28 '22 10:12

calmar