Categories

Follow Us

Reading temperature using the DS3231 RTC

Did you know that you can read the temperature from a DS3231 RTC – the DS3231 uses temperature compensation to calibrate the adjustable capacitors of its resonance circuit, in order to maintain time and date with accuracy

The DS3231 is a low-cost, extremely accurate I2C real-time clock (RTC) with an integrated temperaturecompensated crystal oscillator (TCXO) and crystal.
The device incorporates a battery input, and maintains accurate timekeeping when main power to the device is interrupted. The integration of the crystal resonator enhances the long-term accuracy of the device as well as reduces the piece-part count in a manufacturing line.

The RTC maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year. The clock operates in either the 24-hour or 12-hour format with an AM/PM indicator. Two programmable time-of-day alarms and a programmable square-wave output are provided. Address and data are transferred serially through an I2C bidirectional bus.

A precision temperature-compensated voltage reference and comparator circuit monitors the status of VCC to detect power failures, to provide a reset output, and to automatically switch to the backup supply when necessary. Additionally, the RST pin is monitored as a pushbutton input for generating a μP reset.

Some specific info from the datasheet

Temperature Registers (11h–12h)

Temperature is represented as a 10-bit code with a resolution of 0.25°C and is accessible at location 11h and 12h. The temperature is encoded in two’s complement format. The upper 8 bits, the integer portion, are at location 11h and the lower 2 bits, the fractional portion, are in the upper nibble at location 12h. For example, 0001100101b = +25.25°C. Upon power reset, the registers are set to a default temperature of 0°C and the controller starts a temperature conversion.

The temperature is read on initial application of VCC or I2C access on VBAT and once every 64 seconds afterwards. The temperature registers are updated after each user-initiated conversion and on every 64-second conversion. The temperature registers are read-only.

Parts List

nameLink
Arduino UnoUNO R3 CH340G/ATmega328P, compatible for Arduino UNO
DS3231 RTC
connecting wireFree shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire

 

Connection

 Arduino PinsModule Pins 
 GND GND
5v VCC
A4 SDA
A5 SCL

 

Code

This example requires the https://github.com/Makuna/Rtc

// These tests do not rely on RTC hardware at all
 
//#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
 
void PrintPassFail(bool passed)
{
    if (passed)
    {
      Serial.print("passed");
    }
    else
    {
      Serial.print("failed");
    }
}
 
void ComparePrintlnPassFail(RtcTemperature& rtcTemp, float compare)
{
    Serial.print(rtcTemp.AsFloatDegC());
    Serial.print("C ");
    PrintPassFail(rtcTemp.AsFloatDegC() == compare);
    Serial.println();
}
 
void ConstructorTests()
{
    // RTC constructors
    Serial.println("Constructors:");
    {
      RtcTemperature temp075Below(0b11111111, 0b01000000); // -0.75 
      ComparePrintlnPassFail(temp075Below, -0.75f);
 
      RtcTemperature temp050Below(0b11111111, 0b10000000); // -0.5 
      ComparePrintlnPassFail(temp050Below, -0.50f);
 
      RtcTemperature temp025Below(0b11111111, 0b11000000); // -0.25 
      ComparePrintlnPassFail(temp025Below, -0.25f);
 
      RtcTemperature tempZero(0b00000000, 0b00000000); // 0.0 
      ComparePrintlnPassFail(tempZero, -0.0f);
 
      RtcTemperature temp025Above(0b00000000, 0b01000000); // 0.25 
      ComparePrintlnPassFail(temp025Above, 0.25f);
 
      RtcTemperature temp050Above(0b00000000, 0b10000000); // 0.5 
      ComparePrintlnPassFail(temp050Above, 0.5f);
 
      RtcTemperature temp075Above(0b00000000, 0b11000000); // 0.75 
      ComparePrintlnPassFail(temp075Above, 0.75f);
 
      RtcTemperature temp25Above(0b00011001, 0b00000000); // 25.0
      ComparePrintlnPassFail(temp25Above, 25.0f);
 
      RtcTemperature temp25Below(0b11100111, 0b00000000); // -25.0
      ComparePrintlnPassFail(temp25Below, -25.0f);
    }
    Serial.println();
 
    // SameType
    {
      Serial.print("same type ");
      RtcTemperature temp25Below(0b11100111, 0b00000000); // -25.0
      RtcTemperature test = temp25Below;
      ComparePrintlnPassFail(test, -25.0f);
    }
 
    // CentiDegrees
    {
      Serial.print("centi degrees ");
      RtcTemperature temp025Below(-25); // -0.25
      ComparePrintlnPassFail(temp025Below, -0.25f);
 
      Serial.print("centi degrees ");
      RtcTemperature temp025Above(25); // 0.25
      ComparePrintlnPassFail(temp025Above, 0.25f);
 
      Serial.print("centi degrees ");
      RtcTemperature temp25Below(-2500); // -25.0
      ComparePrintlnPassFail(temp25Below, -25.0f);
 
      Serial.print("centi degrees ");
      RtcTemperature temp25Above(2500); // 25.0
      ComparePrintlnPassFail(temp25Above, 25.0f);
    }
 
    Serial.println();
}
 
