Posts: 2
Joined: Sat Nov 02, 2013 3:51 am

Accessing DS3231 Temperature

Sat Nov 02, 2013 3:58 am

I've been successful in finding and using information on the DS1307 RTC, DS3231 RTC, DS18B20 Temp Sensor and DHT11 Temp Sensor.

However, I cannot find any Raspberry Pi (found for Arduino) information on accessing the Temperature from a DS3231 RTC chip/module. If you can point me in the right direction I would appreciate it.

I'd also like to access the alarms, eeprom, etc but that is less important than the temperature.


User avatar
Posts: 211
Joined: Thu Nov 15, 2012 11:03 pm
Location: Derbyshire UK.

Re: Accessing DS3231 Temperature

Mon Nov 11, 2013 10:06 pm

Did you have any joy ?

I'd like to be able to access a DS18B20 using a spare GPIO pin as I have some Pis in boxes which crashed quite a lot last summer, and I'd like to find out if the problem was temperature related.

Ideally it would be good if the approach is WiringPi compatible, as I'm using a bunch of GPIO pins via WP for other things.

Cheers, J/.
Author of oBeMS open source Building energy Management System.
Automatic Meter Reading (AMR), Building Management System (BMS),
Building Energy Management System (BEMS), Infrastructure Control System (ICS).

Posts: 1
Joined: Sun Dec 15, 2013 2:17 pm

Re: Accessing DS3231 Temperature

Sun Dec 15, 2013 2:40 pm

To obtain the temperature, you have to read the DS3231 registers at address 0x11 and 0x12 (see page 11 of the dadasheet). To do so, you can use the i2cget command:

Code: Select all

sudo i2cget 1 0x68 0x11
sudo i2cget 1 0x68 0x12
You then have to convert the values to temperature. From the datasheet, the 0x11 byte contains the integer part of the temperature. The fractional part of the temperature is contained in the last two bits at 0x12. Today, on my system, the registers contains 0x17 and 0x80 at addresses 0x11 and 0x12. Hexadecimal 0x17 is decimal 23 and 0x80 is binary 10000000. So the temperature around my pi is 23 + 1*2^-1 + 0*2^-2 = 23.5°C.

This python script does all the readings and conversion:

Code: Select all

import smbus

bus = smbus.SMBus(1)
address = 0x68

def getTemp(address):
	byte_tmsb = bus.read_byte_data(address,0x11)
	byte_tlsb = bin(bus.read_byte_data(address,0x12))[2:].zfill(8)
	return byte_tmsb+int(byte_tlsb[0])*2**(-1)+int(byte_tlsb[1])*2**(-2)

print getTemp(address)

User avatar
Posts: 53
Joined: Tue Dec 24, 2013 3:16 pm
Location: IIT Guwahati, India

Re: Accessing DS3231 Temperature

Sun Dec 07, 2014 7:54 pm

I got this error

Traceback (most recent call last):
File "", line 10, in <module>
print getTemp(address)
File "", line 7, in getTemp
byte_tmsb = bus.read_byte_data(address,0x11)
IOError: [Errno 16] Device or resource busy

Any idea what I need more.
Chemist by profession. Electronics hobbyist and Photographer since 80s.

Posts: 2
Joined: Mon Jun 08, 2015 10:55 pm

Re: Accessing DS3231 Temperature

Mon Jun 08, 2015 11:01 pm

Try writing: lsmod
and if you find rtc_ds1307 in the output write: sudo rmmod rtc_ds1307
You'll find i2cget and the python script works great.. to eneble the mod again write : sudo modprobe rtc_ds1307

Then the sudo hwclock will work... I reccon then module(driver) rtd_ds1307 hogs the driver...

Kind regards

Posts: 226
Joined: Sun Dec 23, 2012 6:55 pm
Location: Ottawa, Canada

Re: Accessing DS3231 Temperature

Tue Jun 09, 2015 6:27 pm


I already posted a link to my code for accessing the EEPROM on these real time clock boards on this post: viewtopic.php?p=759676#p759676
The link is:
I also have a script to read the temperature:
If you can live with perl, here it is:

Code: Select all

