[SOLVED] Calibrating the PCF8523 RTC

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
jpj
Posts: 60
Joined: Sat Dec 10, 2016 3:07 pm

[SOLVED] Calibrating the PCF8523 RTC

Post by jpj » Sun Dec 25, 2016 3:26 pm

I've been reading about RTC crystal drift and calibration. I've also received some good information on the Adafruit forum in this thread:
https://forums.adafruit.com/viewtopic.php?f=57&t=108693

I don't have a truly accurate measurement of drift in ppm as discussed in this thread:
http://forum.micropython.org/viewtopic.php?f=6&t=326

After setting the PCF8523 in my Adalogger by calling an ntp server on my LAN, then comparing the rtc and ntp times after three days running time, my rtc is gaining approximately 2.3 seconds per 24 hour period.

If I understand correctly, 2.3 seconds * 11.6 ppm (from Adafruit thread linked to above) means I should calibrate my rtc by writing -26.68 to it's calibration register to slow it down and reduce the gain. So how to write -26.68 into the calibration register? Is it possible with micropython on the esp8266?

Section 8.8 (page 28) of the PCF8523 datasheet has information about the Register Offset for accuracy tuning:
http://www.nxp.com/documents/data_sheet/PCF8523.pdf

I'd like to better understand the datasheet and know how to write into the correct register but that is outside my knowledge and experience level. I tried some Google searches for a tutorial on the subject but didn't find anything. Some assistance or guidance would be greatly appreciated.

I have some C code in an Arduino sketch that someone wrote to calibrate an MCP79412. If it would be easier for me to connect the Adalogger to an Arduino and write to the register, I might be able to re-use that code, provided I can determine the proper byte to write to for the PCF8523.

Thanks for any suggestions, help, or guidance.
J
Last edited by jpj on Tue Dec 27, 2016 1:04 pm, edited 2 times in total.

jpj
Posts: 60
Joined: Sat Dec 10, 2016 3:07 pm

Re: Calibrating the PCF8523 RTC

Post by jpj » Sun Dec 25, 2016 11:02 pm

Update: I need to write positive ppm to slow the rtc down, not negative (-26.68) as I posted previously. The PCF8523 register address is 0x0E, but what bits to actually write into it for my calibration I haven't determined. I don't understand the tables and mode starting on age 28 of the datasheet.
Last edited by jpj on Mon Dec 26, 2016 1:47 pm, edited 1 time in total.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Calibrating the PCF8523 RTC

Post by pythoncoder » Mon Dec 26, 2016 8:05 am

If you look at the calibration workflow on page 31 of the manual you'll see that you need to write 26.62/4.34 = 6 if you're in mode 0 (low power) or 26.62/4.069 = 7 if you're in mode 1 (their example corresponds to your case where the clock is gaining time). If you're not sure what mode you're in I'd write 6 as the precise result for mode 1 is 6.542 so it's marginal whether 6 or 7 is the optimal value.

The device uses an I2C interface so MicroPython will be able to write to the register. I suggest you read the docs on I2C http://docs.micropython.org/en/latest/e ... e.I2C.html. You'll need to find the pin numbers used to connect the processor to the PCF8523. I'd start by issuing a scan:

Code: Select all

from machine import Pin, I2C
sda = Pin(id, Pin.OPEN_DRAIN) # replace id with the data pin
scl = Pin(id, Pin.OPEN_DRAIN) # Likewise for the clock pin
i2c = I2C(sda, scl)
i2c.scan()
you should see the device on address 0x68 (page 46 of the manual). I2C uses 7 bit addressing with the LSB being read/write.

If my reading of the manual is correct the following code fragment should work:

Code: Select all

from machine import Pin, I2C
sda = Pin(id, Pin.OPEN_DRAIN) # replace id with the data pin
scl = Pin(id, Pin.OPEN_DRAIN) # Likewise for the clock pin
i2c = I2C(sda, scl)
buf = bytearray((6,)) # Your correction value
i2c.writeto_mem(0x68, 0x0e, buf) 
Peter Hinch
Index to my micropython libraries.

jpj
Posts: 60
Joined: Sat Dec 10, 2016 3:07 pm

Re: Calibrating the PCF8523 RTC

Post by jpj » Mon Dec 26, 2016 1:40 pm

Thank you pythoncoder! This was the guidance I needed.

I wrote the calibration to the rtc, reset the time from a call to ntp, and will now monitor for accuracy. My REPL session below, with some white space added to enhance readability.

I need to study the PCF8523 datasheet until it makes sense. I also didn't know about the i2c.writeto_mem() function. I had briefly read about bytearray() but need to review that too. You're filling in the blanks for me is greatly appreciated!

For other beginners who may be reading this, the i2c scan returned two addresses, 104 (0x68) is my rtc and 112 (0x70) is a display I have connected.

Code: Select all

>>> from machine import I2C, Pin
>>> i2c = I2C(scl=Pin(5), sda=Pin(4))
>>> i2c.scan()
[104, 112]

>>> buf = bytearray((6,))
>>> buf
bytearray(b'\x06')
>>> i2c.writeto_mem(0x68, 0x0e, buf)

>>> import mytime
>>> mytime.setrtc()

>>> import comparetime
>>> comparetime.runv()
NTP 2016-12-26 13:19:58
RTC 2016-12-26 13:19:58

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Calibrating the PCF8523 RTC

Post by deshipu » Mon Dec 26, 2016 7:01 pm

If you are using the uRTC library, you can also wite that value to the register with this code:

Code: Select all

rtc._register(0x0e, '\x06')
Where rtc is your PCF8523 object.

jpj
Posts: 60
Joined: Sat Dec 10, 2016 3:07 pm

Re: Calibrating the PCF8523 RTC

Post by jpj » Mon Dec 26, 2016 7:06 pm

deshipu wrote:If you are using the uRTC library, you can also wite that value to the register with this code:

Code: Select all

rtc._register(0x0e, '\x06')
Where rtc is your PCF8523 object.
I am using uRTC (thanks to your recent help in a different thread).

Thanks, I'll check it out!

Post Reply