void PrintlnExpected(RtcTemperature& temp, uint16_t digits)
{
  Serial.print(" = ");
  Serial.print(temp.AsFloatDegC(), digits);
  Serial.println();
}
 
void PrintTests()
{
  Serial.println("Prints:");
 
  RtcTemperature temp25Above(2500);
  temp25Above.Print(Serial);
  PrintlnExpected(temp25Above, 2);
 
  RtcTemperature temp25Below(-2500);
  temp25Below.Print(Serial);
  PrintlnExpected(temp25Below, 2);
 
  RtcTemperature temp025Above(25);
  temp025Above.Print(Serial);
  PrintlnExpected(temp025Above, 2);
  temp025Above.Print(Serial, 1);
  PrintlnExpected(temp025Above, 1);
 
  RtcTemperature temp025Below(-25);
  temp025Below.Print(Serial);
  PrintlnExpected(temp025Below, 2);
  temp025Below.Print(Serial, 1);
  PrintlnExpected(temp025Below, 1);
 
  RtcTemperature temp050Above(50);
  temp050Above.Print(Serial);
  PrintlnExpected(temp050Above, 2);
  temp050Above.Print(Serial, 0);
  PrintlnExpected(temp050Above, 0);
 
  RtcTemperature temp050Below(-50);
  temp050Below.Print(Serial);
  PrintlnExpected(temp050Below, 2);
  temp050Below.Print(Serial, 0);
  PrintlnExpected(temp050Below, 0);
  temp050Below.Print(Serial, 2, ',');
  Serial.println(" == -0,50");
 
  Serial.println();
}
 
void MathmaticalOperatorTests()
{
  Serial.println("Mathmaticals:");
 
  RtcTemperature temp050Below(-50);
  RtcTemperature temp050Above(50);
  RtcTemperature temp050Diff(100);
  RtcTemperature temp050Same(-50);
  RtcTemperature tempResult;
 
  Serial.print("equality ");
  PrintPassFail(temp050Below == temp050Same);
  Serial.println();
 
  Serial.print("inequality ");
  PrintPassFail(temp050Below != temp050Above);
  Serial.println();
 
  Serial.print("less than ");
  PrintPassFail(temp050Below < temp050Above);
  Serial.println();
 
  Serial.print("greater than ");
  PrintPassFail(temp050Above > temp050Below);
  Serial.println();
 
  Serial.print("less than ");
  PrintPassFail(temp050Below <= temp050Above);
  Serial.print(" or equal ");
  PrintPassFail(temp050Below <= temp050Same);
  Serial.println();
 
  Serial.print("greater than ");
  PrintPassFail(temp050Above >= temp050Below);
  Serial.print(" or equal ");
  PrintPassFail(temp050Below >= temp050Same);
  Serial.println();
 
  tempResult = temp050Above - temp050Below;
  Serial.print("subtraction ");
  PrintPassFail(tempResult == temp050Diff);
  Serial.println();
 
  tempResult = temp050Above + temp050Above;
  Serial.print("addition ");
  PrintPassFail(tempResult == temp050Diff);
  Serial.println();
 
  Serial.println();
}
 
void setup ()
{
    Serial.begin(115200);
    while (!Serial);
    Serial.println();
 
    ConstructorTests();
    PrintTests();
    MathmaticalOperatorTests();
}
 
void loop ()
{
    delay(500);
}

 

Output

Open the serial monitor window and you will see something like this

