Um relé é um interruptor eletromecânico composto por uma bobina e um conjunto de contatos. Ao ser energizado, uma corrente percorre a bobina fazendo com que os seus contatos abram ou fechem.
O módulo apresentado aqui é um dispositivo com quatro canais independentes e é ativado com nível lógico baixo. Uma grande vantagem deste módulo é que cada canal utiliza um acoplador ótico, garantindo que não exista nenhum contato elétrico entre o pino da placa Arduino com o circuito de acionamento do relé.
Quando o pino de entrada do canal (IN1 a IN4) vai ao nível lógico baixo (LOW) , o acoplador ótico (U1 a U4) conduz e aciona o transistor (Q1 a Q4) que por sua vez energiza a bobina do relé (K1 a K4) fechando os contatos 2 e 3. Parece confuso com muitos elementos 😀 , porém veja o esquema a seguir.
Teste do módulo
Monte o circuito abaixo observando os pinos de ligação.
pino módulo Relé
pino Arduino
IN1
D7
IN2
D8
IN3
D9
IN4
D10
VCC
5V
GND
GND
Aqui vamos criar dois arquivos: o rele.ino que é o código principal e o Rele.h (atente para o primeiro caractere maiúsculo) com a declaração das macros (#define) e a função de tratamento do módulo. A separação, na prática, não é necessária. Estamos sugerindo a separação para que o código seja o mais reutilizável possível. Deste modo você poderá utilizar um mesmo módulo em diversos projetos e ser poupado de escrever tudo novamente 😎 .
Obs.: toda diretiva de pré-processamento começa com o símbolo #. As diretivas não são comandos da linguagem C ou Arduino. São instruções que antes da compilação efetiva, são tratadas (processadas) no código fonte (sketch) e posteriormente entregues ao compilador. Ah, a sintaxe também difere dos comandos/declarações C/Arduino. Não temos o ponto e virgula (;) ao termino de uma diretiva. Por convenção, o nome das constantes da diretiva #define são escritas em maiúsculas.
Copie e cole no IDE do Arduino e salve como rele.ino
Os LCDs (Liquid-Crystal Display) são módulos simples de serem conectados aos microcontroladores, sendo assim muito úteis em projetos que necessitam de uma comunicação com o usuário. Os LCDs mais comuns possuem 16 colunas por 2 linhas, normalmente indicados por 16×2 ou 1602 e podem possuir 14 ou 16 pinos, sem e com backlight (luz de fundo) respectivamente e são equipados com um controlador compatível com o chip HD44780 da Hitachi. E é exatamente este modelo que vamos ver a seguir.
Disposição das Linhas e Colunas
Tomando como exemplo um display de 16×2, a disposição dos caracteres estão numa matriz com as colunas numeradas de 0 a 15 e linhas numeradas 0 e 1.
Pinos
A numeração e descrição dos pinos:
Pino
Descrição
1
VSS
GND (terra)
2
VDD
+5V
3
VO
Ajuste do contraste – utilizar com um resistor fixo ou variável (potenciômetro ou trimpot)
4
RS
Register Select – sinaliza a instrução ou caractere que está sendo escrito (linha de controle)
5
R/W
Read/Write – sinaliza ao microcontrolador do LCD se a operação é de escrita ou gravação (linha de controle)
6
Enable
Ativação do LCD – se nível baixo, ignora RS e R/W (linha de controle)
7
D0
Linha de dado
8
D1
Linha de dado
9
D2
Linha de dado
10
D3
Linha de dado
11
D4
Linha de dado
12
D5
Linha de dado
13
D6
Linha de dado
14
D7
Linha de dado
15
LED +
backlight (anodo) +5V
16
LED –
backlight (catodo) GND
Nos LCDs sem backlight não temos os pinos 15 e 16.
Módulo I2C para LCD
Uma outra opção, bem mais interessante, é a utilizar um módulo I2C acoplado ao display LCD, como o da figura a seguir.
Este módulo conta com um trimpot para ajuste do contraste e um jumper para ligar/desligar o LED de luz de fundo (backlight). Porém, podemos ligar e desligar este LED por software.
I2C
I2C (IIC – Inter Integrated Circuit) é um barramento de comunicação desenvolvido pela Philips, hoje NXP Semiconductors, para permitir troca de dados entre os componentes que residem na mesma placa de circuito impresso. A vantagem de usar este tipo de barramento é que precisamos de apenas dois pinos para comunicação, além do pino de alimentação (5V) e o pino terra (GND).
Este módulo em específico possui o chip PCF8574.
Vamos usar a biblioteca Wire (nativa no software Arduino) para facilitar o desenvolvimento com o protocolo I2C. Os dois fios de comunicação são conhecidos por SDA (Serial Data Line) e SCL (Serial Clock Line).
Nas placas Arduino Uno e compatíveis, o
SDA é o pino analógico 4 (A4) e o
SCL é o pino analógico 5 (A5).
No Arduino Mega o SDA é o pino digital 20 e o SCL é o pino digital 21.
Os módulos I2C possuem um endereço único para cada módulo. A seleção do endereço é feita pela combinação dos pads A0, A1 e A2. No caso deste módulo, o endereço padrão é 0x27 (os três pads isolados). Para configurar outro endereço, conforme a tabela abaixo, solde (coloque em curto) os pads desejados. Por exemplo: pad sem solda é igual a 0 (zero), pad em curto é igual a 1.
A0
A1
A2
endereço
0
0
0
0x27
1
0
0
0x26
0
1
0
0x25
1
1
0
0x24
0
0
1
0x23
1
0
1
0x22
0
1
1
0x21
1
1
1
0x20
Quer dizer que poderíamos ligar até oito módulos LCD no mesmo Arduino, combinando os pads? Sim, mas lembre-se que existem outros módulos I2C no mercado, como módulos de relógio (RTC) e cada um deverá ter o seu próprio endereço.
Exemplo prático – monitor de temperatura com o LM35.
Vamos mostrar dois exemplos: sem e com o módulo I2C.
Providencie:
1 sensor de temperatura LM35
1 potenciômetro ou trimpot de 1KΩ (caso monte com a opção sem módulo I2C)
1 módulo LCD 16 x 2 *
1 protoboard
e muitos (muitos) fios jumpers.
* é muito mais econômico, caso você não possua um módulo LCD, comprá-lo com o módulo I2C já acoplado (soldado). Se você já possui um ou mais LCDs sem este módulo talvez seja vantajoso comprar o módulo I2C separado, mas terá que soldá-lo ao módulo LCD caso queira uma conexão definitiva entre os módulos.
Conectando o LCD no Arduino – sem módulo I2C
A biblioteca LiquidCrystal (nativa no software Arduino) utiliza apenas as linhas de dados D4 a D7, ou seja, apenas 4 bits. Para controle/ajuste do contraste utilizamos um trimpot ou um potenciômetro de 1KΩ.
O sketch deverá incluir a biblioteca LiquiCrystal através da diretiva #include e para facilitar a manutenção, os pinos associados ao LCD estarão definidos pela diretiva #define.
Obs.: toda diretiva de pré-processamento começa com o símbolo #. As diretivas não são comandos da linguagem C ou Arduino. São instruções que antes da compilação efetiva, são tratadas (processadas) no código fonte (sketch) e posteriormente entregues ao compilador. Ah, a sintaxe também difere dos comandos/declarações C/Arduino. Não temos o ponto e virgula (;) ao termino de uma diretiva. Por convenção, o nome das constantes da diretiva #define são escritas em maiúsculas.
A principal linha do sketch (mais adiante) é
LiquidCrystal lcd( RS, RW, EN, D4, D5, D6, D7 );
onde lcd é a representação da classe LiquidCrystal (pode ser qualquer nome, mas lcd nos parece mais apropriado 😉 ). Também indicamos os pinos de controle e os pinos de dados.
Outro destaque é a função sprintf() da linguagem C (consulte a apostila do mini curso Linguagem C), que formata dados e copia-os para um array de caracteres. Isto facilita muito o trabalho, porém da forma como esta função está implementada no Arduino, não conseguimos manipular dados do tipo float, por isso temperatura foi definido como int.
Métodos usados no exemplo:
begin( num_colunas, num_ linhas )
Inicializa o LCD e especifica o seu tamanho (linhas e colunas). Note que a ordem dos parâmetros são número de colunas por número de linhas.
clear()
“Limpa” o LCD e posiciona o cursor nas coordenadas 0,0.
setCursor( coluna, linha )
Posiciona o cursor nas coordenadas coluna e linha.
print( dados, [base] )
Imprime dados no LCD a partir do posicionamento do cursor. O parâmetro base é opcional e só se aplica quando dados for numérico (consulte a apostila do curso Linguagem Arduino), tópico Serial.print).
print() também retorna o número de bytes impressos no LCD.
Acompanhe o diagrama abaixo para montagem. São muitos fios jumpers e nossa sugestão é começar pelo módulo LCD.
Olhando o LCD de frente, da esquerda para direita, temos:
Primeiro, verifique se você tem instalado a biblioteca LiquidCrystal_I2C. Vá até o gerenciador de bibliotecas (atalho CTRL-SHIFT-i), digite liquidcrystal. Optamos por instalar esta mostrada na figura. Caso não encontre, uma boa fonte é o site Arduino Library List (link no final deste artigo), porém para este módulo faça o download aqui https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c
Oriente-se pela imagem abaixo.
pino I2C
pino Arduino
GND
GND
VCC
5V
SDA
A4
SCL
A5
Note como o circuito fica muito (mas muito) mais simples. Além da economia de pinos Arduino.
No sketch a seguir instanciamos a classe
LiquidCrystal_I2C lcd( 0x27, 16, 2 );
e informamos o endereço do módulo, quantidade de colunas e linhas. Na função setup() iniciamos o módulo e na função loop() mantemos o backlight aceso por 10 segundos e em seguida desligamos o backlight por 20 segundos.
Com o método createChar( ) é possível criar e exibir caracteres personalizados no LCD. Isso é especialmente útil se você deseja exibir um caractere que não faz parte do conjunto de caracteres ASCII padrão.
Em módulos LCDs baseados no controlador HD44780 temos dois tipos de memórias: CGROM e CGRAM (memórias do gerador de caracteres).
O CGROM gera todos os padrões de caracteres de 5 x 8 pontos.
O CGRAM pode gerar até 8 padrões de caracteres definidos pelo usuário (personalizados).
Como sugestão utilize uma folha de papel quadriculado, separe os quadrados em grupos de 8 por 5 e preencha os quadrados que deseja mostrar ou, melhor ainda, acesse este site https://maxpromer.github.io/LCD-Character-Creator/. Você pode escolher se é um LCD com ou sem I2C e ainda gerar os valores em binário ou hexadecimal. Depois é só colar o código 😎 .
Métodos usados no exemplo:
createChar( posiçao, mapa de bits )
armazena na memória CGRAM, na posição de 0 a 7, o mapa de bits do caractere customizado.
write( posição )
exibe no display o caractere customizado na posição de memória de 0 a 7.
Um outro exemplo com os vetores populados com números hexadecimais. Preferimos com números binários, pois praticamente você transcreve o que desenhou para o valor binário.
conteúdo revisto e atualizado – publicado originalmente em 2015
Estes módulos permitem adicionar um relógio em tempo real (RTC – Real Time Clock) aos seus projetos de uma forma bem simples e barata. Mesmo que falte energia ao seu Arduino, o relógio continua a contar pois é alimentado com uma bateria que pode durar muitos e muitos anos!
A maioria dos módulos RTC são equipados com os circuitos integrados DS1307 e DS3231 ambos da empresa californiana Maxim Integrated e utilizam o barramento de comunicação I2C.
I2C
I2C (IIC – Inter Integrated Circuit) é um barramento de comunicação desenvolvido pela Philips, hoje NXP Semiconductors, para permitir troca de dados entre os componentes que residem na mesma placa de circuito impresso. Este barramento também é conhecido por TWI (Two Wire Interface) implementado pela ATMEL, hoje Microchip Technology.
A vantagem de usar este tipo de barramento é que precisamos de apenas dois pinos para comunicação, além do pino de alimentação (5V) e o pino terra (GND).
Os módulos I2C possuem um endereço único para cada módulo. A seleção do endereço é feita pela combinação dos pads A0, A1 e A2, para o DS3231 .
Mas como saber o endereço do módulo se não tenho a documentação disponível? 🙁
A biblioteca Wire.h (necessária para utilizar o I2C), contém um exemplo que faz uma varredura em módulos I2C acoplados a placa Arduino. Esta biblioteca é nativa no software Arduino, ou seja, não é preciso instalar.
Na comunicação I2C temos dois terminais conhecidos por SDA (Serial Data Line) e SCL (Serial Clock Line).
Nas placas Arduino Uno e compatíveis, o
SDA é o pino analógico 4 (A4)
e o
SCL é o pino analógico 5 (A5).
No Arduino Mega o SDA é o pino digital 20 e o SCL é o pino digital 21.
Conectando o módulo DS1307 (Tiny RTC)
Primeiro verifique se você vai usar um módulo com um dos dois chips indicados no começo do artigo. Após, verifique se tem instalado a biblioteca RTClib.h (esta biblioteca serve para os dois modelos).
Monte o circuito orientando-se pela tabela a seguir:
pino Tiny RTC
pino Arduino
GND (jumper preto)
GND
VCC (jumper vermelho)
5V
SDA (jumper amarelo)
A4
SCL (jumper azul)
A5
Agora iremos verificar o endereço do módulo. Carregue o IDE Arduino e acesse: menu File (Arquivo) e navegue até Examples (Exemplos), Wire e i2c_scanner. Execute o sketch e veja qual o endereço retornado no monitor serial.
Você deve ter visto esta informação:
Scanning… I2C device found at address 0x50 ! I2C device found at address 0x68 ! done
Foram exibidos dois endereços. Um é do chip DS1307 (0x68) e o outro da memória EEPROM (0x50). Este sketch é muito útil para identificar outros módulos que usam I2C.
Exemplos
É quase certo que o seu módulo novo está com a data e hora incorretas. Vamos fazer o ajuste e será necessário apenas uma vez, visto que o módulo contém uma bateria para mantê-lo funcionando.
O ajuste será feito utilizando duas macros da linguagem C: __DATE__ e __TIME__, que retornam respectivamente a data e hora do seu sistema operacional. Note que este recurso é válido somente em tempo de compilação do sketch. Não dá para colocar estas macros em um laço de repetição, por exemplo, e exibir valores atualizados. Sempre conterá o valor no momento da compilação.
Aqui temos os métodos:
begin() – retorna false caso não seja detectado um módulo RTC ou o seu endereço é inválido.
adjust() – grava data e hora no seguinte formato ano (AAAA), mês (MM), dia (DD), hora (HH), minuto (MM) e segundo (SS). A classe DateTime formata os valores das macros __DATE__ e __TIME__ corretamente para este método.
now() – retorna data e hora corrente. Novamente usamos a classe DateTime que monta uma estrutura com os seguintes métodos: day(), month(), year(), hour(), minute() e second().
#include <Wire.h>;
#include <RTClib.h>;
RTC_DS1307 rtc;
void setup() {
Serial.begin(9600);
delay(1000);
if (rtc.begin()) {
rtc.adjust(DateTime((__DATE__), (__TIME__)));
DateTime now = rtc.now();
int dia = now.day();
int mes = now.month();
int ano = now.year();
int hora = now.hour();
int minuto = now.minute();
int segundo = now.second();
Serial.print(dia);
Serial.print("/");
Serial.print(mes);
Serial.print("/");
Serial.print(ano);
Serial.print("\t");
Serial.print(hora);
Serial.print(":");
Serial.print(minuto);
Serial.print(":");
Serial.print(segundo);
}
else {
Serial.println("Modulo RTC nao encontrado!");
}
}
void loop() {
}
No próximo exemplo vamos formatar os dados retornados pelo módulo .
Foram inicializados três vetores: um para armazenar o texto formatado, um contendo os dias da semana e o último contendo os meses do ano.
Os dados foram formatados com a função sprintf() da linguagem C. Aliás, temos um mini curso de linguagem C que acreditamos seja útil para um melhor entendimento da linguagem Arduino. Não deixe de fazê-lo 😉
Mais um método utilizado:
dayOfTheWeek() – retorna um inteiro (0 a 6) que representa o dia da semana começando em 0 (domingo).
#include <Wire.h>
#include <RTClib.h>
RTC_DS1307 rtc;
void setup() {
char texto[255];
char diasDaSemana[7][10] = {
"Domingo",
"Segunda",
"Terca",
"Quarta",
"Quinta",
"Sexta",
"Sabado"
};
char mesDoAno[13][10] = {
"",
"Janeiro",
"Fevereiro",
"Marco",
"Abril",
"Maio",
"Junho",
"Julho",
"Agosto",
"Setembro",
"Outubro",
"Novembro",
"Dezembro"
};
Serial.begin(9600);
delay(1000);
if (rtc.begin()) {
DateTime now = rtc.now();
int dia = now.day();
int mes = now.month();
int ano = now.year();
int hora = now.hour();
int minuto = now.minute();
int segundo = now.second();
sprintf(texto, "Hoje: %s, %02d/%02d/%04d Hora: %02d:%02d:%02d",
diasDaSemana[now.dayOfTheWeek()], dia, mes, ano, hora, minuto, segundo);
Serial.println(texto);
sprintf(texto, "Hoje: %s, %02d/%s/%04d Hora: %02d:%02d:%02d",
diasDaSemana[now.dayOfTheWeek()], dia, mesDoAno[mes], ano, hora, minuto, segundo);
Serial.println(texto);
}
else {
Serial.println("Modulo RTC nao encontrado!");
}
}
void loop() {
}
A saída no monitor serial será a data e hora do dia que você executou este sketch:
Sensores de presença ou movimento, conhecidos como sensores IR (infravermelho) ou PIR (Passive Infrared Sensor ou Pyroelectric Infrared Sensor), são sensores que detectam radiação emitida pelo corpo humano, por exemplo.
O elemento sensor é vedado e oferece grande imunidade a umidade e temperatura e sua área exposta deixa passar somente radiação infravermelha. O circuito ao redor dá suporte a leitura do sensor e posterior conversão em um sinal digital. Portanto, na saída deste sensor teremos um nível alto, quando da detecção do movimento e um nível baixo em estado de repouso.
A lente (que cobre o elemento sensor) é do tipo Fresnel, feita de plástico, cuja função é ampliar o ângulo de detecção e concentração dos raios infravermelhos.
Pinos e Ajustes
Não é crítico mas requer um pouco de tempo para ajustar as suas necessidades.
Pinos:
5V = ligar no pino 5V da placa Arduino
sinal = ligar em qualquer pino digital da placa Arduino
GND = ligar no pino GND da placa Arduino
Ajustes:
tempo (trimpot) = no sentido horário, aumenta o delay (tempo que o sinal ficará em nível alto) para aproximadamente 5 minutos e no sentido anti-horário para aproximadamente 5 segundos.
sensibilidade (trimpot) = no sentido horário, aumenta a distância de detecção para aproximadamente 7 metros e no sentido contrário para aproximadamente 3 metros.
trigger (jumper) low – não repetitivo: quando alguém é detectado, um nível alto ficará presente no pino digital até que o tempo se esgote, daí o nível muda para baixo por aproximadamente 3 segundos, não aceitando novas detecções neste período. high – repetitivo: quando em nível alto, ficará neste estado enquanto o sensor detectar alguém no ambiente (dentro do tempo ajustado, porém o tempo será renovado a cada detecção) até que não haja movimento, daí alterando o nível para baixo por aproximadamente 3 segundos, não aceitando novas detecções neste período.
Um pouco confuso, não? 🙂 A melhor forma de entender estes ajustes é fazer experiências com a montagem sugerida mais adiante.
Montagem do circuito
Nos testes/experiências com este sensor, deixamos os trimpots posicionados no sentido máximo anti-horário e o jumper do modo trigger em high. A nossa sugestão é deixar inicialmente desta forma e ir ajustando conforme a sua necessidade. O LED, neste período de ajuste, terá grande importância para nos orientar quando sensor estiver em nível alto. O pino de sinal do PIR está conectado ao pino digital 2 do Arduino e o LED está conectado ao pino 13 digital do Arduino através de um resistor de 220Ω.
Estes sensores da Aosong Electronics Co, combinam um sensor de umidade e um sensor de temperatura no mesmo invólucro. De baixo custo e fácil implementação, o DHT11 é mais barato que o DHT22 que por sua vez é mais preciso, segundo dados do fabricante.
A biblioteca que usamos foi desenvolvida (e é mantida) pela equipe da Adafruit. O download pode ser feito do repositório da Adafruit ou no final deste artigo.
Instalando a biblioteca DHT
Com as versões mais recentes da IDE do Arduino (a partir da 1.6.2), a instalação de bibliotecas de terceiros pode ser feita pelo menu Sketch, Include Library, Manage Libraries…
Neste exemplo vamos apresentar uma forma alternativa de instalação, ou seja, vamos mostrar como adicionar uma biblioteca manualmente.
Considerando o ambiente operacional Microsoft Windows e se você optou pela instalação padrão do IDE do Arduino, a pasta que contém as bibliotecas de terceiros está localizada no seu perfil de usuário.
Ao fazer o download de uma biblioteca qualquer (geralmente está compactada – .zip), extraia os arquivos e copie para a pasta libraries do seu perfil de usuário. Note que os nomes das bibliotecas compactadas geralmente apresentam a palavra master como parte do nome. Por exemplo: DHT-sensor-library-master.zip. Após você descompactar este arquivo, renomeie a pasta para DHT.
Após a cópia, se você estiver com o IDE aberto, saia e abra novamente para que o Arduino carregue as bibliotecas instaladas.
Montagem do circuito
A montagem é muito simples, o circuito é o mesmo do DHT11 e DHT22. Você vai precisar de um sensor e um resistor de 10KΩ. Veja as imagens a seguir (oriente-se pelo pino 1 marcado na imagem):
Recursos da biblioteca DHT
Infelizmente a documentação, de um modo geral, não é clara ou até mesmo não existe nas bibliotecas de terceiros. Colocamos aqui a funções da biblioteca DHT da Adafruit. Se vocês encontrarem alguma inconsistência, escreva/comente para que possamos corrigi-las.
begin() configuração inicial do sensor.
readTemperature( true/false ) lê a temperatura e retorna um valor do tipo float em Celsius, se parâmetro false, ou Farenheit, se parâmetro true.
readHumidity() retorna um valor (percentual) do tipo float que representa a umidade relativa do ar.
computeHeatIndex( temperatura_Farenheit , umidade ) retorna um valor em Farenheit do tipo float que representa a sensação térmica. Você deve passar os parâmetros de temperatura em Farenheit e umidade (ambos do tipo float).
convertCtoF( temperatura_Celsius )
convertFtoC( temperatura_Farenheit ) converte respectivamente Celsius em Farenheit e Farenheit em Celsius (ambos do tipo float).