Sabia que os aquários devem ter uma iluminação apropriada para que as plantas sobrevivam?
Vários fatores influenciam na sobrevivência das plantas e dos peixes dentro de um aquário. Por isso, todos devem ter bombas, um sistema de filtro, para remover resíduos químicos que são letais para os peixinhos,uma série de decorações diferentes e outros animais como esponjas, moluscos e corais. Além disso tudo, habitantes do aquário precisam de um sistema de iluminação adequado. Nesta aula, vamos ver como, a partir de um relógio, controlar LEDs de forma mais confortável para nossos peixinhos.
Então, as plantas precisam de 10 a 12 horas de exposição, diária, a luz. Mas não é qualquer luz que elas gostam. Também é importante que a luz fornecida as plantas seja mais pro vermelho e azul. O truque aqui é simular dentro do aquário, da melhor forma possível, o que acontece na natureza. Tudo isso pode ser feito manualmente, ou seja, liga-se as lampadas por algumas horas e depois você vai ter que lembar de desligar. No entanto, a melhor forma de fazer isso é automatizando esse processo. Assim, pode-se controlar por quanto tempo as luzes vão ficar ligadas e ajustar o brilho para que não fique tanto tempo na intensidade máxima.
Até agora, vimos como mexer com LEDs, display de sete segmentos e usamos, pela primeira vez, um sensor para sentir a temperatura dos ambientes. Vamos usar um componente usado para mostrar as horas, data e dia da semana, ou seja, vamos criar um relógio digital. Como todo relógio digital, esse módulo também vem com lugar para por bateria. Assim, você pode programar seus robôs para funcionarem na hora que você desejar, comprovar que horas tentaram abrir a porta da sua casa ou regar suas plantas na hora certa.
A figura mostra o que vem escrito no módulo RTC. Nos nossos projetos, vamos usar, como sempre, o VCC e o GND para a alimentação do componente. Além dos pinos responsáveis por alimentar o componente, ou seja, para deixar ele funcionando, os outros pinos servem para transferir as informações do componente para o Arduino de forma sincronizada. Do mesmo modo que o sensor de temperatura e umidade, o pino que transfere dados para o Arduino é o SDA e o pino que sincroniza as informações na tela do usuário é o SCL. Esse pino chama-se, na eletrônica, de “clock”. Quanto maior o “clock” de um componente, mais fácil fica para fazer essa sincronização dos dados. Como o módulo RTC gera muita informações diferentes, ele organiza e sincroniza as informações para que o Arduino nos mostre essas informações. Lembre-se que, para saber mais sobre o componente, consulte o datasheet.
Você vai precisar de:
- Módulo RTC DS3231.
- Protoboard
- Arduino.
Montagem Prática
Nessa montagem, exploraremos todas as funcionalidades do módulo RTC, ou seja, vamos fazer ele mostrar as horas, data e dia da semana. Além disso, como na ultima aula, usaremos o monitor serial do Arduino para nos mostrar esses resultados. Novamente, tanto o Fritzing quanto o tinkercad não tem o módulo RTC DS3231. Por isso, nem tente simular o circuito, use a imagem abaixo como referência para fazer a montagem.
A imagem abaixo ilustra o passo a passo da montagem prática do circuito acima. Na imagem 1 temos os componentes utilizados e, na imagem 2, conectamos os jumpers de alimentação do circuito. Da mesma forma que a montagem da aula passada, ligamos o jumper vermelho no pino 3,3 V e o jumper preto no pino GND do Arduino. Na imagem 3 colocamos um jumper branco na saída de dados, SDA, e na porta A4. Em seguida, conectamos um jumper amarelo no pino de sincronização, SCL, no pino A5.
Com o circuito montado, vamos começar a programação.
#include <Wire.h> #include <DS3231.h> DS3231 rtc; bool Century; bool h12; bool PM; void setup() { Wire.begin(); Serial.begin(9600); // O bloco abaixo define a data e a hora de partida do sensor rtc.setDate(26); rtc.setMonth(10); rtc.setYear(20); rtc.setDoW(5);// Domingo = 1 ... Sábado = 7 rtc.setHour(19); rtc.setMinute(15); rtc.setSecond(50); } void loop() { //O bloco abaixo escreve o horário, a data e a temperatura na tela. Serial.print(rtc.getDate()); Serial.print('-'); Serial.print(rtc.getMonth(Century)); Serial.print('-'); Serial.print("20"); Serial.print(rtc.getYear()); Serial.print(' '); Serial.print(rtc.getHour(h12,PM)); Serial.print(':'); Serial.print(rtc.getMinute()); Serial.print(':'); Serial.println(rtc.getSecond()); Serial.print("Temperatura = "); Serial.println(rtc.getTemperature()); // O bloco abaixo escreve o dia da semana na tela. if(rtc.getDoW()== 1){ Serial.println("Domingo"); } if(rtc.getDoW()== 2){ Serial.println("Segunda"); } if(rtc.getDoW()== 3){ Serial.println("Terça"); } if(rtc.getDoW()== 4){ Serial.println("Quarta"); } if(rtc.getDoW()== 5){ Serial.println("Quinta"); } if(rtc.getDoW()== 6){ Serial.println("Sexta"); } if(rtc.getDoW()== 7){ Serial.println("Sábado"); } }
Nas duas primeiras linhas, temos que incluir duas bibliotecas para que a comunicação entre o sensor e o Arduino seja bem sucedida. Na quarta linha, adicionamos a variável “rtc” do tipo “DS3231”. Esse tipo de variável é especifica do RTC3231 e só vai ser utilizada na presença desse componente. Nas linhas 6, 7 e 8, declaramos 3 variáveis do tipo “bool”. Esse tipo de variável guarda um valor lógico, ou seja, verdadeiro ou falso. Essas variáveis são necessárias para guardar os valores das horas.
No “void setup()”, temos que iniciar a biblioteca “Wire.h” e definir a taxa de transmissão do monitor Serial. Essa ações são realizadas pelo Arduino nas linhas 11 e 12. É necessário, nas linhas seguintes, definir a data e a hora de partida do RTC. Por isso, nas linhas 16 a 22, usamos as funções da biblioteca “DS3231” para definir a data e a hora inicial.
- Linha 16: define o dia como 26.
- Linha 17: define o mês como 10.
- Linha 18: define o ano como 20.
- Linha 19: define o dia da semana como Quinta. Os dias da semana são indexados de 1 a 7. Começando com Domingo e terminando com sábado.
- Linhas 20: define as horas como 19.
- Linha 21: define os minutos como 15.
- Linha 22: define os segundos como 50.
No “void loop()”, vamos escrever todos os dados do RTC no monitor serial. Começamos com a data e temperatura e, ao fim, usamos um novo recurso de programação para mostrar o dia da semana.
- Linha 30: procura, no módulo, o valor corresponde ao dia e imprime.
- Linhas 31: Imprime um traço.
- Linha 32: procura, no módulo, o valor correspondente ao mês e imprime.
- Linhas 33: Imprime um traço.
- Linhas 34: Imprime o valor 20. O módulo retorna um valor de 1 a 99. Por isso, para imprimir “2020” temos que escrever 20 antes do valor vindo do RTC.
- Linha 35: procura, no módulo, o valor correspondente ao ano e imprime.
- Linha 36: imprime um espaço vazio.
- Linha 37: procura, no módulo, o valor corresponde a hora e imprime.
- Linha 38: imprime dois pontos.
- Linha 39: procura, no módulo, o valor corresponde aos minutos e imprime.
- Linha 40: imprime dois pontos.
- Linha 41: procura, no módulo, o valor corresponde aos segundos, imprime e pula para a próxima linha.
- Linha 42 imprime “Temperatura =”.
- Linha 43: procura, no módulo, o valor corresponde a temperatura, imprime e pula para a próxima linha.
Para escrever o dia da semana precisamos pegar o valor armazenado dentro do RTC, verificar qual é esse valor e imprimir na tela o dia da semana equivalente. Para isso, usamos a ferramenta condicional “if” vista em aulas anteriores.
- Linha 47: O condicional “if” verifica se o valor armazenado no RTC é o número 1.
- Linha 48: Se o número armazenado for o 1, imprime na tela “Domingo”.
- Linha 49: O condicional “if” verifica se o valor armazenado no RTC é o número 2.
- Linha 50: Se o número armazenado for o 2, imprime na tela “Segunda”.
Todos os outros “if” do código fazem a mesma coisa, isto é, pesquisam o valor armazenado e imprimem o dia da semana equivalente.
Para saber mais:
Podemos usar outra ferramenta de programação para não escrever tantos “ïf”. Essa ferramenta chama-se “Switch, case” e torna-se útil em situações em que temos apenas uma condição e diferentes resultados. Por isso, ela é ideal no nosso código.
#include <Wire.h> #include <DS3231.h> DS3231 rtc; bool Century; bool h12; bool PM; void setup() { Wire.begin(); Serial.begin(9600); // O bloco abaixo define a data e a hora de partida do sensor rtc.setDate(26); rtc.setMonth(10); rtc.setYear(20); rtc.setDoW(5);// Domingo = 1 ... Sábado = 7 rtc.setHour(19); rtc.setMinute(15); rtc.setSecond(50); } void loop() { //O bloco abaixo escreve o horário, a data e a temperatura na tela. Serial.print(rtc.getDate()); Serial.print('-'); Serial.print(rtc.getMonth(Century)); Serial.print('-'); Serial.print("20"); Serial.print(rtc.getYear()); Serial.print(' '); Serial.print(rtc.getHour(h12,PM)); Serial.print(':'); Serial.print(rtc.getMinute()); Serial.print(':'); Serial.println(rtc.getSecond()); Serial.print("Temperatura = "); Serial.println(rtc.getTemperature()); // O bloco abaixo escreve o dia da semana na tela. switch (rtc.getDoW()){ case 1: Serial.println("Domingo"); break; case 2: Serial.println("Segunda"); break; case 3: Serial.println("Terça"); break; case 4: Serial.println("Quarta"); break; case 5: Serial.println("Quinta"); break; case 6: Serial.println("Sexta"); break; case 7: Serial.println("Domingo"); break; } }
- Linha 47: usamos o “switch” e colocamos dentro dos parênteses dele o valor armazenado do dia da semana.
- Linha 49: verifica se o valor da condição dentro dos parênteses do “Switch” é o número 1.
- Linha 50: Se o valor armazenado no RTC for o número 1, imprime “Domingo”.
- Linha 51: O “break” fecha o “switch” impedindo de checar os outros casos.
Nas linhas seguintes, o código verifica cada valor de 1 a 7 e para quando encontrar o valor armazenado no RTC.
Para saber mais:
Além do “Switch,case”, podemos usar os vetores computacionais para imprimir os dias da semana. Essa ferramenta é utilizada para guardar informações que seriam necessárias várias variáveis para fazer o mesma coisa. No nosso caso, como temos apenas 7 dias da semana e o RTC indexa valores em ordem de 1 a 7, podemos usar essa mesma ferramenta para armazenar o caracteres dos dias da semana e usar o “for” para acessar esses caracteres dentro desses vetores. Os vetores, no Arduino, são indexados em zero, ou seja, a primeira posição é a posição Zero. Dessa forma, quando criamos um vetor de 5 posições, elas vão de Zero a 4. Além disso, mudamos o bloco que escreve a data e o horário. Perceba que não é necessário pular uma linha toda vez que colocamos um ponto e vírgula (;).
#include <Wire.h> #include <DS3231.h> DS3231 rtc; bool Century; bool h12; bool PM; char dias_da_semana [7][8] = {"Domingo","Segunda","Terca", "Quarta", "Quinta", "Sexta", "Sabado"}; void setup() { Wire.begin(); Serial.begin(9600); // O bloco abaixo define a data e a hora de partida do sensor rtc.setDate(26); rtc.setMonth(10); rtc.setYear(20); rtc.setDoW(2);// Domingo = 1 ... Sábado = 7 rtc.setHour(19); rtc.setMinute(15); rtc.setSecond(50); } void loop() { //O bloco abaixo escreve o horário, a data e a temperatura na tela. Serial.print(rtc.getDate()); Serial.print('-'); Serial.print(rtc.getMonth(Century));Serial.print('-');Serial.print("20");Serial.print(rtc.getYear()); Serial.print(' '); Serial.print(rtc.getHour(h12,PM));Serial.print(':');Serial.print(rtc.getMinute());Serial.print(':');Serial.println(rtc.getSecond()); Serial.print("Temperatura = ");Serial.println(rtc.getTemperature()); // O bloco abaixo escreve o dia da semana na tela. for(int i = 1; i <= 7; i++){ Serial.print (dias_da_semana [rtc.getDoW()-1] [i-1]); } Serial.println(); delay(1000); }
- Linha 10: criamos 7 vetores com 8 espaços para caracteres e colocamos os dias da semana nesses vetores. Escolhemos 7 vetores porque temos 7 dias da semana e 8 caracteres porque o dia da semana com mais caracteres é “Domingo”.
- Linha 32: escreve a data.
- Linha 34: escreve as horas e pula uma linha.
- Linha 35: escreve a temperatura e pula uma linha.
- Linha 39: “for” para acessar os caracteres dentro dos vetores. Como os valores armazenados dentro do RTC vão de 1 a 7, a variável “i” começá em 1, termina em 7 e é incrementada de 1 em 1.
- Linha 40: imprime o dia da semana acessando os caracteres dentro dos vetores criados na linha 10. Os colchetes são utilizados para definir qual vetor e qual posição dentro desse vetor vamos acessar. Lembre-se que os vetores no Arduino são indexados em Zero. Assim, o primeiro colchete ( [rtc.getDoW () – 1] ) pega o valor armazenado no RTC e diminui uma unidade. Fazemos isso para acessar o dia da semana correto. O segundo colchete ([i – 1]) acessa os caracteres dentro dos vetores. Temos que diminuir uma unidade, já que os vetores começam em Zero. Perceba que o “for” possibilita a impressão dos dias da semana por caracteres individuais.
- Linha 41: Fecha as chaves do “for”.
- Linha 42: Pula uma linha.
- Linha 43: Espera 1000 milissegundos, isto é, 1 segundo.
Agora que sabemos como trabalhar com o módulo RTC, vamos construir o circuito para nossos peixinhos. Não podemos nos esquecer deles!
Nesta montagem, mantemos as ligações do exemplo anterior e adicionamos dois LEDs, um vermelho e outro Azul. Veja o desenho esquemático abaixo para auxiliar na montagem do circuito.
A imagem abaixo mostra como devemos montar esse circuito. A única mudança em relação primeiro circuito é a adição de mais dois passos. Assim, no mesmo circuito do exemplo anterior, adicione os dois resistores de 470 Ω e dois LEDs, um azul e outro vermelho, conforme mostrado no passo 4. A imagem 5 mostra o circuito em funcionamento após fazer o upload da programação adiante.
Para ligar e desligar os LEDs, vamos adicionar no código a configuração inicial dos LEDs e as condições para ligar esses LEDs. Recomenda-se que as luzes do aquário estejam ligadas por 8 horas, ou seja, queremos que os LEDs liguem e permaneçam ligados por 8 horas. Para isso, definimos que os LEDs liguem as 7 da manhã e desliguem as 15 da tarde.
#include <Wire.h> #include <DS3231.h> DS3231 rtc; bool Century; bool h12; bool PM; char dias_da_semana [7][8] = {"Domingo","Segunda","Terca", "Quarta", "Quinta", "Sexta", "Sabado"}; void setup() { Wire.begin(); Serial.begin(9600); // O bloco abaixo define a data e a hora de partida do sensor rtc.setDate(26); rtc.setMonth(10); rtc.setYear(20); rtc.setDoW(2);// Domingo = 1 ... Sábado = 7 rtc.setHour(6); rtc.setMinute(59); rtc.setSecond(45); // O bloco abaixo configura os LEDs pinMode (2,OUTPUT); pinMode (4,OUTPUT); } void loop() { //O bloco abaixo escreve o horário, a data e a temperatura na tela. Serial.print(rtc.getDate()); Serial.print('-'); Serial.print(rtc.getMonth(Century));Serial.print('-');Serial.print("20");Serial.print(rtc.getYear()); Serial.print(' '); Serial.print(rtc.getHour(h12,PM));Serial.print(':');Serial.print(rtc.getMinute());Serial.print(':');Serial.println(rtc.getSecond()); Serial.print("Temperatura = ");Serial.println(rtc.getTemperature()); // O bloco abaixo escreve o dia da semana na tela. for(int i = 1; i <= 7; i++){ Serial.print (dias_da_semana [rtc.getDoW()-1] [i-1]); } Serial.println(); delay(1000); if((rtc.getHour(h12,PM) == 7)&& ((rtc.getMinute() == 0))){ digitalWrite(2,HIGH); digitalWrite(4,HIGH); } if((rtc.getHour(h12,PM) == 15)&& ((rtc.getMinute() == 0))){ digitalWrite(2,LOW); digitalWrite(4,LOW); } }
- Linhas 28 e 29: definem os pinos 2 e 4 como saída para os LEDs.
- Linha 51: “if” que verifica se os valores, armazenados no RTC, correspondentes as horas é são os números 7 e Zero.
- Linhas 52 e 53: liga os LEDs nos pinos 2 e 4.
- Linha 56: “if” que verifica se os valores, armazenados no RTC, correspondentes as horas é são os números 15 e Zero.
- Linhas 57 e 58: desliga os LEDs nos pinos 2 e 4.
Dessa forma, os LEDs ligarão as 7 da manha e desligarão as 15 da tarde.