Constructors:
-0.75C passed
-0.50C passed
-0.25C passed
0.00C passed
0.25C passed
0.50C passed
0.75C passed
25.00C passed
-25.00C passed

same type -25.00C passed
centi degrees -0.25C passed
centi degrees 0.25C passed
centi degrees -25.00C passed
centi degrees 25.00C passed

Prints:
25.00 = 25.00
-25.00 = -25.00
0.25 = 0.25
0.3 = 0.3
-0.25 = -0.25
-0.3 = -0.3
0.50 = 0.50
1 = 1
-0.50 = -0.50
-1 = -1
-0,50 == -0,50

Mathmaticals:
equality passed
inequality passed
less than passed
greater than passed
less than passed or equal passed
greater than passed or equal passed
subtraction passed
addition passed

Link

https://www.silabs.com/documents/public/data-sheets/Si1145-46-47.pdf

Share

Arduino and PCF8563 RTC example

The PCF8563 is a CMOS Real-Time Clock (RTC) and calendar optimized for low power consumption. A programmable clock output, interrupt output, and voltage-low detector are also provided. All addresses and data are transferred serially via a two-line bidirectional I²C-bus. Maximum bus speed is 400 kbit/s.

This is an easy to use module for this device

Features

  • Provides year, month, day, weekday, hours, minutes, and seconds based on a 32.768 kHz quartz crystal
  • Century flag
  • Clock operating voltage: 1.0 V to 5.5 V at room temperature
  • Low backup current; typical 0.25 μA at VDD = 3.0 V and Tamb = 25 °C
  • 400 kHz two-wire I²C-bus interface (at VDD = 1.8 V to 5.5 V)
  • Programmable clock output for peripheral devices (32.768 kHz, 1.024 kHz, 32 Hz, and 1 Hz)
  • Alarm and timer functions
  • Integrated oscillator capacitor
  • Internal Power-On Reset (POR)
  • I²C-bus slave address: read A3h and write A2h
  • Open-drain interrupt pin

 

This is the schematic for a typical module

pcf8563 schematic

pcf8563 schematic

Here is how to connect the module to your Arduino

Connection

Arduino PinModule Pin
 5v Vcc
GNDGnd
A5SCL
A4SDA

 

Code

You do not need a library but I downloaded the library from https://bitbucket.org/orbitalair/arduino_rtc_pcf8563/downloads

This is one of the basic examples

/* Demonstration of Rtc_Pcf8563 Alarms.
 *
 * The Pcf8563 has an interrupt output, Pin3.
 * Pull Pin3 HIGH with a resistor, I used a 10kohm to 5v.
 * I used a RBBB with Arduino IDE, the pins are mapped a
 * bit differently.  Change for your hw.
 * SCK - A5, SDA - A4, INT - D3/INT1
 *
 * After loading and starting the sketch, use the serial monitor
 * to see the clock output.
 *
 * setup:  see Pcf8563 data sheet.
 *         1x 10Kohm pullup on Pin3 INT
 *         No pullups on Pin5 or Pin6 (I2C internals used)
 *         1x 0.1pf on power
 *         1x 32khz chrystal
 *
 * Joe Robertson, jmr
 * orbitalair@bellsouth.net
 */
#include <Wire.h>
#include <Rtc_Pcf8563.h>
 
/* get a real time clock object */
Rtc_Pcf8563 rtc;
/* a flag for the interrupt */
volatile int alarm_flag=0;
 
/* the interrupt service routine */
void blink()
{
  alarm_flag=1;
}
 
void setup()
{
  pinMode(3, INPUT);           // set pin to input
  digitalWrite(3, HIGH);       // turn on pullup resistors
 
  Serial.begin(9600);
 
  /* setup int on pin 3 of arduino */
  attachInterrupt(1, blink, FALLING);
  /* clear out all the registers */
  rtc.initClock();
  /* set a time to start with.
   * day, weekday, month, century, year */
  rtc.setDate(14, 6, 3, 0, 10);
  /* hr, min, sec */
  rtc.setTime(1, 15, 40);
  /* set an alarm for 20 secs later...
   * alarm pin goes low when match occurs
   * this triggers the interrupt routine
   * min, hr, day, weekday
   * 99 = no alarm value to be set
   */
  rtc.setAlarm(16, 99, 99, 99);
}
 
