terça-feira, abril 21, 2020

Relógio de Tempo Real: DS3231

O próximo na lista de RTCs é o DS3231, que eu tenho em um módulo para o Raspberry Pi (mas que pode ser usado com um Arduino).


O datasheet do DS3231 está aqui. Novamente é um RTC que usa I2C para a comunicação, suportando até 400KHz. O endereço é 0x68, que é o mesmo do DS1307 (mas atenção que não são compatíveis).

Ao contrário dos demais RTCs que estamos vendo, o DS3231 possui um cristal internal, o que lhe garante uma maior precisão.

O DS3231 suporta bateria externa. Tanto a alimentação principal como a bateria aceitam tensões de 2.3 a 5,5 (os valores típicos são 3,3V de alimentação principal e 3,0V de bateria). Não há suporte interno à carga de bateria.

Como de costume, os acessos ao RTC são iniciados pela escrita de um endereço, seguida da leitura ou escrita do dado propriamente dito.  Posições consecutivas podem ser acessadas sem enviar o endereço para cada uma até que seja enviada a condição de stop.

O DS3231 não possui Ram, mas dispõe de 2 alarmes. Ele possui também um sensor de temperatura, para compensar variações do oscilador, que pode ser lido.


Como de costume nos RTCs, os valores são armazenados em BCD. Os registradores 0x00 a 0x06 contém a data e hora. Os registradores 0x07 a 0x0D contém a programação do alarme (note que não incluem mês e ano e o alarme 2 não tem segundos). Os registradores 0x0E e 0x0F são para controle e status. O registrador 0x10 permite uma ajuste fino na frequência para compensar variações do cristal com o tempo (normalmente não é necessário). Por último, os registradores 0x11 e 0x12 fornecem uma leitura de temperatura.

Os alarmes são sinalizados no registros de status e, opcionalmente, por um sinal de interrupção. Infelizmente este sinal não está disponível no módulo que eu tenho. Os bits mais significativos dos registradores de programação dos alarmes permitem definir a condição de acionamento do alarme:


No Gerenciador de Bibliotecas da IDE do Arduino eu encontrei nada menos que uma dezena de bibliotecas com suporte ado DS3231:


No Raspberry Pi, o Raspbian possui suporte ao DS3231, o site da Adafruit tem instruções de como configurá-lo para isto.



O programa Python abaixo exercita de forma simples o módulo DS3231 ligado a um Raspberry, fazendo um dump em hexa dos primeros 7 registradores e mostrando a data e hora decodificadas. Para acertar a data e hora, fornecer na linha de comando dia, mes, ano, hora, minuto e segundo.
#!/usr/bin/env python

from time import sleep
import smbus
import sys

bus = smbus.SMBus(1)
DEVICE_ADDRESS = 0x68

def bcd(val):
    d1 = val % 10
    d2 = (val - d1) / 10
    return (d2 << 4) + d1

def dcb(val):
    d2 = val >> 4
    d1 = val & 0xF
    return str(d2*10 + d1)

if len(sys.argv) == 7:
    dia = int(sys.argv[1])
    mes = int(sys.argv[2])
    ano = int(sys.argv[3])
    hora = int(sys.argv[4])
    minuto = int(sys.argv[5])
    segundo = int(sys.argv[6])
    dh = [ bcd(segundo), bcd(minuto), bcd(hora), 1, bcd(dia), bcd(mes), bcd(ano) ]
    bus.write_i2c_block_data(DEVICE_ADDRESS, 0, dh)

dh = bus.read_i2c_block_data (DEVICE_ADDRESS, 0, 7);
x = "Regs: "
for val in dh:
    x = x + hex(val) + " "
print (x)

print(dcb(dh[4])+"/"+dcb(dh[5])+"/"+dcb(dh[6])+" "+dcb(dh[2])+":"+dcb(dh[1])+":"+dcb(dh[0]))

Nenhum comentário: