MCP7940 – RTC with Pi

As I’m building my own IQ house control system, I need to have RTC in my system. So started playing with MCP7940N and i2c interface. I’m using Raspberry Pi for my experiments with i2c/SPI.

Construction is pretty simple, just use MCP7840N Datasheet.

mcp7940n-schema

 

Then you can start checking with Pi. In my case, I’m using RevB, so my bus has number 1 and RTC got 0x6f address.

root@pi:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 6f
70: -- -- -- -- -- -- -- --

what next? Check address 0x00, if the onboard oscilator is running

root@pi:~# i2cget -y 1 0x6f 0x00 b
0x00

0x00 means NO, it’s NOT running. So, turn it on

root@pi:~# i2cset -y1 1 0x6f 0x00 0x80

and check few times address 0x00

root@pi:~# i2cget -y 1 0x6f 0x00 b
0x87
root@pi:~# i2cget -y 1 0x6f 0x00 b
0x88
root@pi:~# i2cget -y 1 0x6f 0x00 b
0x89
root@pi:~# i2cget -y 1 0x6f 0x00 b
0x90
root@pi:~# i2cget -y 1 0x6f 0x00 b
0x91

Increments! Great. That means – our oscilator is working = our clock is working too. Next step is to set current time and date. But wait. How are values stored and read/written? RTC uses BCD encoding for values, that means, eg. number 94 is stored as 9 and 4, both in 4 bits = 9 is stored as 1001 and 4 as 0100, in hexadecimal 0x94. Easy? Eg. day is using 6 bits, upper two for 0123 values, bottom bits for 0-9, so 31th will be stored as 0x31. For more details please read the PDF – RTCC Memory map. So back to setting the date & time:

# 2nd Feb 2014
root@pi:~# i2cset -y 1 0x6f 0x06 0x14
root@pi:~# i2cset -y 1 0x6f 0x05 0x02
root@pi:~# i2cset -y 1 0x6f 0x04 0x19
# 00:02:00
root@pi:~# i2cset -y 1 0x6f 0x02 0x00
root@pi:~# i2cset -y 1 0x6f 0x01 0x02
root@pi:~# i2cset -y 1 0x6f 0x01 0x80

Fine. But if we’re setting ’00’ as seconds – address 0x00 – why value 0x80? 7th bit = ST – onboard oscilator enabled.

I’ve written simple Python code to read from RTC and print out the value:

from time import sleep
import smbus
import time
import signal
import sys

bus = smbus.SMBus(1)
RTC_ADDR = 0x6f

ADDR_SEC = 0x00
ADDR_MIN = 0x01
ADDR_HOUR = 0x02

def signal_handler(signal, frame):
  sys.exit(0)

def bcd2bin(x):
  return (((x) & 0x0f) + ((x) >> 4) * 10)

if __name__ == "__main__":
  signal.signal(signal.SIGINT, signal_handler)
  while True:
    sec = bcd2bin(bus.read_byte_data(RTC_ADDR, ADDR_SEC) & 0x7f)
    min = bcd2bin(bus.read_byte_data(RTC_ADDR, ADDR_MIN) & 0x7f)
    hour = bcd2bin(bus.read_byte_data(RTC_ADDR, ADDR_HOUR) & 0x3f)
    print "%02d:%02d:%02d" % (hour, min, sec)
    sleep(0.9) # nearly 1 sec

Just run by

root@pi:~# python rtc.py
00:35:41
00:35:42
00:35:43
00:35:44
00:35:45
00:35:46

Voila! :) RTC is up and running. I’d like to check tomorrow (resp. today) morning, if everything is still working correctly, and can create next module for my IQ house control system :)

6 thoughts on “MCP7940 – RTC with Pi

  1. Hello Tom,

    I bought the same RTC module for my raspberry pi but I cannot get it to work. I hope you can give me a hint. I run the setup script from the piface github repository (tried both master and dev_tp branches) and /dev/i2c-1 is created. But:

    # i2cdetect -y 1 //shows all “–”
    # i2cget -y 1 0x6f 0x00 b // Error: read failed (or read failed for i2cset)

    It seems like there is no connection at all with the RTC. Am I missing something?

    Thank you very much for your time.

  2. Thanks for the quick reply.

    # i2cdetect -y 0
    Error: Could not open file ‘/dev/i2c-0’ or ‘/dev/i2c/0’: No such file or directory

    The setup script creates /dev/i2c-1, but there is no communication using i2c tools. Did you use some setup besides the official script? Any other configuration/module?

  3. I did:

    # apt-get install i2c-tools
    # modprobe i2c-bcm2708
    # modprobe i2c-dev
    # i2cdetect -y 0
    # i2cdetect -y 1
    

    if it’s working, then update your /etc/modules file and add these two lines into it:

    i2c-bcm2708
    i2c-dev
    

    which RasPi revision do you have?

  4. I have a model B.

    I will try a clean installation and your steps and let you know what happens.

  5. I think I found the error. i2c-tools install was throwing an erro at the end:

    /run/udev or .udevdb or .udev presence implies active udev. Aborting MAKEDEV invocation.

    I don’t know what this means, but it seems to be the source of my problems. Wierd, it is a clean raspbian installation.

    Anyway, thank you, I appreciate your help. Congratulations on your blog :)

Leave a Reply

Your email address will not be published. Required fields are marked *

4 × 6 =