void loop()
{
  /* each sec update the display */
  Serial.print(rtc.formatTime());
  Serial.print("  ");
  Serial.print(rtc.formatDate());
  Serial.print("  0x");
  Serial.print(rtc.getStatus2(), HEX);
  Serial.print("\r\n");
  delay(1000);
  if (alarm_flag==1){
    clr_alarm();
  }
 
}
 
void clr_alarm()
{
  detachInterrupt(1);
  Serial.print("blink!\r\n");
 
  rtc.clearAlarm();
  delay(1000);
  alarm_flag=0;
  attachInterrupt(1, blink, FALLING);
}

 

Links
PCF8563 RTC Board PCF8563T CMOS Real-time Clock/Calendar Development Module

Share

Arduino and DS3231 RTC example

The DS3231 is a low-cost, extremely accurate I2C real-time clock (RTC) with an integrated temperature-compensated crystal oscillator (TCXO) and crystal.
The device incorporates a battery input, and maintains accurate timekeeping when main power to the device is interrupted.

ds3231

ds3231

Features

Highly Accurate RTC Completely Manages All Timekeeping Functions
Real-Time Clock Counts Seconds, Minutes, Hours, Date of the Month, Month, Day of the Week, and Year, with Leap-Year Compensation Valid Up to 2100
Accuracy ±2ppm from 0°C to +40°C
Accuracy ±3.5ppm from -40°C to +85°C
Digital Temp Sensor Output: ±3°C Accuracy
Two Time-of-Day Alarms
Programmable Square-Wave Output Signal
Simple Serial Interface Connects to Most Microcontrollers
Fast (400kHz) I2C Interface
Battery-Backup Input for Continuous Timekeeping
Low Power Operation Extends Battery-Backup Run Time
3.3V Operation

 

 

Here is a schematic for a typical module

DS3231 schematic

DS3231 schematic

 

Connection

 Arduino PinsModule Pins 
 GND GND
5v VCC
A4 SDA
A5 SCL

 

Code

This uses the RTCLib – https://github.com/adafruit/RTClib

#include <Wire.h>
#include "RTClib.h"
 
RTC_DS3231 rtc;
 
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
 
void setup () {
 
#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif
 
  Serial.begin(9600);
 
  delay(3000); // wait for console opening
 
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
 
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}
 
void loop () {
    DateTime now = rtc.now();
 
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
 
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
 
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));
 
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
 
    Serial.println();
    delay(3000);
}

Links
DS3231 AT24C32 IIC Module Precision Clock Module

Share

Arduino Data logger shield RTC example

This is a simple data logging shield which will enable you to add SDCard storage support and RTC capability to your Arduino project. Here is a picture of the shield that I purchased

data logging shield

data logging shield

Features

Here is a summary of the features of the shield

SD card interface works with FAT16 or FAT32 formatted cards. 3.3v level shifter circuitry prevents damage to your SD card
Real time clock (RTC) keeps the time going even when the Arduino is unplugged. The battery backup lasts for years
Included libraries and example code for both SD and RTC mean you can get going quickly Prototyping area for soldering connectors, circuitry or sensors.
Onboard 3.3v regulator is both a reliable reference voltage and also reliably runs SD cards that require a lot of power to run
Works with Arduino UNO, Duemilanove, Diecimila, Leonardo or ADK/Mega R3 or higher. ADK/Mega R2 or lower are not supported
To start, remove the battery from the holder while the Arduino is not powered or plugged into USB. Wait 3 seconds and then replace the battery. This will reset the RTC chip.
Code

You will need to include the RTCLib, this example gets the latest time from your computer and then displays it via the serial monitor

#include <Wire.h>
#include "RTClib.h"
 
RTC_DS1307 RTC;
 
void setup ()
{
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();
 
  if (! RTC.isrunning())
  {
    Serial.println("RTC is NOT running!");
    //sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
 
}
 
void loop ()
{
    DateTime now = RTC.now();
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    delay(1000);
}

Result

This is a brief outline of the output as seen in the serial monitor

2015/11/22 21:38:20
2015/11/22 21:38:21
2015/11/22 21:38:22
2015/11/22 21:38:23
2015/11/22 21:38:24

 

Link
Data Logger Module Logging Data Recorder Shield for Arduino UNO SD Card

Share