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.
Thanks
- JohnBeardmore
- Posts: 211
- Joined: Thu Nov 15, 2012 11:03 pm
- Location: Derbyshire UK.
- Contact: Website
Re: Accessing DS3231 Temperature
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/.
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).
See: http://t4sustainability.co.uk/oBeMS/
Automatic Meter Reading (AMR), Building Management System (BMS),
Building Energy Management System (BEMS), Infrastructure Control System (ICS).
See: http://t4sustainability.co.uk/oBeMS/
Re: Accessing DS3231 Temperature
Hello,
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:
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:
Cheers
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
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)
Re: Accessing DS3231 Temperature
I got this error
Traceback (most recent call last):
File "t3231.py", line 10, in <module>
print getTemp(address)
File "t3231.py", 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.
Traceback (most recent call last):
File "t3231.py", line 10, in <module>
print getTemp(address)
File "t3231.py", 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.
-
- Posts: 2
- Joined: Mon Jun 08, 2015 10:55 pm
Re: Accessing DS3231 Temperature
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
Dennis
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
Dennis
Re: Accessing DS3231 Temperature
Hi,
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: http://www.perlmonks.org/?node_id=1118676
I also have a script to read the temperature: readI2cTempt.pl
If you can live with perl, here it is: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:
HiPi::Utils
HiPi::BCM2835::I2C
4. You will need to make the script executable and call it as root
Regards
anita2R
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: http://www.perlmonks.org/?node_id=1118676
I also have a script to read the temperature: readI2cTempt.pl
If you can live with perl, here it is:
Code: Select all
#!/usr/bin/perl
#
# readI2cTempt.pl
# 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) {
$sign="-";
} else {
$sign="+";
}
#
# 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;
$int++;
# 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;
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:
HiPi::Utils
HiPi::BCM2835::I2C
4. You will need to make the script executable and call it as root
Regards
anita2R
Re: Accessing DS3231 Temperature
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
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
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')
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

Re: Accessing DS3231 Temperature
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 working...so 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


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???

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
john31415
Alabama
john31415
Alabama
Re: Accessing DS3231 Temperature
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?
Also, why does it specify DS1307 when the device being accessed is DS3231?
Re: Accessing DS3231 Temperature
Why invent the wheel?
cat /sys/devices/platform/soc/3f804000.i2c/i2c-1/1-0068/hwmon/hwmon0/temp1_input
cat /sys/devices/platform/soc/3f804000.i2c/i2c-1/1-0068/hwmon/hwmon0/temp1_input
Re: Accessing DS3231 Temperature
or also, with Pi3B and jessie:
echo $(cat /sys/bus/i2c/devices/1-0068/hwmon/hwmon0/temp1_input|awk '{print $0/1000 " °C"}')
echo $(cat /sys/bus/i2c/devices/1-0068/hwmon/hwmon0/temp1_input|awk '{print $0/1000 " °C"}')
Re: Accessing DS3231 Temperature
Thank you Zili & vintozver!
Both those work great!
Both those work great!

-
- Posts: 216
- Joined: Tue May 01, 2012 8:47 am
- Location: Germany (old europe)
Re: Accessing DS3231 Temperature
on my rpi4:
works with hwmon1 not hwmon0:
Code: Select all
uname -a
Linux pump 4.19.93-v7l+ #1290 SMP Fri Jan 10 16:45:11 GMT 2020 armv7l GNU/Linux
Code: Select all
echo $(cat /sys/bus/i2c/devices/1-0068/hwmon/hwmon1/temp1_input|awk '{print $0/1000 " °C"}')
24.25 °C