# Version 1.00
# 19 February 2015
# Version 1.01
# 05 March 2015
# Improved commenting
# A script to read the temperature from a DS3231 real-time clock (RTC) board
#  attached to i2c bus #1 at address 0x68 (change as required)
#  and output a formatted temperature result
# The temperature is +/- 0.25 C
# The script must be called as root, but lowers permissions once
#  the i2c object has been created
use HiPi::Utils;
use HiPi::BCM2835::I2C qw( :all );
use strict;
# setup regular user & group id's for lowering permissions
my $user = '<yourusername>';
my $group = '<yourgroupname>';
# setup bus number and RTC address on i2c bus
my $i2cBus = BB_I2C_PERI_1;
my $i2cAddr = 0x68;
# create i2c device object
my $objI2c = HiPi::BCM2835::I2C->new(
    peripheral => $i2cBus,
    address    => $i2cAddr
HiPi::Utils::drop_permissions_name( $user, $group );
$objI2c->set_baudrate( $i2cBus, BB_I2C_CLOCK_400_KHZ );
# read 2 bytes at register locations 0x11 & 0x12 
(my $Msb, my $Lsb) = $objI2c->i2c_read_register_rs( 0x11, 2 );
# $Msb contains integer in 2's complement format
# determine sign from most significant bit, 1= neg, 0=pos
my $sign;
if ($Msb & 0b10000000) {
        } else {
# either use value as is (+ve) or do a 2's complement (-ve)
my $int;
if ($sign eq "+"){
        $int = $Msb;
        } else {
        # 2's complement
        $int = ~$Msb;
        # mask off all but lowest 7 bits
        $int = $int & 0b1111111;
# fractional part is in most significant 2 bits of $Lsb
my $frac = $Lsb >> 6;
# accuracy to 0.25C
$frac = $frac * 0.25;
# combine integer and fraction
my $res = $int + $frac;
# add sign if negative
if ($sign eq "-") {
        $res = $sign . $res;
# print formatted temperature result
printf "%.02fºC\n", $res;
exit 0;
1. Put your username and group in the appropriate place in the script (about line 25) - names go inside single quotes
2. Change the bus/address for your RTC if required (just below the username and group lines)
3. You will need to install two perl modules:
4. You will need to make the script executable and call it as root



Posts: 3
Joined: Tue Apr 19, 2016 6:56 am

Re: Accessing DS3231 Temperature

Tue Apr 19, 2016 7:31 am

Thanks liparis, your python code works, however I needed to modify it slightly,
only 2 changes,
call os.system to remove the rtc chip
read the temperature
and call os.system re-enable the rtc chip

Code: Select all

import smbus
import os

bus = smbus.SMBus(1)
address = 0x68

os.system('sudo rmmod rtc_ds1307')
def getTemp(address):
   byte_tmsb = bus.read_byte_data(address,0x11)
   byte_tlsb = bin(bus.read_byte_data(address,0x12))[2:].zfill(8)
   return byte_tmsb+int(byte_tlsb[0])*2**(-1)+int(byte_tlsb[1])*2**(-2)

#print getTemp(address)
Celsius = getTemp(address)
Fahrenheit = 9.0/5.0 * Celsius + 32
print Fahrenheit, "*F /", Celsius, "*C"
os.system('sudo modprobe rtc_ds1307')

It outputs as "86.45 *F / 30.25 *C"
I placed this in a .py script that gets called in a .sh script :)
the sh script is called from other programs so kept the original, I have it when it sends status emails, ddns update, and ncid phone call.
I tried to use a DHT11 sensor but it was too slow, and caused a delay/lag in programs. The original ds18b20 sensor stopped working when I installed the RTC :(

User avatar
Posts: 1
Joined: Sat Sep 17, 2016 4:34 pm
Location: Alabama

Re: Accessing DS3231 Temperature

Sat Sep 17, 2016 5:12 pm

This was very helpful to me. I eventually want to be able to access the AT24C32's EEPROM (maybe to store temperature vs time data? :-) I had one heck of a time as a new RPi3 user getting (1) the Rpi3 to even use the Real Time Clock and then (2) to access the DS3231's nice temperature data. And to use Python3 with I2C. But my fragile house of cards of processes, modules, scripts, permissions, parameters, users, versions, and revisions is far. :-).

Your script enabled me to get my first reading of the temperature from the ds3231 in meaningful units. By stopping the rtc_ds1307 module at the terminal (that this is needed seems to be a bug) I could read the ds3231 0x11 and 0x12 registers where the temperature data resides, but I sincerely had no desire to dig into LSB and MSB and 2's complements etc, to figure out the temperature. Your Python script does the job - thank you! Note to Python3 users like me, the only change needed is to put the Print command argument in parentheses. And make sure you have the Python3 I2C stuff installed.

If I was greedy I might ask if you have a comparable script to access the EEPROM??? :-). There is also supposed to be a 32khz square wave on the pin next to the EEPROM's - can the frequency be adjusted using Python? I have a little DS138 oscilloscope for which that would make a nice test signal. All in all it is crazy what a little $4 circuit can do.

Thanks to all but especially liparis and sgarcia05 for your helpful Python scripts. -- John
Last edited by john31415 on Mon Apr 10, 2017 4:24 pm, edited 1 time in total.
"If you can't explain it simply, you don't understand it well enough." -- Albert Einstein

Posts: 15
Joined: Fri Mar 10, 2017 3:27 am

Re: Accessing DS3231 Temperature

Mon Apr 10, 2017 4:22 pm

liparis' script starts out with smbus but I'm using i2c. I tried it anyway and it worked. Are they the same thing or just compatible/overlapping?

Also, why does it specify DS1307 when the device being accessed is DS3231?

Posts: 40
Joined: Thu Jun 01, 2017 2:16 am
Location: Bellevue, WA, USA

Re: Accessing DS3231 Temperature

Fri Jul 07, 2017 6:02 am

Why invent the wheel?

cat /sys/devices/platform/soc/3f804000.i2c/i2c-1/1-0068/hwmon/hwmon0/temp1_input

User avatar
Posts: 7
Joined: Wed Jan 13, 2016 2:48 pm

Re: Accessing DS3231 Temperature

Mon Feb 19, 2018 7:47 pm

or also, with Pi3B and jessie:

echo $(cat /sys/bus/i2c/devices/1-0068/hwmon/hwmon0/temp1_input|awk '{print $0/1000 " °C"}')

Posts: 20
Joined: Thu Apr 14, 2016 12:38 pm

Re: Accessing DS3231 Temperature

Fri Sep 21, 2018 4:58 am

Thank you Zili & vintozver!
Both those work great! :D

Posts: 244
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: Accessing DS3231 Temperature

Sat Feb 01, 2020 4:27 pm

on my rpi4:

Code: Select all

uname -a
Linux pump 4.19.93-v7l+ #1290 SMP Fri Jan 10 16:45:11 GMT 2020 armv7l GNU/Linux
works with hwmon1 not hwmon0:

Code: Select all

echo $(cat /sys/bus/i2c/devices/1-0068/hwmon/hwmon1/temp1_input|awk '{print $0/1000 " °C"}')
24.25 °C

Return to “Automation, sensing and robotics”