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

name Link
Arduino Uno UNO R3 CH340G/ATmega328P, compatible for Arduino UNO
DS3231 RTC
connecting wire Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire

 

Connection

 Arduino Pins Module 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

Leave a Reply