segunda-feira, 6 de outubro de 2014

Ligando o Raspberry Pi no horário desejado com o RTC DS3231

RTC DS3231

Um RTC( Real Time Clock ) é um relógio em forma de circuito integrado. É utilizado para manter o horário de sistemas, mesmo quando desligados. Os RTCs geralmente funcionam em conjunto de uma pequena bateria, que com um consumo extremamente baixo, podem durar alguns anos sem trocá-la.

Os diversos modelos de RTC diferem no consumo, tipo de comunicação, precisão e recursos adicionais.

O Raspberry Pi não contém um RTC na placa, o horário é sincronizado via internet. Em projetos em que uma conexão com a internet não é uma opção, um RTC pode se tornar necessário dependendo da aplicação.

Um bom recurso de alguns RTCs é a função alarme. No caso do RTC DS3231,  são dois alarmes com diversas configurações.


Utilizando as funções básicas do RTC DS3231


A versão do módulo que comprei, foi feita especialmente para o Raspberry Pi, se encaixa facilmente nos pinos e é ideal para quem quer facilidade.

O RTC DS3231 utiliza comunicação I2C, é um rtc preciso e utiliza um TCXO( Temperature-compensated crystal oscillator ). A tensão de funcionamento é de 3.3v à 5.5v. A bateria desse módulo é soldada.

Para utilização das funções básicas será necessário carregar o módulo para I2C e um driver feito para diversas variantes desse RTC. Como root execute:

# modprobe i2c-bcm2708
# modprobe rtc-ds1307

Crie um novo device I2C.

# echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device

Caso esteja no Raspberry Pi revisão ,1 troque i2c-1 por i2c-0.

Ao executar o comando hwclock, será retornado a data e hora atual no RTC.

# hwclock
Mon 06 Oct 2014 16:26:15 UTC  -0.943644 seconds


Quando executado pela primeira vez, o horário provavelmente estará errado. Para alterar existem duas opções, alterar manualmente:

# hwclock --set --date="2014-10-06 13:30:00"

Ou alterar de acordo com a data retornada pelo sistema:

# hwclock -w

Para fazer o inverso, ajustar o horário do sistema de acordo com o RTC, execute:

# hwclock -s


Utilizando a função alarme para ligar o Raspberry Pi


Um dos problemas desse módulo específico para Raspberry Pi, é que ele não tem o pino de alarme mapeado na placa. Foi preciso soldar um fio no pino do chip para a utilização desse recurso.

O pino que precisaremos utilizar é o INT/SQW.

Imagem do datasheet ds3231
Imagem do datasheet

Esse pino tem 2 opções de utilização, a saída de um onda quadrada ou a interrupção gerada pelo alarme quando ativo.

Descrito como "Active-Low Interrupt" em seu datasheet, quando ativo, o pino se torna LOW ao invés de HIGH. É necessário o uso de um resistor pull-up para manter a tensão elevada( HIGH ). Internamente o circuito utilizado é chamado de open-drain( ou open collector ). Após o transistor ser ativado( passar a conduzir ) pelo integrado, a tensão que antes era elevada pelo pull-up irá cair consideravelmente, se tornando nosso LOW.

Imagem do datasheet ds3231
Imagem do datasheet

Com esse pino podemos idenficar externamente quando o alarme é ativado, ainda que essa saída seja opcional, é possível verificar o alarme também por software( o que no nosso caso não serviria, pois o Raspberry Pi vai estar desligado ).

Fio soldado no pino 3
Fio soldado no pino 3

Primeiramente será necessário programar o alarme via software. Ligue o RTC normalmente no Raspberry Pi( mesmo que já tenha soldado o fio ).

Conexão RTC DS3231
Conexão RTC DS3231

Na parte de software utilizaremos a wiringPi para comunicação I2C.

Baixe a lib utilizando o GIT:

$ git clone git://git.drogon.net/wiringPi

Caso não tenha o git instalado:  

$ sudo apt-get install git-core

Entre no diretório da wiringPi e rode como root ou sudo:

$ ./build

Esse comando irá compilar e instalar automaticamente a biblioteca.

Baixe o nosso código com:

$ git clone https://github.com/everpi/rtc_ds3231_alarm.git

Carregue o driver I2C e compile o código.

$ gpio load i2c 
$ gcc ds3231.c -lwiringPi -o ds3231


