Awesome
MicroPython TinyRTC I2C module
MicroPython driver for the TinyRTC I2C module, featuring a DS1307 RTC and AT24C32N EEPROM.
Pins
Pins are available on both sides. You can use either. One side exposes more pins.
Pin | Name | Description |
---|---|---|
BAT | Battery Voltage | For monitoring battery voltage |
GND | Ground | Ground |
VCC | Input Supply | +5V power for module and to charge coin cell battery |
SDA | I2C Data | I2C data for DS1307 and EEPROM |
SCL | I2C Clock | I2C clock for DS1307 and EEPROM |
DS | DS18B20 | Optional temperature sensor 1-wire data |
SQ | Square Wave | Optional square wave or logic level output |
DS1307 RTC Examples
# VCC-GND STM32F407VET6 on SPI3
>>> from machine import I2C, Pin
>>> i2c = I2C(3) # SCL=A8, SDA=C9
>>> i2c.scan()
[80, 104]
# 80 == 0x50 == AT24C32N EEPROM
# 104 == 0x68 == DS1307
>>> import ds1307
>>> ds = ds1307.DS1307(i2c)
ds.datetime()
ds.datetime(now)
# initial datetime value, oscillator disabled
>>> ds.datetime()
(2000, 1, 1, 0, 0, 0, 0, 0)
# read datetime after 1 second (no change)
>>> ds.datetime()
(2000, 1, 1, 0, 0, 0, 0, 0)
# enable oscillator
>>> ds.halt(False)
# read datetime after 1 second
>>> ds.datetime()
(2000, 1, 1, 0, 0, 0, 1, 0)
# read datetime after 1 more second
>>> ds.datetime()
(2000, 1, 1, 0, 0, 0, 2, 0)
# read datetime after 1 more second
>>> ds.datetime()
(2000, 1, 1, 0, 0, 0, 3, 0)
# set the datetime 24th March 2018 at 1:45:21 PM
>>> now = (2018, 3, 24, 6, 13, 45, 21, 0)
>>> ds.datetime(now)
# read datetime after 1 second
>>> ds.datetime()
(2018, 3, 24, 6, 13, 45, 22, 0)
# read datetime after 1 second
>>> ds.datetime()
(2018, 3, 24, 6, 13, 45, 23, 0)
# disable oscillator
>>> ds.halt(True)
# read datetime after 1 second
>>> ds.datetime()
(2018, 3, 24, 6, 13, 45, 24, 0)
# read datetime after 1 second (no change)
>>> ds.datetime()
(2018, 3, 24, 6, 13, 45, 24, 0)
# minute increment (00:00:59 -> 00:01:00)
>>> ds.datetime((2018, 3, 24, 6, 0, 0, 58, 0))
>>> ds.datetime()
(2018, 3, 24, 6, 0, 0, 59, 0)
>>> ds.datetime()
(2018, 3, 24, 6, 0, 1, 0, 0)
# hour increment (00:59:59 -> 01:00:00)
>>> ds.datetime((2018, 3, 24, 6, 0, 59, 58, 0))
>>> ds.datetime()
(2018, 3, 24, 6, 0, 59, 59, 0)
>>> ds.datetime()
(2018, 3, 24, 6, 1, 0, 0, 0)
# day + weekday increment (23:59:59 Sat -> 00:00:00 Sun)
>>> ds.datetime((2018, 3, 24, 6, 23, 59, 58, 0))
>>> ds.datetime()
(2018, 3, 24, 6, 23, 59, 59, 0)
>>> ds.datetime()
(2018, 3, 25, 0, 0, 0, 0, 0)
# month increment (Wed 28th Feb 2018 -> Thu 1st Mar 2018)
>>> ds.datetime((2018, 2, 28, 3, 23, 59, 58, 0))
>>> ds.datetime()
(2018, 2, 28, 3, 23, 59, 59, 0)
>>> ds.datetime()
(2018, 3, 1, 4, 0, 0, 0, 0)
# month increment on leap year Feb has 29 days (Sun 28th Feb 2016 -> Mon 29th Feb 2016)
>>> ds.datetime((2016, 2, 28, 0, 23, 59, 58, 0))
>>> ds.datetime()
(2016, 2, 28, 0, 23, 59, 59, 0)
>>> ds.datetime()
(2016, 2, 29, 1, 0, 0, 0, 0)
# month increment on leap year (Mon 29th Feb 2016 -> Tue 1st Mar 2016)
>>> ds.datetime((2016, 2, 29, 1, 23, 59, 58, 0))
>>> ds.datetime()
(2016, 2, 29, 1, 23, 59, 59, 0)
>>> ds.datetime()
(2016, 3, 1, 2, 0, 0, 0, 0)
# year increment (31st Dec 2018 -> 1st Jan 2019)
>>> ds.datetime((2018, 12, 31, 1, 23, 59, 58, 0))
>>> ds.datetime()
(2018, 12, 31, 1, 23, 59, 59, 0)
>>> ds.datetime()
(2019, 1, 1, 2, 0, 0, 0, 0)
# square wave output on pin SQ - 1Hz
>>> ds.square_wave(1, 0)
# square wave output on pin SQ - 4.096kHz
>>> ds.square_wave(4, 0)
# square wave output on pin SQ - 8.192kHz
>>> ds.square_wave(8, 0)
# square wave output on pin SQ - 32.768kHz
>>> ds.square_wave(32, 0)
# logic level output on pin SQ - high
>>> ds.square_wave(0, 1)
# logic level output on pin SQ - low
>>> ds.square_wave(0, 0)
DS18B20 1-Wire Temperature Sensor Examples
>>> from machine import Pin
>>> import onewire
>>> ow = onewire.OneWire(Pin('A9'))
>>> ow.scan()
[bytearray(b'(\xc9E\x01\x00\x00\x80/')]
>>> import time, ds18x20
>>> ds = ds18x20.DS18X20(ow)
>>> roms = ds.scan()
>>> ds.convert_temp()
>>> time.sleep_ms(750)
>>> for rom in roms:
... print(ds.read_temp(rom))
23.8125
AT24C32N EEPROM Examples
>>> from machine import I2C, Pin
>>> i2c = I2C(3) # SCL=A8, SDA=C9
>>> i2c.scan()
[80, 104]
>>> import at24c32n
>>> eeprom = at24c32n.AT24C32N(i2c)
# read 32 bytes starting from memory address 0
>>> eeprom.read(0, 32)
b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
# write hello world to memory address 0
>>> eeprom.write(0, 'hello world')
# read back the hello world
>>> eeprom.read(0, 32)
b'hello world\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
>>> eeprom.read(0, 11)
b'hello world'
# write multiple pages (32 bytes per page)
>>> eeprom.write(0, b'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')
# read multiple pages (32 bytes per page)
>>> eeprom.read(0,64)
b'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\xff\xff'
# mutliple page writes (fill pages 0 and 1 with test data)
# write is performed in two steps, "0" x 32 in the first page, then "1" x 32 in the next page
# memory address was at the start of a page boundary so each write is a full 32 byte page write
>>> eeprom.write(0, b'0000000000000000000000000000000011111111111111111111111111111111')
>>> eeprom.read(0,64)
b'0000000000000000000000000000000011111111111111111111111111111111'
# partial page writes
# write some bytes spanning two pages, not starting at a page boundary
# write is performed in two steps, "abc" in the first page then "def" in the next page
>>> eeprom.write(29, b'abcdef')
>>> eeprom.read(0,64)
b'00000000000000000000000000000abcdef11111111111111111111111111111'
# fill entire eeprom with 0xFF
>>> buf = b'\xff' * 32
>>> for i in range(128):
... eeprom.write(i*32, buf)
# show page boundaries
>>> for i in range(128):
... eeprom.write(i*32, '|-Page-{:-<24}|'.format(i))
>>> eeprom.read(0,128)
b'|-Page-0-----------------------||-Page-1-----------------------||-Page-2-----------------------||-Page-3-----------------------|'
# read entire eeprom
>>> eeprom.read(0,4096)
PyBoard / STM32F4 built-in RTC
You do not need this module if you are using a PyBoard or STM32 microcontroller with built in RTC hardware.
Simply add a coin cell battery between GND + VBAT and use pyb.RTC.
On the early pyboards, VBAT is the backup battery for the RTC. On the newer boards, VBAT is for powering the pyboard using a battery and the RTC battery is called Vbackup.
- Dave Hylands on the micropython forum
# on the PyBoard or a STM32F407
rtc = pyb.RTC()
# set time
rtc.datetime((2018, 3, 24, 6, 13, 45, 21, 0))
# attach battery between GND + VBAT
# disconnect, reconnect
# get time
print(rtc.datetime())
Troubleshooting
If you are using the ESP32 loboris port, swap the addrsize=16
for a adrlen=2
.
Parts
- TinyRTC I2C module $0.53 AUD
- LIR2032 rechargeable coin cell $1.19 AUD
Connections
STM32F407VET6 | TinyRTC I2C module |
---|---|
A9 (any pin) | DS |
A8 (I2C3 SCL) | SCL |
C9 (I2C3 SDA) | SDA |
3V3 | VCC |
GND | GND |
Links
License
Licensed under the MIT License.