The Raspberry Pi doesn’t have an RTC chip on it but with an expansion board you can add this
A popular chip is the DS3231 , lets have a quick look at this chip
DS3231 Information
I used a Pioneer600 board which has one of these chips on it among other features
Parts
The Pioneer600 costs around $39 for many useful features
Name | Link |
Raspberry Pi 4 | Aliexpress product link |
Raspberry Pi Expansion Board Pioneer600 | Aliexpress product link |
DS3231 Examples
C example using the BCM library
#include <bcm2835.h>
#include <stdio.h>
#include <unistd.h>
//regaddr,seconds,minutes,hours,weekdays,days,months,yeas
char buf[]={0x00,0x00,0x22,0x06,0x27,0x12,0x19};
char *str[] ={"SUN","Mon","Tues","Wed","Thur","Fri","Sat"};
void pcf8563SetTime()
{
bcm2835_i2c_write(buf,8);
}
void pcf8563ReadTime()
{
buf[0] = 0x00;
bcm2835_i2c_write_read_rs(buf ,1, buf,7);
}
int main(int argc, char **argv)
{
if (!bcm2835_init())return 1;
bcm2835_i2c_begin();
bcm2835_i2c_setSlaveAddress(0x68);
bcm2835_i2c_set_baudrate(10000);
printf("DS3231 Test Program ...\n\n");
pcf8563SetTime();
while(1)
{
pcf8563ReadTime();
buf[0] = buf[0]&0x7F; //sec
buf[1] = buf[1]&0x7F; //min
buf[2] = buf[2]&0x3F; //hour
buf[3] = buf[3]&0x07; //week
buf[4] = buf[4]&0x3F; //day
buf[5] = buf[5]&0x1F; //mouth
//year/month/day
printf("20%02x/%02x/%02x ",buf[6],buf[5],buf[4]);
//hour:minute/second
printf("%02x:%02x:%02x ",buf[2],buf[1],buf[0]);
//weekday
printf("%s\n",str[(unsigned char)buf[3]]);
bcm2835_delay(1000);
}
bcm2835_i2c_end();
bcm2835_close();
return 0;
}
Save the file as “ds3231.c”. Compile and run with:
gcc -Wall ds3231.c -o ds3231-lbcm2835 sudo ./ds3231
Python example
#!/usr/bin/python
# -*- coding: utf-8 -*-
import smbus
import time
address = 0x68
register = 0x00
#sec min hour week day mout year
NowTime = [0x00,0x00,0x22,0x06,0x27,0x12,0x19]
w = ["SUN","Mon","Tues","Wed","Thur","Fri","Sat"];
#/dev/i2c-1
bus = smbus.SMBus(1)
def ds3231SetTime():
bus.write_i2c_block_data(address,register,NowTime)
def ds3231ReadTime():
return bus.read_i2c_block_data(address,register,7);
ds3231SetTime()
while 1:
t = ds3231ReadTime()
t[0] = t[0]&0x7F #sec
t[1] = t[1]&0x7F #min
t[2] = t[2]&0x3F #hour
t[3] = t[3]&0x07 #week
t[4] = t[4]&0x3F #day
t[5] = t[5]&0x1F #mouth
print("20%x/%02x/%02x %02x:%02x:%02x %s" %(t[6],t[5],t[4],t[2],t[1],t[0],w[t[3]-1]))
time.sleep(1)
Save the file as “ds3231.py” and execute it with:
sudo python ds3231.py
C example using WiringPi
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <stdio.h>
#define DS3231_Address 0x68
//seconds,minutes,hours,weekdays,days,months,yeas
char buf[]={0x00,0x00,0x22,0x06,0x27,0x12,0x19};
char *str[] ={"SUN","Mon","Tues","Wed","Thur","Fri","Sat"};
int fd,i;
void pcf8563SetTime()
{
for(i = 0;i < 7;i++)
{
wiringPiI2CWriteReg8(fd,i,buf[i]);
}
}
void pcf8563ReadTime()
{
for(i = 0;i < 7;i++)
{
buf[i] = (char)wiringPiI2CReadReg8(fd,i);
}
}
int main(int argc, char **argv)
{
if(wiringPiSetup() < 0)return 1;
fd = wiringPiI2CSetup(DS3231_Address);
printf("DS3231 Test Program ...\n\n");
pcf8563SetTime();
while(1)
{
pcf8563ReadTime();
buf[0] = buf[0]&0x7F; //sec
buf[1] = buf[1]&0x7F; //min
buf[2] = buf[2]&0x3F; //hour
buf[3] = buf[3]&0x07; //week
buf[4] = buf[4]&0x3F; //day
buf[5] = buf[5]&0x1F; //mouth
//year/month/day
printf("20%02x/%02x/%02x ",buf[6],buf[5],buf[4]);
//hour:minute/second
printf("%02x:%02x:%02x ",buf[2],buf[1],buf[0]);
//weekday
printf("%s\n",str[(unsigned char)buf[3]]);
delay(1000);
}
return 0;
}
Save the file as “ds3231.c”. Compile and run with:
gcc -Wall ds3231.c -o ds3231-lbcm2835 -lwiringPi sudo ./ds3231