Ao executar, o valor referente ao alarme será atualizado nos registradores do ds3231.

$ ./ds3231 2120
Hour:21 Min:20


Os argumentos do programa são em formato hora/minuto. Ao executar o exemplo acima, o alarme será ativado exatamente as 21 horas e 20 minutos de qualquer dia. Uma flag pode ser colocada para definir somente para minutos, exemplo:

$ ./ds3231 2120M
Hour:21 Min:20


Nesse último exemplo, o alarme será ativado todas as vezes em que o relógio marcar no minuto 20, independente da hora. Apesar do programa que fiz não suportar, é possível programar dias, dias da semana, meses e anos.

Após definir o horário, retire o RTC da placa e ligue da seguinte forma utilizando um resistor de 680 Ohm:

Esquema básico do alarme
Esquema básico do alarme

Quem leu o post "Botão para iniciar o Raspberry Pi quando desligado" deve lembrar que o pino utilizado como trigger( ao provocar um curto com gnd ) para ligar a placa é o GPIO3, exatamente um dos pinos utilizados pelo I2C. Esse pino contém um resistor pull-up que mantém a tensão elevada( HIGH ).

Imagem do datasheet, GPIO
Imagem do datasheet, GPIO

Utilizaremos o próprio pino de trigger como referência HIGH para o pino INT do RTC. Quando o alarme for ativado, o open-drain do pino abrirá, a tensão irá cair ( LOW ) e o Raspberry Pi ligará.

Apesar da solução acima funcionar, há um problema. Quando o alarme é ativado, ele não se desliga sozinho, é necessário realizar o reset via software e para isso é necessário o I2C.

É possível ligar o fio do alarme e utilizar o I2C em conjunto, substituindo o resistor por 470 Ohm, mas somente quando o alarme está desligado. Quando ligado, o I2C para de funcionar. Para quem necessita usar o alarme diversas vezes isso é um problema, mas que pode ser resolvido.

A solução que dei pro meu caso, foi a utilização de um transistor PNP para cortar corrente que flui entre gpio3 e o fio do alarme.

Será necessário o seguinte:

- Transistor PNP S9012
- Resistors de 2.2k, 100 Ohm e 470 Ohm

O problema de utilizar outros transistors é que os resistors que utilizei são dimensionados especificamente para esse transistor. Caso vá utilizar outro PNP provavelmente será necessário ajustar os valores, além de ser necessário que o PNP comece a conduzir em tensões baixas.

Esquema completo do alarme
Esquema completo do alarme


O corte é feito utilizando o GPIO17( fio azul ), colocando-o em output e estado HIGH.

$ echo 17 > /sys/class/gpio/export
$ echo out > /sys/class/gpio/gpio17/direction
$ echo 1 > /sys/class/gpio/gpio17/value

Após o RTC ligar o Raspberry Pi, o fio verde referente ao SCL estará em LOW devido ao alarme. Todas as vezes que o sistema iniciar será necessário executar os comandos acima para retornar o I2C ao normal, só então será possível programar novamente o alarme.

Referência:
http://www.raspberrypi.org/wp-content/uploads/2012/10/Raspberry-Pi-R2.0-Schematics-Issue2.2_027.pdf
https://learn.adafruit.com/adding-a-real-time-clock-to-raspberry-pi/set-rtc-time
http://datasheets.maximintegrated.com/en/ds/DS3231.pdf

7 comentários:

  1. Onde posso comprar esse modulo no brasil?

    ResponderExcluir
    Respostas
    1. Olá esse modulo específico eu não encontrei à venda no brasil, no mercado livre você encontra módulos diferentes mas com o mesmo chip.

      Excluir
  2. Talvez no ML. Comprei no eBay por aproximadamente 7 reais

    ResponderExcluir
  3. EverPI, vi que no exemplo acima você utiliza a biblioteca wiringPI, você já fez algum exemplo utilizando essa biblioteca para leitura de um keypad matrix 4x4 via GPIO ?

    ResponderExcluir
    Respostas
    1. Ainda não possuo um keypad, qual seria o modelo?

      Excluir
  4. Olá, já comprei o modulo e instalei, até funcionou, mas deixei ele fora da tomada por uma hora e acabou perdendo a hora, será que fiz algo errado ?

    ResponderExcluir
    Respostas
    1. Olá, geralmente quando isso acontece é problema na bateria.

      Excluir