Módulo ACS712 - Medindo Corrente Elétrica Alternada e Contínua com Arduino

Módulo ACS712 - Medindo Corrente Elétrica Alternada e Contínua com Arduino

Neste tutorial você aprenderá como medir corrente elétrica alternada utilizando o  módulo sensor de corrente ACS712 juntamente com um Arduino. Para isso, realizaremos a medição do valor de corrente de um motor universal monofásico, com o objetivo de monitorar seu consumo de energia. Recomendamos a você que leia os tópicos introdutórios do tutorial SCT-013 - Sensor de Corrente Alternada com Arduino, pois, além de serem abordados os conceitos à respeito da medição de corrente, também são vistos os conceitos relacionados à Potência Elétrica, os quais, que serão utilizados neste tutorial. 

Apesar de abordarmos como medir corrente alternada, a medição de corrente Contínua é muito semelhante e será comentada em um tópico ao final do tutorial.

[toc]

kit robotica educacional com Arduino ESP ou Microbit

Sensor de corrente ACS712

O ACS712 é um pequeno sensor de corrente invasivo para baixas e médias correntes com alta sensibilidade e baixo custo. Ele é capaz de medir valores de corrente continua e alternada.

O ACS712 é um sensor de efeito Hall que gera uma saída de tensão proporcional a corrente que flui entre os pinos IP+ e  IP- do sensor.

Chip sensor ACS712
Chip sensor ACS712

Por usar o efeito Hall, o circuito do sensor ficar isolado eletricamente do circuito cujo o qual se está aferindo a corrente.

Existem diversos modelos do ACS712 com diferentes limites de medição de corrente, como podemos ver na tabela abaixo.

Tabela de opções sensores de corrente ACS712

As informações que serão importantes para nós são: os modelos (Part Number), a temperatura de operação em graus Celsius (TA), a corrente máxima a ser medida em Ampères (Optimized Range) e a relação de mV/A (Sensitivity, Sens). As informações completas podem ser consultadas no datasheet do fabricante.

O Módulo sensor de corrente ACS712

O módulo ACS712 nada mais é que um placa com o ACS712 e tudo que é preciso para usá-lo de maneira mais simples. Lembrando que este é um sensor de corrente invasivo, onde é necessário interromper o circuito para que ele seja instalado. Para este tutorial, será utilizado o módulo ACS712 30A, que por sua vez, consegue ler valores de corrente de até 30 Ampères.

Caso esteja usando o módulo ACS712 5A você precisa levar em conta a sensibilidade dele e fazer a devida alteração no código do Arduino.

Imagem do Módulo sensor de corrente ACS712
Imagem do Módulo sensor de corrente ACS712

Efeito hall

O ACS712 utiliza do efeito Hall para realizar a interface entre a corrente real do circuito com o Arduino, no qual, segundo preleciona Thomazini no livro Sensores Industriais:

"O efeito Hall caracteriza-se basicamente pelo aparecimento de um campo elétrico transversal em um condutor percorrido por uma corrente elétrica, quando ele se encontra mergulhado em um campo magnético".

Os sensores por efeito Hall são constituídos por dispositivos semicondutores que sofrem influência de campo magnético. Quando colocamos esse dispositivo semicondutor em série com a fonte e a carga, ocorre a passagem de elétrons por meio dele.

Passagem de corrente elétrica por um material semicondutor

Ao adicionarmos um campo magnético perpendicular ao movimento dos elétrons, surge uma força magnética, chamada de força de Lorentz.

Adição de um campo magnético

Sob influência dessa força, os elétrons livres não se moverão mais de forma retilínea, mas se concentrarão na direção da força magnética.

Regra da mão direita, indicando o sentido da força magnética
Concentração dos elétrons livres na parte superior do material semicondutor

Essa concentração faz surgir um potencial negativo, logo, na parte onde houver falta desses elétrons, surgirá o potencial negativo. Dessa forma, haverá uma diferença de potencial entre essas extremidades que será proporcional ao valor de corrente que está passando pelo material semicondutor. Com isso, medindo a tensão entre essas extremidades e por meio de cálculos, é possível descobrir o valor de corrente.


Mãos à Obra - Medindo Corrente Elétrica Alternada com Módulo ACS712 30A

Componentes necessários

Para a realização deste tutorial serão necessários:

Além desses itens, utilizaremos um pequeno motor universal monofásico para realizar a medição da corrente inerente ao funcionamento da mesma e também da potência consumida estipulada.

Montando o projeto

Por se tratar de um sensor de corrente invasivo, é necessário realizar a interrupção do circuito para que o ACS712 possa ser conectado ao circuito, como vemos abaixo.

Após isso, conectamos a alimentação (5V e GND) do ACS712 no arduino, e o pino OUT conectamos ao pino analógico A0, de acordo com o diagrama abaixo.

Programando

Após concluir a montagem descrita acima, basta dar upload no código abaixo para o arduino, no qual a explicação detalhada de cada linha poderá ser vista no tópico "Entendendo a fundo/Software". Lembre-se de selecionar a placa e a porta que está utilizando corretamente.

float vetCorrente[300];

void setup()
{
  Serial.begin(9600);
  pinMode(A0, INPUT);
}

void loop()
{
  double maior_Valor = 0;
  double valor_Corrente = 0;  

  float tensao = 127;
  float potencia = 0;

  for(int i = 0; i < 300; i++)
  {
    vetCorrente[i] = analogRead(A0);
    delayMicroseconds(600);
  }  

  for(int i = 0; i < 300; i++)
  {
    if(maior_Valor < vetCorrente[i])
    {
      maior_Valor = vetCorrente[i];
    }
  }  

  maior_Valor = maior_Valor * 0.004882812;
  valor_Corrente = maior_Valor - 2.5;
  valor_Corrente = valor_Corrente * 1000;
  valor_Corrente = valor_Corrente / 66;         //sensibilidade : 66mV/A para ACS712 30A / 185mV/A para ACS712 5A
  valor_Corrente = valor_Corrente / 1.41421356;

  Serial.print("Corrente = ");
  Serial.print(valor_Corrente);
  Serial.println(" A");

  potencia = valor_Corrente * tensao;

  Serial.print("Potencia = ");
  Serial.print(potencia);
  Serial.println(" W");
  
  Serial.print(".");
  delay(500);
  Serial.print(".");
  delay(500);
  Serial.print(".");
  delay(500);

  Serial.println("");
}

Colocando pra funcionar

Código compilado e circuito montado! Veja o resultado abaixo.

Resultado da montagem prática
Valores mostrados no monitor serial

Entendendo a fundo

Neste tópico serão tratados o funcionamento de cada parte do projeto deste tutorial, onde veremos os cálculos realizados pelo arduino para chegar ao valor de corrente correto.

Hardware

O circuito integrado ACS712 é fabricado pela Allegro MicroSystems, no qual é possível visualizar sua pinagem na imagen logo abaixo.

Pinagem do circuito integrado ACS712
  • IP+ / IP- : são os terminais que serão conectados em série com a carga. É por onde a corrente elétrica irá fluir.
  • VIOUT: corresponde ao pino de saída do sensor. Ele irá representar a forma de onda da corrente proporcional a sua entrada, no qual a sua proporcionalidade é definida pelo modelo que será utilizado. A forma de onda em sua saída apresentará um offset de 2,5V.
  • FILTER: terminal no qual será conectado um capacitor que definirá a largura de banda.
  • VCC / GND: correspondem aos terminais de alimentação do circuito integrado.

Logo abaixo é mostrado o circuito típico de suas aplicações.

Circuito do sensor ACS712

Software

A programação será responsável por, primeiramente, realizar várias leituras do pino analógico, no qual o ACS712 está conectado, durante um período de tempo, assim, podemos ter uma noção dos valores que constituem a senoide da corrente. Com esses valores, o arduino poderá calcular o valor de pico da senoide, no qual o mesmo equivale ao maior valor da amostra encontrada, e após isso, basta dividir esse valor por √2, segundo a seguinte fórmula:

Irms = Ipico / √2

Assim, conseguiremos descobrir o valor rms (eficaz) da corrente passando pelo condutor no qual o ACS712 está conectado.

Agora será explicado a função de cada linha presente no código apresentado no tópico "Programando".

- Criando um vetor

Inicialmente é criado um vetor que será utilizado para armazenar 300 amostras de valores que serão lidos adiante.

float vetCorrente[300];

- Aquisição das amostras por meio de uma estrutura de repetição

É criado um "for" para que o arduino possa armazenar vários valores de corrente durante um determinado instante de tempo.

for(int i = 0; i < 300; i++)
{
  vetCorrente[i] = analogRead(A0);
  delayMicroseconds(600);
}

- Encontrando o maior valor de amostra do vetor "vetCorrente[300]"

Cria-se outro laço "for" para que o arduino possa encontrar, entre as 300 amostras, a que apresente o maior valor.

for(int i = 0; i < 300; i++)
{
  if(maior_Valor < vetCorrente[i])
  {
    maior_Valor = vetCorrente[i];
  }
}

- Calculando o valor da corrente

No primeiro instante é necessário converter o valor encontrado, que se encontra entre 0 e 1023, para o valor de tensão lido pelo arduino. Para isso, por meio de uma regra de 3 simples, é possível encontrar o valor de tensão.

1024     -     5

(valor da amostra)     -     x

Seguindo essa regra de 3, é possível descobrir que basta multiplicar o valor da amostra por 0,004882812 para encontrar o valor da tensão lido pelo arduino.

maior_Valor = maior_Valor * 0.004882812;

- Removendo o valor de offset das amostras

A forma de onda resultante na saída do módulo ACS712 equivale a uma senoide com uma tensão de offset, como podemos ver abaixo.

Exemplo da forma de onda da saída do módulo ACS712

Seguindo seu datasheet, o valor da tensão de offset (equivalente ao zero da forma de onda senoidal da corrente) é proporcional ao valor de VCC * 0,5, que no nosso caso seria:

Voffset = VCC * 0,5

Voffset = 5 * 0,5

Voffset = 2,5 V

Por esse motivo foi necessário diminuirmos o valor de tensão encontrado por 2,5, como é indicado logo abaixo.

valor_Corrente = maior_Valor - 2.5;

- Convertendo para mili

O datasheet deste módulo apresenta os valores de sensibilidade de mV/A, com isso, foi necessário converter os valores de V para mV, para que o arduino possa calcular o valor da corrente adiante.

valor_Corrente = valor_Corrente * 1000;

- Encontrando o valor de pico da corrente

Agora dividiremos o resultado pelo valor equivalente a sensibilidade do sensor. Como visto anteriormente, existem diferentes modelos de ACS712, no qual o que foi utilizado neste tutorial é o ACS712ELCTR-30A-T, conhecido como ACS712 30A, no qual consultando seu datasheet foi possível encontrar o valor de sensibilidade de mV/A, que corresponde a 66 mV/A.

valor_Corrente = valor_Corrente / 66;

Caso o seu ACS712 seja de outro modelo, substitua o valor "66" pelo valor que corresponda a sensibilidade do seu módulo. Para o ACS712 5A, por exemplo, você precisa mudar para 185.

- Calculando o valor rms da corrente

Achado o valor de pico, é possível calcular o valor rms da corrente, finalizando assim o código referente a corrente.

valor_Corrente = valor_Corrente / 1.41421356;

- Mostrando o resultado no monitor serial

É mostrado os valores de corrente e potência no monitor serial, para que você possa visualizá-los.

Serial.print("Corrente = ");
Serial.print(valor_Corrente);
Serial.println(" A");

Serial.print("Potencia = ");
Serial.print(potencia);
Serial.println(" W");

É dado um tempo para a próxima atualização dos valores.

Serial.print(".");
delay(500);
Serial.print(".");
delay(500);
Serial.print(".");
delay(500);

Medindo corrente contínua

Uma vantagem deste sensor é que com ele você poderá medir também o valor da corrente de cargas DC, ou seja, do mesmo modo que ele pode ser empregado para medir corrente alternada, ele também pode ser empregado para medir corrente contínua.  Para isso, basta mudarmos algumas linhas da programação referentes ao vetor de amostras vetCorrente[300]. Abaixo é detalhado as alterações que deverão ser feitas.

Ao invés de encontrarmos o maior valor presente no vetor, como foi descrito no tópico Encontrando o maior valor de amostra do vetor "vetCorrente[300]" logo acima, teremos que realizar um cálculo de média aritmética com todos os valores.

Veja abaixo o código a ser retirado.

for(int i = 0; i < 300; i++)
{
  if(maior_Valor < vetCorrente[i])
  {
    maior_Valor = vetCorrente[i];
  }
}

maior_Valor = maior_Valor * 0.004882812;
valor_Corrente = maior_Valor - 2.5;

Em seu lugar, colocaremos o seguinte código.

int somaTotal;

for(int i = 0; i < 300; i++)
{
  somaTotal = vetCorrente[i] + somatorio;
}

valor_medio = somaTotal / 300;

valor_medio = valor_medio * 0.004882812;
valor_Corrente = valor_medio - 2.5;

Além disso, devemos retirar a seguinte linha do código:

valor_Corrente = valor_Corrente / 1.41421356;

Retirar essa linha se faz necessário pois ela converter o valor de pico da corrente para o valor rms, mas, por estarmos tratando de corrente contínua, isso não é necessário.

Essas modificações surtirão no seguinte efeito:

  • Por meio do laço for será realizado a soma de todos os valores presentes no vetor vetCorrente[300], e armazenando o resultado na variável somaTotal;
  • É realizado a divisão da variável somaTotal pelo número 300, encerrando assim o cálculo da média aritmética;
  • As linhas seguintes serão responsáveis por converter o valor achado até o momento no valor de corrente realmente lido.

O código final com essas alterações pode ser visualizado logo abaixo.

float vetCorrente[300];

void setup()
{
  Serial.begin(9600);
  pinMode(A0, INPUT);
}

void loop()
{
  double maior_Valor = 0;
  double valor_Corrente = 0;  

  float tensao = 127;
  float potencia = 0;

  for(int i = 0; i < 300; i++)
  {
    vetCorrente[i] = analogRead(A0);
    delayMicroseconds(600);
  }  



  int somaTotal = 0;

  for(int i = 0; i < 300; i++)
  {
    somaTotal = vetCorrente[i] + somaTotal;
  }
  valor_medio = somaTotal / 300;
  
  valor_medio = valor_medio * 0.004882812;
  valor_Corrente = valor_medio - 2.5;



  valor_Corrente = valor_Corrente * 1000;
  valor_Corrente = valor_Corrente / 66;         //sensibilidade : 66mV/A para ACS712 30A / 185mV/A para ACS712 5A

  Serial.print("Corrente = ");
  Serial.print(valor_Corrente);
  Serial.println(" A");

  potencia = valor_Corrente * tensao;

  Serial.print("Potencia = ");
  Serial.print(potencia);
  Serial.println(" W");
  
  Serial.print(".");
  delay(500);
  Serial.print(".");
  delay(500);
  Serial.print(".");
  delay(500);

  Serial.println("");
}

Com essas alterações, você poderá medir a corrente de sua carga DC tranquilamente.


Considerações finais

Esperamos que este tutorial tenha tanto trazido-lhe o entendimento a respeito do módulo ACS712 quanto tirado suas dúvidas sobre esse sensor de corrente.


Robô seguidor de linha

Robô seguidor de linha

Neste tutorial vamos aprender a fazer um robô seguidor de linha utilizando o sensor de obstaculo infravermelho (Você poderá usar o Módulo Segue Faixa - TCRT5000) em conjunto com um Arduino.

Robô seguidor de linha em competição

Para melhor entendimento deste tutorial é necessário que você já tenha um conhecimento prévio sobre Arduino e ponte H. Mas não se preocupe pois nossa equipe já produziu outros tutoriais sobre esse assuntos e você pode conferir alguns destes nos seguintes links: Entradas e Saídas Analógicas e Módulo Ponte H L298n .

[toc]

kit robotica educacional com Arduino ESP ou Microbit

A importância do robô seguidor de linha

O robô seguidor de linha, também conhecido como seguidor de faixa, é um projeto bem famoso entre os apaixonados por robótica. Quase sempre é o primeiro projeto de robótica móvel.

Em todo o mundo, competições de robótica possuem modalidades únicas  para o seguidor de linha, o que faz deste projeto algo que nunca irá deixar de ser melhorado.

Seu projeto envolve conceitos de dimensionamento de energia, controle de motores, programação de embarcados, entre outros.

Esses mesmos conceitos são levados para projetos maiores e mais complexos, tanto acadêmicos quanto industriais.

Robô seguidor de linha em uma industria
Exemplo de aplicação industrial de um robô seguidor de linha

Robôs seguidores de linha na industria

As aplicações industriais são bem diversificadas. Os robôs que gerenciam o estoque da grande rede de varejos Alibaba, começaram a funcionar com os princípios do seguidor de linha.

Eles manejavam as prateleiras de produtos dentro do estoque por meio de orientação de faixas no chão. Sua função era transportar os materiais de um lado para outro, seja para reajustar o estoque ou para levar para uma área de exportação.

Atualmente o Alibaba evoluiu os robôs, de forma que eles se comunicam, e se localizam, por meio de IA (Inteligência Artificial).

Centro de distribuição do Alibaba com uso de robô
Centro de distribuição do Alibaba

 


Como um robô seguidor de linha funciona ?

O funcionamento do robô seguidor de linha é simples. Ele deve seguir andando por cima de uma linha de cor preta (fita isolante) ou branca.

Os circuitos podem alternar entre as cores do campo e da faixa, no nosso caso iremos assumir que a pista é branca e a faixa é preta.

Usaremos 2 sensores infravermelho que detectam a presença ou não desta faixa. De acordo com a combinação dos sensores, o carrinho irá para frente ou virar para um dos lados.

Funcionamento do sensor infravermelho

O módulo sensor de obstáculo infravermelho IR é bem simples. Ele emite uma luz infravermelha por um LED negro e capta o reflexo com um LED receptor (LED claro).

Como sabemos, a luz reflete em superfícies claras e é absorvida em superfícies negras, como a fita isolante. Sendo assim o LED receptor irá detectar a luz infravermelha no branco e não detectar no preto.

Para uma melhor eficácia do sensor, a superfície em contraste com a faixa preta deve ser branca. Para ajustar a sensibilidade ao contraste, o modulo possui um potenciômetro de calibração.

sensor infravermelho
Funcionamento do sensor infravermelho

Diferença entre sensores infravermelho obstaculo e o TCRT5000

Você pode usar diferentes sensores infravermelhos para o projeto seguidor de linha, o que você precisa levar em conta é as especificações de cada um.

Um sensor infravermelho amplamente utilizado é o TCRT5000, que tem como vantagem seu tamanho e preço. Porem, ele precisa está próximo ao chão para que seja capaz de identificar a faixa, uma vez que seu alcance é de até 8mm. Entretanto, ele possui a vantagem de sofrer menos interferências de luzes infravermelhas externas.

Sensor de linha TCRT5000
Módulo Sensor de linha TCRT5000

Em contrapartida, a vantagem de usar o sensor de obstaculo é o seu maior alcance possuir ajuste, porem ele é mais suscetível a interferências das luzes ambientes.

Sensor de obstáculo infravermelho
Sensor de obstáculo infravermelho

Nesse tutorial, usaremos o sensor de obstaculo infravermelho. Dessa forma, caso esteja usando o TCRT5000, fique atento com a distância do chão. Ele precisa ficar com uma distância entre 1mm e 8mm para ser capaz de detectar a faixa.

Controlando motores com Ponte H

Quando lidamos com controle de cargas que consomem grande quantidade de energia, é importante que essas cargas sejam controladas com circuitos que separem o circuito de controle do circuito de potência.

Para controlar motores, é comum usarmos um circuito chamado ponte H, ele é capaz por controlar o sentido de giro do motor e a sua velocidade, usando o PWM.

PWM

PWM (Pulse Width Modulation – Modulação por Largura de Pulso) é uma técnica para obter resultados analógicos por meios digitais (Leia mais sobre Grandezas digitais e analógicas e PWM).

Essa técnica consiste na geração de uma onda quadrada em uma frequência muito alta em que pode ser controlada a porcentagem do tempo em que a onda permanece em nível lógico alto, alterando, assim, a tensão média.

Por exemplo, se a saída é de 5V, porem ela fica apenas 50% do tempo em 5V e outros 50% do tempo em nível lógico baixo, isso resulta em uma tensão média de 2,5V (50% x 5V).

Dessa forma, esta variável de tempo é capaz de controlar de velocidade do nosso carrinho alterando a tensão média aplicada no motor.

Os valores de PWM variam de 0 (parado) até 255 (velocidade máxima ou 5 V).

Controlando a velocidade do motor através da Ponte H

Existem varias opções de Ponte H, nesse tutorial usaremos o módulo Ponte H com CI L298N que dispões de duas pontes H, sendo capaz assim de controlar dois motores.

Cada ponte H possui um pino que ativa ou não a ponte H. Caso tenha um sinal de 5V aplicado nele, a ponte estará ligada, caso seja 0V a ponte estará desligada. Como temos 2 pontes H, temos o Enable A(Ativa A) e o Enable B (Ativa B).

Normalmente os Enables A e B ficam em curto com um sinal de 5V da placa através de um jumper.

Jumpers Enable A e B

Se retiramos esse jumper e inserimos um sinal PWM nessas entradas, modularemos a tensão que é enviada para o motor. Isso ocorre porque a ponte H só ira “funcionar” enquanto o sinal de Enable estiver com 5V, assim teremos o mesmo efeito de tensão média explicado anteriormente.

Apesar de a ponte H ser controlada por um sinal de 5V, elá pode chavear uma tensão diferente. Podemos, por exemplo, controlar uma tensão de 6V, vindo de um conjunto de 4 pilhas AA. Nesse caso, apesar de o sinal PWM ser de 5V ele modulará os 6V nos motores.

A descrição completa sobre como funciona uma ponte H L298N e como controlar a velocidade de um motor usando uma ponte H L298N pode ser visto nos nossos tutoriais sobre os respectivos assuntos.

 


Montado um robô seguidor de linha com sensor infravermelho

A partir de agora iremos mostrar como montar o seu próprio robô seguidor de linha.

Componentes Necessários

Para este projeto iremos utilizar:

 

Montando o projeto do robô seguidor de linha

Abaixo segue um esquema de ligações e montagem ELETRÔNICA do projeto:

Este projeto possui um procedimento de montagem complexo devido ao fato da necessidade de termos que passar vários fios por um espaço limitado ao tamanho do chassi do seu carrinho.

Calibração do Sensor infravermelho

Ao usar o sensor infravermelho, seja o sensor de obstaculo ou o TCRT5000, você precisa calibrar o sensor para que seja capaz de detectar adequadamente a mudança de cor entre preto e branco.

No vídeo a segui eu mostramos como fazer essa calibração.

Programando o controle do Robô seguidor de linha

A programação do projeto é bem simples. O carrinho precisa fazer a leitura dos sensores e definir pra qual  lado ele deve ir, somente isso, até por que um programa muito extenso pode prejudicar o rendimento.

/*DECLARAÇÃO DE VARIAVEIS*/
#define MotorA_sentido1 2
#define MotorA_sentido2 4
#define MotorB_sentido1 8
#define MotorB_sentido2 9
#define MotorA_PWM 3  
#define MotorB_PWM 10  

#define veloc0 0
#define veloc1 80
#define veloc2 180
#define veloc3 255

#define Sensor_direita 6
#define Sensor_esquerda 7

bool direita, esquerda;

void setup() {
  Serial.begin(9600);
  pinMode(MotorA_sentido1, OUTPUT);
  pinMode(MotorA_sentido2, OUTPUT);
  pinMode(MotorB_sentido1, OUTPUT);
  pinMode(MotorB_sentido2, OUTPUT);
  pinMode(MotorA_PWM, OUTPUT);
  pinMode(MotorB_PWM, OUTPUT);
  pinMode(Sensor_direita, INPUT);
  pinMode(Sensor_esquerda, INPUT);
  
}

void loop() {
   //Define o sentido de rotação dos motores
  digitalWrite(MotorA_sentido1, LOW);
  digitalWrite(MotorA_sentido2, HIGH);
  digitalWrite(MotorB_sentido1, HIGH);
  digitalWrite(MotorB_sentido2, LOW);
  
  //Leituras dos Sensores
  direita = digitalRead(Sensor_direita);
  esquerda = digitalRead(Sensor_esquerda);
  Serial.print(direita);
  Serial.print(" || ");
  Serial.println(esquerda);

  //Rodando os motores dependendo das leituras
 if(direita == false && esquerda == false){
 analogWrite(MotorA_PWM, veloc2);
 analogWrite(MotorB_PWM, veloc2);
 } else if(direita == false && esquerda == true){
 delay(400);
 analogWrite(MotorA_PWM, veloc2);
 analogWrite(MotorB_PWM, veloc1);
 delay(400);
 }else if(direita == true && esquerda == false){
 delay(400);
 analogWrite(MotorA_PWM, veloc1);
 analogWrite(MotorB_PWM, veloc2);
 delay(400);
 
 }else if(direita == true && esquerda == true){
 analogWrite(MotorA_PWM, veloc0);
 analogWrite(MotorB_PWM, veloc0);
 }
}

Colocando o Robô seguidor de linha para funcionar

Agora é só por o carrinho pra rodar na pista !

Robô seguidor de linha montado
Robô seguidor de linha montado

 

Problemas comuns e como resolver

Vale notar que ele pode não fazer o percurso de primeira, o que significa que ajustes devem ser feitos no código ou ate mesmo no hardware. Alguns problemas comuns de acontecer:

  • Bateria fraca - Os testes podem ter consumido a bateria e talvez seja necessário o uso de uma nova. Baterias abaixo de 6,5 Volts já começam a diminuir a eficiência do carrinho.
  • Carrinho saindo da pista - Isso pode acontecer por ele estar rápido de mais ou por falha do infravermelho. Em caso de ele estar muito rápido basta trocar a velocidade dos motores em cada situação, o nosso código já possui outras velocidades definidas no cabeçalho. Se o problema for com o contraste da pista (talvez parte dela esteja mais escura) use 2 LEDs de alto brilho na frente do carrinho para iluminar a pista próximo aos sensores. Os LEDs podem ir conectados diretos no 5 V do arduino (lembrando de por um resistor de 300Ohms).
  • Carrinho não roda - Este é um problema complexo, pois podem ser infinitas possibilidades. Tente isolar os componentes e testar 1 por 1, principalmente os motores e a ponte H. Em alguns casos pode ser problemas de aterramento da bateria também.

Entendendo a fundo o Software

Declaração de Variáveis

Na primeira parte do código é feita a declaração das variáveis a serem utilizadas. Nota-se que a existe um grande numero de variáveis utilizando #define, isto é por conta de serem apenas nomes associados a números, não precisamos fazer contas com essas variáveis, portanto elas não precisam ser do tipo INT, FLOAT, entre outras.

O fato de declarar algo por meio de #define ocupa menos espaço de memória, o que dá um ganho na velocidade de execução do programa. As únicas variáveis a serem definidas por um tipo são as que armazenarão os valores lidos dos sensores (direita e esquerda), essas variáveis são do tipo bool e portanto só assumem dois estados (FALSE e TRUE).

/*DECLARAÇÃO DE VARIAVEIS*/
#define MotorA_sentido1 2
#define MotorA_sentido2 4
#define MotorB_sentido1 8
#define MotorB_sentido2 9
#define MotorA_PWM 3  
#define MotorB_PWM 10  

#define veloc0 0
#define veloc1 80
#define veloc2 180
#define veloc3 255

#define Sensor_direita 6
#define Sensor_esquerda 7

bool direita, esquerda;

Cada motor possui 3 pinos: 2 para definir o sentido de rotação da roda (IN1 e IN2 / IN3 e IN4) e 1 pra definir a velocidade de rotação (Enable A / Enable B)por meio de valores PWM. Lembre-se de que os pinos de velocidade devem conter o "~" desenhado ao lado da porta na placa Arduino, caracterizando o pino como PWM.

Declaramos também 4 velocidades de PWM que podem ser interpretadas como PARADO, DEVAGAR, NORMAL e RÁPIDO, respectivamente. Os sensores foram definidos em suas respectivas portas digitais(6 e 7) e por fim, foram declaradas 2 variáveis do tipo BOOL para armazenar os valores dos sensores.

Função Void Setup()

A função void setup, que roda apenas uma vez, defini todas as configurações necessárias para funcionamento do sistema.

void setup() {
  Serial.begin(9600);
  pinMode(MotorA_sentido1, OUTPUT);
  pinMode(MotorA_sentido2, OUTPUT);
  pinMode(MotorB_sentido1, OUTPUT);
  pinMode(MotorB_sentido2, OUTPUT);
  pinMode(MotorA_PWM, OUTPUT);
  pinMode(MotorB_PWM, OUTPUT);
  pinMode(Sensor_direita, INPUT);
  pinMode(Sensor_esquerda, INPUT);
  
}

Nesta função declaramos as variáveis que definem os pinos utilizados no Arduino como sendo Entrada(INPUT) ou Saída(OUTPUT). Além disso colocamos a função Serial.begin() que inicializa a comunicação serial entre o Arduino e o computador.

MAS O CARRINHO NÃO RODA LIGADO NA BATERIA ?!?!?! Sim, porém precisamos fazer testes antes de executar a versão final, para isso utilizamos alguns comandos via serial para poder calibrar sensores, averiguar execução do programa, entre outros.

Função  Void Loop ()

Em seguida temos o loop do nosso programa onde o carrinho ira fazer suas principais funções.

- Definindo sentido de giro dos motores

Primeiro é necessário definir o sentido de rotação das rodas.

//Define o sentido de rotação dos motores
  digitalWrite(MotorA_sentido1, LOW);
  digitalWrite(MotorA_sentido2, HIGH);
  digitalWrite(MotorB_sentido1, HIGH);
  digitalWrite(MotorB_sentido2, LOW);

Nesta parte do código precisamos mandar um sinal alto e um sinal baixo entre os pares de portas IN1/IN2 e IN3/IN4. Como nosso carrinho não anda pra trás nós vamos setar essas configurações para que as rodas girem no mesmo sentido(pra frente no caso).

Veja que os pares no nosso código estão invertidos, isso acontece por que a montagem de hardware foi invertida entre os motores.

É como se os polos fossem trocados de lugar entre os motores, porém lembre-se que motores DC não possuem polaridade definida, logo podemos inverter a ligação + e - sem problemas. Isso altera apenas o sentido para o qual o motor gira. Essa é uma das partes que devem ser testadas antes da montagem final do carrinho.

- Leituras dos Sensores

Adiante, temos as leituras dos sensores infravermelhos e a impressão na serial dos valores lidos. Isso é apenas para verificar se os sensores estão funcionando corretamente, não interferindo no funcionamento final do projeto.

//Leituras dos Sensores
  direita = digitalRead(Sensor_direita);
  esquerda = digitalRead(Sensor_esquerda);
  Serial.print(direita);
  Serial.print(" || ");
  Serial.println(esquerda);

As variáveis do tipo BOOL são utilizadas para armazenar os valores digitais lidos pelos sensores.

- Controlando a direção do robô

Por fim, temos as condições de giro do motor com base no sensores infravermelhos.

//Rodando os motores dependendo das leituras
 if(direita == false && esquerda == false){
 analogWrite(MotorA_PWM, veloc2);
 analogWrite(MotorB_PWM, veloc2);
 } else if(direita == false && esquerda == true){
 delay(400);
 analogWrite(MotorA_PWM, veloc2);
 analogWrite(MotorB_PWM, veloc1);
 delay(400);
 }else if(direita == true && esquerda == false){
 delay(400);
 analogWrite(MotorA_PWM, veloc1);
 analogWrite(MotorB_PWM, veloc2);
 delay(400);
 
 }else if(direita == true && esquerda == true){
 analogWrite(MotorA_PWM, veloc0);
 analogWrite(MotorB_PWM, veloc0);
 }

Para isso, utilizamos as condições IF Else, que são mais comum. São 2 variáveis combinatórias que geram 4 possibilidades, porém a ultima condição é quase "impossível" (true e true), pois seria a leitura dos sensores detectando a faixa preta ao mesmo tempo (como é um erro estranho, o carrinho deve parar).

Os motores estão ligados em portas DIGITAIS mas lembre-se que estamos utilizando valores PWM, logo as funções de comando são do tipo analogWrite(porta, PWM). Para que o carrinho possa ter tempo de verificar o estado dos sensores novamente, alguns delays de curto período são utilizados, mas isso pode variar de projeto para projeto.

Entendendo a fundo o Hardware

O carrinho funciona com uma comunicação entre os sensores, o Arduino e a ponte H controlando os motores.

Através das leituras do sensores enviadas para o Arduino por meio das portas digitais, o controlador irá acionar um motor mais rápido ou mais devagar do que o outro. Os sensores emitem 5 V (faixa preta) ou 0 V(pista branca) para as portas digitais. O Arduino modula os valores de velocidade pelos valores PWM que variam de 0 volts (0) até 5 volts (255), fazendo isso ao longo de todo trajeto.

Observe que utilizamos apenas 1 bateria para todo o sistema. A bateria que alimenta o Arduino pelo pino P4 energiza não somente o controlador como também a ponte H dos motores por meio do pino Vin do Arduino. Esta porta é capaz de emitir valores maiores do que os 5 volts que o regulador de tensão da placa utiliza. Sendo assim a tensão de entrada no pino P4 é a mesma do pino Vin.


Conclusão

Este é um dos projetos mais simples de robótica móvel utilizando Arduino e claro que pode ser melhorando em muitos aspectos.

Algumas sugestões de melhorias são:  controle de velocidade PID, desvio de obstáculos, reconhecimento de pista, machining learning, etc.

Desafio

Crie uma função para o robô desviar de obstáculos e retornar para a pista. O sensor ultrassônico é uma ótima opção para ajudar nesse desafio.


Shield Ethernet W5100 - Monitorando sensores com um Servidor Web

Shield Ethernet W5100 - Monitorando Sensores com um Servidor Web

Se você gostou do nosso tutorial inicial sobre a criação de Servidores Web utilizando o Arduino UNO juntamente com o Shield Ethernet W5100, prepare-se, pois, neste tutorial vamos dar sequência ao conteúdo citado, apresentando novos conceitos para que você possa incrementar a sua aplicação. Neste tutorial você aprenderá como a monitorar as informações de seu Arduino, como por exemplo, temperatura, através de um navegador com o auxilio de um Servidor Web implementado com o Shield Ethernet W5100

É importante, para o pleno entendimento desse tutorial, que o leitor tenha lido o tutorial anterior: Shield Ethernet W5100 - Criando um Servidor Web com Arduino

[toc]


Mãos à obra - Monitorando sensores com um Servidor Web

Nesta seção iremos demonstrar todos os passos que você deve seguir para aprender a monitorar sensores com um Servidor Web. De maneira mais específica, vamos desenvolver um projeto em que o usuário consiga monitorar valores de temperatura provenientes de um sensor LM35 (não esqueça de conferir nosso tutorial sobre o sensor de temperatura LM35 clicando aqui) e também o estado de um botão, ou seja, se o mesmo está pressionado ou não.

Componentes necessários

Para reproduzir este projeto, você irá precisar dos seguintes componentes:

Montando o projeto

Na figura abaixo você pode conferir o hardware pronto para ser utilizado.

Projeto Shield Ethernet W5100 - Monitorando sensores com um Servidor Web
Projeto com Shield Ethernet W5100, Arduino Uno e LM35

Gostaríamos de sugerir que você tenha bastante cuidado no momento em que for encaixar o Shield Ethernet W5100 no Arduino UNO, pois, além da possibilidade de entortar os pinos do shield, você também pode se machucar.

Lembre-se que o shield em questão possui uma série de pinos em sua parte inferior, tanto nas laterais como em sua parte dianteira, portanto, antes de pressionar o mesmo sobre o Arduino UNO, certifique-se de que os pinos estejam levemente posicionados em suas respectivas entradas para que então você possa ir realizando o encaixe lentamente.

Realizando as conexões

Para reproduzir este projeto, garanta que o seu Shield Ethernet W5100 esteja ligado corretamente a uma das portas LAN presentes no seu modem ou roteador.

Programando

Este programa foi elaborado a partir do código-exemplo da biblioteca Ethernet.h denominado WebServer.

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 25, 16); 
EthernetServer server(80);     

void setup() 
{
    pinMode(5,INPUT);
    Ethernet.begin(mac, ip);  
    server.begin();           
} 


void loop() {

    EthernetClient client = server.available();  

    if (client) 
    {    
        boolean currentLineIsBlank = true;
        while (client.connected()) 
        {
            if (client.available()) 
            {   
                char c = client.read(); 
                
                if (c == '\n' && currentLineIsBlank) {
                  
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Connection: close");
                    client.println("Refresh: 2");
                    client.println();
                    
                    client.println("<!DOCTYPE html>");
                    client.println("<html>");
                    client.println("<head>");
                    client.println("<title>Servidor Web VDS</title>");
                    client.println("</head>");
                    client.println("<body>");
                    client.println("<h1><font color=#4279c7>Servidor Web do Vida de Sil&iacute;cio</font></h1>");
                    client.println("<hr/>");
                    client.println("<h1>Temperatura</h1>");
                    porta_analogica(client);   
                    client.println("<br/>");
                    client.println("<h1>Entrada digital</h1>");
                    porta_digital(client); 
                    client.println("</body>");
                    client.println("</html>");
                    break;
                }
                
                if (c == '\n') 
                {    
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') 
                {
                    currentLineIsBlank = false;
                }
            } 
        } 
        
        delay(1);      
        client.stop(); 
        
    } 
} 

void porta_analogica(EthernetClient client_aux)
{
  client_aux.print("LM35:");
  int valor = analogRead(A0);
  float temperatura = (((valor*5)/1023)-0.5)*100;
  if(temperatura >=50)
  {
      client_aux.println("<font color=#FF0000>");
      client_aux.println(temperatura);
      client_aux.println("graus");
      client_aux.println("</font>");
  }
  else
  {
      client_aux.println("<font color=#000000>");
      client_aux.println(temperatura);
      client_aux.println("graus");
      client_aux.println("</font>");
  }
}


void porta_digital(EthernetClient client_aux)
{
  client_aux.print("Pino digital 5:");
  bool valor = digitalRead(5);
  if(valor == HIGH)
  {
      client_aux.println("<font color=#FF0000> Ligado</font>");
  }
  else
  {
      client_aux.println("<font color=#000000> Desligado</font>");
  }
}

Colocando para funcionar

Veja como ficou nosso segundo Servidor Web.

Shield Ethernet W5100 - Monitorando sensores com um Servidor Web
Acessando Servidor web do Shield Ethernet W5100 através de um navegador

Entendendo a fundo

Antes de começarmos com a explicação do código, gostaríamos de ressaltar que iremos apresentar os detalhes apenas dos tópicos não contemplados no tutorial anterior, pois, desta maneira, será mais fácil focar nas partes referentes às atualizações feitas sobre o programa já existente, portanto, caso você tenha alguma dúvida sobre alguma parte do programa que não seja explicada neste momento, sugerimos que acesse o nosso material citado anteriormente.

Software

- Definindo os pré-requisitos para o funcionamento do código

Inicialmente, devemos incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca SPI.h, responsável pela comunicação dos módulos do shield com o Arduino UNO utilizando o protocolo SPI e a biblioteca Ethernet.h que atua possibilitando a conexão do conjunto, em um primeiro momento, com uma rede local.

Após a inclusão das bibliotecas citadas, devemos definir um endereço MAC (lembre-se que este pode ser qualquer um, desde que seja único em sua rede local) e um endereço IP (este deve ser um endereço válido  e disponível dentro da sua rede local). Além disso, devemos criar o objeto que será responsável por representar o Servidor Web no código (aqui, chamamos este de server) e relacioná-lo com a porta 80.

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 25, 16); 
EthernetServer server(80);

- Definindo as configurações iniciais

Dentro da função setup(), devemos determinar o modo de operação do pino digital que será utilizado (este terá o papel de uma entrada digital) . Além disso, iniciamos a conexão com a rede local através da função Ethernet.begin() (passando como parâmetro os endereços MAC e IP definidos anteriormente) e também iniciamos o Servidor Web por meio da sentença server.begin() (lembre-se que server é o objeto criado para representar o Servidor Web no código).

void setup() 
{
    pinMode(5,INPUT);
    Ethernet.begin(mac, ip);  
    server.begin();           
}

- Criando a página para responder à requisição do navegador

No artigo anterior foi possível compreender como devemos proceder para elaborar uma página bem simples, contendo apenas elementos escritos e também estáticos, ou seja, que não sofriam nenhum tipo de alteração. Neste momento, iremos incrementar o programa criado anteriormente, portanto, vamos deixar de lado a parte referente ao processo de requisição do navegador (já explicado) e iremos focar apenas na elaboração da página que cumpra o objetivo proposto neste material.

Você se lembra do cabeçalho padrão que enviamos para o navegador antes de enviarmos a página propriamente dita? Para ajudar, vamos colocá-lo aqui.

client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();

Definindo tempo de atualização da página 

A primeira modificação que faremos neste momento será a inclusão de uma linha de código que faça com que a página seja atualizada em intervalos de tempo definidos. Isto é importante para este projeto em virtude de estarmos trabalhando com aquisição de variáveis, portanto, devemos atualizar a página periodicamente para que seja possível visualizarmos sempre os valores atuais das variáveis envolvidas. Sendo assim, utilizamos a seguinte sentença para que a página seja atualizada de 2 em 2 segundos.

client.println("Refresh: 2");

Veja como ficará o nosso cabeçalho padrão

client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println("Refresh: 2");
client.println();

A estrutura da página em HTML

O próximo passo que faremos será construir, de fato, a página que será enviada ao navegador. Com uma breve recapitulação, devemos lembrar que todo conteúdo que compõe a página deve estar dentro da seguinte estrutura:

client.println("<!DOCTYPE HTML>");
client.println("<html>");
           . 
           .
***** Conteúdo da página *****
           .
           .
client.println("</html>"); 

Como ressaltado anteriormente, dentro desta estrutura temos o conteúdo da página que queremos enviar para o navegador, de modo que, nesta, devemos ter pelo menos dois blocos, um responsável pelas informações gerais do documento, limitado pelo uso do par <head></head> e o outro, por sua vez, deve conter o corpo da página e está entre as tags <body> e </body>.

client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
           .
           .
   ***** Bloco 1 *****
           .
           .
client.println("</head>");
client.println("<body>");
           .
           .
   ***** Bloco 2 *****
           .
           .
client.println("</body>");
client.println("</html>");

Definido o título para a página

Neste momento, vamos utilizar apenas uma tag dentro do bloco 1, denominada <title>, cuja função consistirá em definir um título para a página (este título aparecerá na aba do navegador). Para executarmos a ação proposta, devemos colocar o título desejado entre o par <title></title>.

client.println("<!DOCTYPE HTML>");
client.println("<html>");

client.println("<head>");
client.println("<title>Servidor Web VDS</title>"); 
client.println("</head>");

client.println("<body>");
           .
           .
   ***** Bloco 2 *****
           .
           .
client.println("</body>");
client.println("</html>");

Veja como ficou o título da nossa página:

servidor Shield Ethernet W5100 - Monitorando sensores com um Servidor Web
Título da página.

Escrevendo o corpo da página web

Quanto ao corpo da página (entre o par <body></body>), a primeira coisa que faremos será colocar um título visível na própria página. Para realizar este procedimento, utilizaremos a tag <h1>, que por sua vez, consiste em uma tag para apresentar um determinado texto em um modelo predefinido. Além disso, utilizaremos também a tag <font>, através da qual, poderemos fazer alterações no título produzido.

client.println("<h1><font color=#4279c7>Servidor Web do Vida de Sil&iacute;cio</font></h1>");

Alguns pontos no trecho de código acima devem ser ressaltados:

  1. Tudo que estiver escrito entre o par <h1></h1> estará pré formatado no estilo deste cabeçalho.
  2. A tag <font> é responsável por modificar algum atributo relativo à formatação de uma determinada porção de texto. Para isto, devemos colocar o nome do atributo que queremos modificar, após a palavra font (apenas na tag de abertura), sendo assim, quando escrevemos <font color=#4279c7>, estamos indicando que a porção de texto entre o par <font color=#4279c7></font> deverá está colorida em um certo tom de azul (dado pelo código RGB em hexadecimal #4279c7).
  3. Repare que a palavra Silício foi escrita no código como Sil&iacute;cioEsta forma de escrita é necessária sempre que temos a utilização de algum tipo de acento, pois, nem todos os dispositivos estão configurados para apresentar caracteres acentuados da mesma forma. Sendo assim, utilizamos o comando &iacute; para colocar o acento agudo na letra da palavra Silício.

Veja o resultado deste procedimento na figura abaixo:

acessando Servidor Web Shield Ethernet W5100

Posteriormente, vamos inserir uma barra horizontal para separar o título criado no passo anterior dos textos que ainda serão criados, através do comando <hr/>.

client.println("<hr/>");

Após a inserção da barra citada, nossa página ficará da seguinte maneira:

Imprimindo a tempertatura

Em seguida, escrevemos outro texto utilizando o modelo de cabeçalho h1 referente ao valor que será obtido pelo sensor de temperatura LM35.

client.println("<h1>Temperatura</h1>");

Com este passo, a página será apresentada assim:

O próximo passo consiste em apresentar o valor de temperatura obtido através da conversão do sinal proveniente do sensor de temperatura utilizado. Obviamente, existem várias formas de fazer isso, no entanto, nós criamos uma função própria para isso, chamada porta_analogica() e passamos a variável client como parâmetro da mesma.

porta_analogica(client);

A função porta_analogica() será responsável por fazer a aquisição do valor de tensão na porta analógica A0 proveniente do sensor de temperatura LM35. Repare que nesta função utilizamos um conjunto if()/else para testar se o valor de temperatura é superior a um determinado valor, de modo que, caso seja, apresentaremos este valor na cor vermelha e caso não seja, na cor preta.

void porta_analogica(EthernetClient client_aux)
{
  client_aux.print("LM35:");
  int valor = analogRead(A0);
  float temperatura = (((valor*5)/1023)-0.5)*100;
  if(temperatura >=50)
  {
      client_aux.println("<font color=#FF0000>");
      client_aux.println(temperatura);
      client_aux.println("graus");
      client_aux.println("</font>");
  }
  else
  {
      client_aux.println("<font color=#000000>");
      client_aux.println(temperatura);
      client_aux.println("graus");
      client_aux.println("</font>");
  }
}

A apresentação do valor de temperatura ficará conforme a figura abaixo:

imprimindo valores de temperatura do servidor web no navegador

Imprimindo o estado da entrada digital - Botão

Após chamar a função porta_analogica(), utilizamos o comando <Br/> para fazer com que a próxima sentença utilizada na construção da página ocorra na próxima linha da tela.

client.println("<br/>");

Neste momento escrevemos um outro texto utilizando o modelo de cabeçalho h1. Este irá definir o título da seção em que o estado do botão será apresentado.

 client.println("<h1>Entrada digital</h1>");

Confira em que estágio nossa página está:

Por fim, chamamos a função porta_digital() cuja função consiste realizar os procedimentos necessários para apresentar o estado da nossa variável digital. Repare que, assim como na função porta_analogica(), também passamos a variável cliente como parâmetro.

porta_digital(client);

No bloco de código abaixo demonstramos o funcionamento da função porta_digital(), que por sua vez, apresentará a palavra Ligado, na cor vermelha, caso o botão esteja pressionado e a palavra Desligado, na cor preta, caso o botão esteja solto

void porta_digital(EthernetClient client_aux)
{
  client_aux.print("Pino digital 5:");
  bool valor = digitalRead(5);
  if(valor == HIGH)
  {
      client_aux.println("<font color=#FF0000> Ligado</font>");
  }
  else
  {
      client_aux.println("<font color=#000000> Desligado</font>");
  }
}

Veja o nosso resultado final:

Os procedimentos citados anteriormente servem para elaborar a página que será exibida no navegador em resposta a requisição feita pelo mesmo, de modo que, caso você queira entender partes do código externas ao que foi apresentado, verifique nosso primeiro tutorial.


Considerações finais

Neste tutorial, demonstramos como você monitorar as variáveis envolvidas no seu projeto, em uma página criada para ser exibida no seu navegador, utilizando um Arduino UNO e um Shield Ethernet W5100. Esta foi a segunda parte de uma série de artigos sobre a criação de Servidores Web, portanto, esperamos que continue nos acompanhando e sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.


Módulo relé - Acionando cargas com Arduino

Módulo relé - Acionando cargas com Arduino

Ao se trabalhar com sistemas inteligentes, é comum a necessidade de se controlar cargas das mais diversas potências, tal como: lâmpadas, motores, resistências, etc. O componente mais usado para ligar e desligar esses aparelhos são o relés. O relés são responsáveis por ligar e desligar equipamentos através de comandos. Neste tutorial você entenderá a importância dos relés, como funcionam. Aprenderá, também, a usar um módulo relé com seu Arduino.

[toc]

Para que servem os Relés?

Os microcontroladores, tais como Atmega, PIC e MSP, são dispositivos lógicos. Eles são usados com o intuito de ser a inteligência do circuito, o cérebro de nosso sistema inteligente.

Por isso, um microcontrolador usa tensões e correntes baixas para funcionar e não são produzidos para suportar grandes tensões e correntes. O Arduino UNO, por exemplo, que usa o Atmega328, suporta um máximo de 40mA em suas portas I/O e fornece uma tensão de 5V. Além disso, é sempre aconselhável separar o sistema de inteligência do sistema de acionamento, para que curtos ou problemas no sistema de acionamento não danifique sua placa Arduino.

Quando queremos acionar cargas com valores de corrente ou tensão maiores precisamos utilizar algum dispositivo que suporte tal carga. Por exemplo: Queremos acender uma lâmpada de 127V quando estiver escuro. Sabemos que o Arduino não é capaz de fornecer tal tensão, para isso iremos precisar de algum dispositivo capaz de ligar e desligar a lâmpada através do comando do nosso Arduino, uma boa pedida é o relé.

Para entender melhor o relé, vamos ver a diferença e semelhança entre ele e um interruptor residencial.

- Entendendo um interruptor

Diariamente ligamos e desligamos lâmpadas através de um dispositivo muito eficaz, o interruptor. Tal como o nome já diz, ele tem a capacidade de interromper o fluxo de energia e vice-versa. Veja na figura abaixo como um interruptor trabalha. O fio vermelho, que é o positivo e traz a energia, passa pelo interruptor e depois vai para a lâmpada que já possui o negativo conectado. Quando o interruptor está aberto, não temos passagem de energia, quando mudamos o estado dele e fechamos o contato, a lâmpada liga.

Interruptor residencial
Interruptor residencial

- Entendendo um Relé

Um relé é semelhante a um interruptor, com uma diferença, não precisamos usar nosso dedo para fechar ou abrir o contato. Para essa função, usamos um sistema engenhoso que quando alimentado, fecha o contato.

Esse sistema engenhoso possui um eletroímã, ou seja. Uma bobina que quando energizada criará um campo eletromagnético, se tornando um imã. Devido a força de atração magnética do eletroímã teremos a movimentação do interruptor. Veja a imagem a baixo para que possa entender melhor:

Dentro de um relé
Dentro de um relé

Quando alimentamos os terminais 3 e 4 da bobina, ela gera um campo eletromagnético que atrai a haste conectada ao terminal 2, que vence a força exercida pela mola conectada a ela. Isso faz com que essa haste se mova até encostar na haste conectada ao terminal 1. Com isso, teremos o contato fechado.

Quando paramos de alimentar a bobina através dos terminais 3 e 4, a força magnética exercida sobre a haste conectada ao terminal 2 deixa de existir e a mola puxa a haste de volta ao seu lugar inicial, abrindo o contato. Portanto, agora temos um interruptor acionado por uma bobina.

Usando um relé, podemos controlar um dispositivo, tal como a lâmpada de 127V que possui uma corrente e tensão alta, através da alimentação de uma bobina. A corrente e a tensão que essa bobina precisa varia com a especificação do relé.

Módulo Relé

Apesar de a bobina relé demandar uma corrente e uma tensão baixa, ainda assim o relé precisa de mais energia do que uma porta digital da sua placa Arduino pode fornecer.

Por conta disso, precisamos de um circuito auxiliar para o acionamento do relé. Esse circuito, que usa uma fonte de alimentação que pode ser a própria saída de 5V do seu Arduino, não é trivial, mas já pode ser encontrado pronto nos módulos relés muito usados com Arduino. Esse tipo de módulo poupa tempo e é muito simples de usar.

Módulo relé de 1 canal.
Módulo relé de 1 canal.

Veja que esse módulo relé possui 3 pinos. São eles:

  • Vcc - Pino para alimentação 5V
  • GND - Pino para Terra 0v
  • IN - Pino de comando do módulo. Esse é o pino responsável por ligar ou desligar o relé.

Existem vários modelos de módulos relés com diversas quantidades de canais, indo até 16 relés em uma só placa:

Módulo relé de 16 canais.
Módulo relé de 16 canais.

Veja algumas opções de módulos relés nesse link do Vida de Silício


Mãos à obra – Detectando elementos

Cuidado!

Nesse tutorial iremos mexer com tensões e correntes maiores. Tome cuidado ao manusear seu projeto, risco de choque!!

Tome cuidado para não energizar seu Arduino com a tensão da tomada. Isso irá queimá-lo.

Componentes utilizados:

Montando o projeto

Na figura abaixo, o leitor poderá conferir como foi realizada a montagem do projeto apresentado neste tutorial.  Lembre-se de montar o projeto com o seu Arduino desligado.

Vamos separar essa montagem em duas partes:

- Circuito de controle

Essa parte do projeto representa o Arduino e seus periféricos de baixa potência. Para montar seu circuito, use a figura a seguir. Garanta que seu Arduino esteja desligado durante a montagem.

O pino de entrada do botão é o 8 e o pino de saída do relé é o 13.

- Circuito de potência

Nessa parte iremos montar a parte de maior potência do nosso circuito. Para esse projeto iremos precisar de uma extensão que você não usará mais, ou você pode fazer a sua.

Quando lidamos com energia elétrica temos que tomar muito cuidado! Então monte seu projeto com segurança.  Não queremos transformar nossa diversão em dor de cabeça, não é mesmo?

Por isso, vamos montar uma extensão segura. Caso você já tenha uma que possa cortar os seus fios, você poderá usá-la. Basta executar apenas os três últimos passos.

Para nossa extensão você vai precisar de:

  • Um adaptador de tomada macho
  • Um adaptador de tomada fêmea
  • 4 metros de Fio de cobre (Fique à vontade em relação ao tamanho).
Adaptadores e fio para fazer a extensão
Adaptadores e fio para fazer a extensão

Vamos montar nossa extensão:

  • Divida seu fio de cobre em dois fios de 2 metros (ou metade do tamanho que você tiver). Dessa forma, você terá dois fios iguais;
  • Com seu alicate, descasque a ponta de cada fio;
Descasque a ponta do fio.
Descasque a ponta do fio.
  • Parafuse a ponta dos dois no adaptador macho;
Parafuse os fios dentro dos adaptadores.
Parafuse os fios dentro dos adaptadores.
  • Parafuse a outra ponta dos dois no adaptador fêmea;
Extensão pronta.
Extensão pronta.
  • Agora vamos conectá-la ao nosso circuito.
  • Corte um dos dois fios em um ponto onde ficará nosso módulo relé, verifique o melhor ponto para coloca-lo. (É para corta apenas um dos fios!)
contando 1 dos fios para colocarmos o módulo relé
Contando 1 dos fios para colocarmos o módulo relé
  • Descasque as duas pontas do fio cortado;
  • Parafuse uma no comum (COM) e outra no contato normalmente aberta (Pode está escrito nessa porta a sigla NA ou NO);
Parafuse os fios no módulo relé
Parafuse os fios no módulo relé.

Agora, volte, e confira se você realmente montou tudo como explicado.

Seu circuito ficará semelhante ao da foto a seguir:

Sistema montado.

Programando

Antes de adentrarmos na apresentação do código, disponibilizamos uma seção para ajudar aqueles que são iniciantes no assunto. Sinta-se livre para prosseguir caso você já tem domínio da IDE do Arduino.

Conectando o Arduino ao computador

Primeiramente, conecte seu Arduino ao computador e abra a IDE Arduino. Em seguida, é necessário selecionar a porta COM na qual o Arduino está conectado (este procedimento pode ser feito clicando no menu Ferramentas (tools) e em seguida escolhendo-se a porta correspondente no submenu Porta (port). Neste caso, a porta na qual está o Arduino é apresentada da seguinte maneira: COM3 (Arduino Micro).

Por fim, garanta também que o tipo de placa apropriado esteja selecionado (isso pode ser feito acessando o menu Ferramentas (tools) e o submenu Placa (board)).

– Código do projeto

Crie um programa (sketch) e salve com o nome de “programa_modulo_rele”.

Com o seu programa salvo, escreva nele o código conforme escrito abaixo.

#define RELE 13 
#define BOTAO 8

void setup() 
{
    pinMode(BOTAO, INPUT_PULLUP);
    pinMode(RELE, OUTPUT);
    estavel = digitalRead(BOTAO);
    estadoRele= 0; 
}

bool changed() 
    {
         bool now = digitalRead(BOTAO);   
         if (instavel != now) 
         {       
              bounce_timer = millis();   
              instavel = now;            
         }
         else if (millis() - bounce_timer > 10) 
         {  
              if (estavel != now) 
              {           
                  estavel = now;                  
                  return 1;
         }
    }
    return 0;
}

void loop() 
{
     if (changed()) { //verifica se houve mudança de estado
     { 
          if (digitalRead(BOTAO))
          {   
               estadoRele=!estadoRele;  //se mudou o estado e o botão está pressionado muda o valor de set
          }
     }
     digitalWrite(RELE,estadoRele);
}

Depois de escrever o código, clique em Upload para que o programa seja transferido para seu Arduino.

Colocando para funcionar

Conecte algum aparelho em sua extensão (que tenha uma coerente menor que 10A), um ventilador por exemplo. Então ligue seu Arduino e em seguida ligue a tomada de sua extensão.

Cuidado!

Só ligue seu sistema na tomada quando tiver a certeza que está tudo corretamente conectado.

Tome cuidado para não tomar um choque ou energizar seu Arduino com a tensão da tomada. Isso irá te machucar ou queimar seu Arduino.

Se tudo deu certo, quando você apertar o botão uma vez, o dispositivo que estiver ligado na tomada deverá ligar.

Sistema com relé acendendo lampada depois de apertado o botão pela primeira vez
Sistema depois de apertado o botão pela primeira vez

Quando apertar uma segunda vez, o dispositivo deverá desligar.

Sistema depois de apertado o botão pela segunda vez
Sistema depois de apertado o botão pela segunda vez

Entendendo a fundo

Software

– Nomeando os pinos utilizados através da diretiva #define

Primeiramente, utilizamos a diretiva #define para associar o pino de entrada digital 13 ao nome RELE e o pino digital 8 ao nome BOTAO (vale ressaltar que isso é apenas um recurso para facilitar a didática da programação, portanto, não obrigatório).

#define RELE 13
#define BOTAO 8

– Declarando as variáveis a serem utilizadas no projeto

Em seguida, temos um bloco onde ocorre a declaração das variáveis que serão utilizadas no decorrer do programa. As variáveis estavel instavel (ambas booleanas) e a variável bounce_timer (tipo unsigned long) são responsáveis por coordenar o processo de tratamento do bounce existente ao utilizarmos um push-button. Além disso, temos a variável estadoRele, também booleana, cuja função é acionar e desacionar o relé.

Um ponto importante que deve ser ressaltado aqui é que neste tipo de projeto torna-se fundamental o tratamento citado anteriormente, portanto, caso você tenha dúvidas no procedimento, sugerimos a leitura do nosso tutorial Leitura de botões e o Bounce.

bool estavel;    // Guarda o último estado estável do botão;
bool instavel;   // Guarda o último estado instável do botão;
unsigned long bounce_timer;
bool estadoRele;

– Definindo as configurações iniciais do projeto

Dentro da função setup(), temos a definição dos modos de operação dos pinos que serão utilizados neste projeto, isto é, do pino 13 como um pino de saída digital e do pino 8 como um pino de entrada digital. Além desta configuração, por meio da função digitalRead(), fazemos com que a variável estavel armazene o estado em que o botão se encontra no começo do programa e por fim, carregamos a variável estadoRele com o valor 0.

void setup() {
  pinMode(BOTAO, INPUT_PULLUP);  
  pinMode(RELE, OUTPUT); 
  estavel = digitalRead(botao);
  estadoRele= 0;
}

– Acionando o relé

O procedimento de acionamento do relé é bem simples, de modo que, a única coisa que fazemos é verificar o retorno gerado através da execução da função changed(), o qual, será verdadeiro ou falso. Caso o retorno da mesma seja verdadeiro, quer dizer que o usuário do projeto deseja efetuar uma mudança no estado do relé, sendo assim, verifica-se posteriormente se o botão está pressionado, para que, por fim, o conteúdo da variável estadoRele seja atualizado com o inverso do seu valor e possa ser utilizado na manipulação do relé através da função digitalWrite().

void loop() 
{
     if (changed()) 
     { 
          if (digitalRead(botao))
          {   
               estadoRele=!estadoRele; 
          }
     digitalWrite(RELE,estadoRele);
}

Conforme ressaltamos anteriormente, utilizamos a função changed() para conferir se houve alguma mudança do estado do relé, desejada pelo operador. Esta função é a responsável por atuar no tratamento do bounce quando houver um aperto do botão. Basicamente, o que ocorre neste ponto é a verificação do estado do botão após a passagem de uma quantidade de tempo julgada necessária para garantirmos que o sinal não sofre mais alterações em virtude da trepidação inerente ao seu funcionamento.

Novamente ressaltamos que, caso você tenha alguma dúvida neste ponto, consulte nosso tutorial sobre o tratamento do bounce, clicando aqui.

bool changed() 
    {
         bool now = digitalRead(BOTAO);   
         if (instavel != now) 
         {       
              bounce_timer = millis();   
              instavel = now;            
         }
         else if (millis() - bounce_timer > 10) 
         {  
              if (estavel != now) 
              {           
                  estavel = now;                  
                  return 1;
         }
    }
    return 0;
}

Desafio

Agora que sabemos usar um módulo relé. Que tal usar um sensor de presença para acender uma lâmpada ou um sensor de temperatura para ligar seu ventilador? Seria uma boa ideia para automatizar o seu quarto, o que acha?

Faça isso:

  • Ligue uma lâmpada quando detectar movimento no ambiente (Tutorial HC-SR501) ;
  • Ligue um ventilador caso a temperatura esteja muito alta (Tutorial LM35).

Dica: Leia nosso tutorial ensinando como controlar um Módulo Relé através de seu celular utilizando um Módulo Bluetooth:

Considerações finais

Neste tutorial demonstramos como você deve proceder para utilizar relés no acionamento de cargas cujas especificações de tensão e corrente não permitem que as mesmas sejam feitas diretamente por uma placa Arduino. Esperamos que você tenha gostado deste conteúdo e sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.


Módulo RFID RC522 Mifare com Arduino

Módulo RFID RC522 Mifare com Arduino

Neste tutorial entenderemos um como funciona um sistema RFID e aprenderemos como utilizar o módulo RFID RC522 Mifare através do Arduino.

[toc]

Entendendo o RFID

A tecnologia de RFID (Radio Frequency IDentification – identificação por radiofrequência) é um método de identificação através de sinais de rádio. Existem diversos métodos de identificação, mas o mais comum é armazenar um número de série que identifique uma pessoa ou um objeto, ou outra informação em um microchip.  

Tal tecnologia permite a captura automática de dados para identificação de objetos com dispositivos eletrônicos conhecidos como etiquetas eletrônicas, RF tags, cartões RF ou transponders, que emitem sinais de radiofrequência para leitores que captam estas informações. Tal tecnologia existe desde a década de 40 e veio para complementar a tecnologia de código de barras, bastante difundida no mundo.

O RFID pode ser utilizado em diferentes aplicações, inclusive na parte de segurança, onde podemos citar como exemplos de sua utilização o controle de acesso em catracas, alarmes contra furtos em lojas e até mesmo para o desbloqueio de computadores. Outra função muito comum que é atribuída a essa tecnologia são os cartões de utilização de transporte público.

Aplicação comum do RFID no controle de acesso
Aplicação comum do RFID no controle de acesso

Como funciona os sistemas RFID

Um sistema de RFID é composto, basicamente, de:

  • Um transceptor com decodificador e uma antena;
  • Um transponder (chamado também de Tag) que é eletronicamente programado com informações.

O transceptor emite, através de uma antena, sinais de rádio para ativar o Tag, que por sua vez, reponde uma mensagem ao receptor com a informações armazenadas em seu chip.

Uma tag é composta, basicamente, por um chip, que armazena informações, e uma antena.

Transponder RFID
Transponder RFID

Os transponders RFID são divididos em dois tipos : passivos e ativos.

Os transponders passivos utilizam a energia da onda de rádio frequência emitida pelo leitor para transmitir o seu sinal de resposta. Geralmente vêm com suas informações gravadas permanentemente quando são fabricadas. Contudo, em algumas é possível alterar as informações armazenadas em seu chip.

A grande vantagem dos transponders passivos é a facilidade de usa-lo em diversas aplicações, tais como: etiquetas, passaportes, chaveiros, cartões, etc.

Exemplo de aplicação de uma tag RFID passiva em uma etiqueta
Exemplo de aplicação de uma tag RFID passiva em uma etiqueta

Os transponders ativos contam com uma fonte de energia própria para transmitir seu sinal de resposta, aumentando o alcance. Esse tipo de Tag pode contar com memória RAM, capaz de armazenar até 32 KB de informação.

Exemplo de transponder RFID ativo usado para identificação de um veículo.
Exemplo de transponder RFID ativo usado para identificação de um veículo. Eles são muito usados nesse tipo de aplicação devido ao seu maior alcance.

Outra característica importante dos sistema RFID é a frequência de operação. A frequência interfere na taxa de transferência de dados entre a etiqueta e o leitor e em seu alcance.

As três frequências mais utilizadas para o sistema RFID passivo são: baixa frequência (LF), de 125kHz, alta frequência (HF), 13,56 MHz, e ultra alta frequência (UHF), operando na faixa de 860 a 960MHz.

Quanto maior a frequência, maior será o alcance máximo, mas esse não é o único fator. Também influenciam no alcance do sistema RFID: potencia e sensibilidade do transceptor e o tipo de transponder.

Módulo RFID-RC522 13,56MHz Mifare

Este módulo RFID usa o chip MFRC522 da empresa NXP, que por sua vez, pode ser usado em comunicações a uma frequência de 13,56MHz, permitindo, por exemplo, sem contato, a leitura e escrita em cartões que seguem o padrão Mifare.

Módulo RFID MFRC522 Mifare - Tansceptor

Para usar a tecnologia RFID precisamos de um receptor e de um emissor. Geralmente o módulo leitor RFID RC522 acompanha um kit com uma tag e um cartão RFID o qual usaremos nesse projeto.

Exemplo de cartão e tag RFID MFRC522 Mifare
Exemplo de cartão e tag RFID MFRC522 Mifare - Transponders

Mão à obra - Usando o Módulo Leitor RFID-RC522 13,56MHz Mifare com Arduino

Componentes necessários

Montando o projeto

 

Esquema de montagem do Módulo RFID RC522 Mifare com Arduino
Esquema de montagem do Módulo RFID RC522 Mifare com Arduino

Programando

- Biblioteca

Para desenvolver o projeto proposto com o Módulo RFID RC522 utilizou-se a biblioteca MFRC522.h. Esta biblioteca foi produzida por Miguel Balboa e está disponível neste link.

Você pode expandir o tutorial abaixo para aprender como instalá-la.

Adquirindo e instalando a biblioteca que será utilizada

Para adquirir a biblioteca em questão, basta acessar o link apresentado anteriormente, clicar no botão clone or Download e por fim, no botão Download ZIP, conforme a figura abaixo.

Como baixar a biblioteca RFID
Como baixar a biblioteca RFID

Após a realização do download dos arquivos compactados no formato ZIP, abra a IDE do Arduino, selecione o menu Sketch, o submenu Incluir Bilioteca e por fim, basta clicar na opção Adicionar biblioteca .ZIP (Add ZIP Library) e encontrar o arquivo que acabou de ser baixado.

 

 

Uma outra forma de fazer isso é extrair o conteúdo do arquivo ZIP dentro da pasta Libraries (onde foi instalada a IDE do Arduino).

- Código do projeto

Não ligar o módulo RFID-RC522 em 5V, o mesmo deve ser ligado em 3,3V.

//Vida de Silício
//Felipe Gbur

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
#define LED_R 2//LED Vermelho
#define LED_G 3 //LED Verde
char st[20];

MFRC522 mfrc522(SS_PIN, RST_PIN);

void setup()
{
  // Inicia a serial
  Serial.begin(9600);
  // Inicia  SPI bus 
  SPI.begin();
  // Inicia MFRC522    
  mfrc522.PCD_Init();
  Serial.println("Aproxime o seu cartao/TAG do leitor");
  Serial.println();
  pinMode(LED_R, 2);
  pinMode(LED_G, 3);
}

void loop()
{
  digitalWrite (LED_G, LOW);
  digitalWrite (LED_R, HIGH);

  // Busca novos cartões 
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Seleciona um catão a ser lido
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  //Mostra ID na serial
  Serial.print("ID da tag:");
  String conteudo = "";
  byte letra;
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    conteudo.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    conteudo.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Mensagem : ");
  conteudo.toUpperCase();

  if (conteudo.substring(1) == "D6 35 19 7E") //ID CARTÃO
  {
    Serial.println("Acesso autorizado !");
    Serial.println();
    digitalWrite (LED_G, HIGH);
    digitalWrite (LED_R, LOW);
    delay(5000);//Delay apagar LED Verde
    digitalWrite (LED_G, LOW);
    digitalWrite (LED_R, HIGH);
  }
}

Colocando para funcionar

- Descobrindo o endereço do cartão ou tag

Depois de carregar o código para seu Arduino você deve entrar no monitor serial e verificar a UID de sua tag que esta sendo detectada pelo modulo e esta sendo impressa no monitor serial,  posteriormente você deve substituir a UID que já esta no código para a UID de sua tag. É possível ver na imagem a baixo Duas tag diferentes sendo utilizadas, sendo que uma delas não esta cadastrada.

Descobrindo a ID do cartão.

- Projeto com Cartão cadastrado

Resultado final.


Entendendo a fundo

Software

– Incluindo as bibliotecas a serem utilizadas no projeto

Inicialmente, observe que foi necessário incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca SPI.h é a responsável pela comunicação utilizando o protocolo SPI enquanto a biblioteca MFRC522.h atua sobre a biblioteca SPI.h simplificando o processo de comunicação através do protocolo citado, para que assim, o usuário possa utilizar o Módulo Leitor RFID-RC522 de maneira mais fácil.

#include <SPI.h> 
#include <MFRC522.h>

– Nomeando os pinos de entrada e saída através da diretiva #define

Em seguida, utilizamos a diretiva #define para associar os pinos digitais 10 e 9 para serem usado na comunicação SPI. Também nomeamos o pinos digitais que serão usados para acionar os LED's.

#define SS_PIN 10 
#define RST_PIN 9 
#define LED_R 2   //LED Vermelho 
#define LED_G 3   //LED Verde

Vale ressaltar que isso é apenas um recurso para facilitar a didática da programação, portanto, não obrigatório.

– Declarando o objeto mfrc522

Em seguida, cria-se o objeto chamado  que irá representar o módulo RFID

Lembre-se:mfrc522 é apenas um nome que escolhemos, sendo assim, é importante ressaltar que, o objeto identificado por mfrc522 poderia ser chamado de qualquer outro nome, como por exemplo, moduloRFID.

MFRC522 mfrc522(SS_PIN, RST_PIN);

– Definindo as configurações iniciais

Primeiramente, na função setup(), utiliza-se a função Serial.begin() para inicializar a comunicação serial do Arduino UNO com o computador  (onde será possível ver o resultado do projeto)

Serial.begin(9600);

Em seguida, utiliza-se a função SPI.begin() para inicializar a comunicação.

// Inicia SPI bus 
SPI.begin();

Posteriormente, recorre-se à função mfrc522.PCD_Init() para inicializar o RFID-MFRC522.

// Inicia MFRC522 
mfrc522.PCD_Init();

A função mfrc522.PICC_IsNewCardPresent() inserida dentro de um laço de repetição, faz com que o modulo fique buscando por um novo cartão a ser lido.

// Busca novos cartões 
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }

Suscetivamente a função mfrc522.PICC_ReadCardSerial() tem como objetivo ler a TAG ler o cartão que foi encontrado anteriormente.

// Seleciona um catão a ser lido
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

Esta parte do código tem como finalidade imprimir no monitor serial a UID da TAG que foi lido.

 //Mostra ID na serial
  Serial.print("ID da tag:");
  String conteudo = "";
  byte letra;
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    conteudo.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    conteudo.concat(String(mfrc522.uid.uidByte[i], HEX));
  }

Aqui é onde você define a UID do seu cartão/tag if (conteudo.substring(1) == "Sua tag"), onde no código é usada como exemplo a seguinte TAG: 75 25 17 CB.

Nesta parte também é onde esta definida a função do projeto, em nosso caso, quando o tag for lido o LED verde deve se acender para sinalizar que o acesso foi autorizado.

É importante ressaltar que caso queira registrar mais de uma tag você deve copiar o código a partir do if e posteriormente registrar a UID da nova tag.

Serial.print("Mensagem : ");
  conteudo.toUpperCase();

  if (conteudo.substring(1) == "75 25 17 CB") //UID CARTÃO
  {
    Serial.println("Acesso autorizado !");
    Serial.println();
    digitalWrite (LED_G, HIGH);
    digitalWrite (LED_R, LOW);
    delay(5000);//Delay apagar LED Verde
    digitalWrite (LED_G, LOW);
    digitalWrite (LED_R, HIGH);
  }

Desafio

  1. Implemente um projeto que imprima em um Display LCD 16x2, ou no monitor serial caso não tenha o LCD, o nome do portador do Cartão;
  2. Faça um controle de ponto identificando o horário de saída e de entrada de uma pessoa usando o RTC DS3231.

Tutoriais vão de ajudar nesses desafios:

Considerações finais

Hoje aprendemos um pouco sobre a tecnologia RFID, e como utilizamos o módulo RFID-RC522 13,56MHz. Comente o que achou da postagem, e compartilhe conosco  como pretende utilizar desta tecnologia em seu projeto.


Shield Ethernet W5100 - Criando um Servidor Web com Arduino

Shield Ethernet W5100 - Primeiros passos na criação de um Servidor Web com Arduino

Em uma das nossas publicações anteriores ensinamos como você deve proceder para criar um Servidor Web com o NodeMCU. Neste tutorial, iremos utilizar um Shield Ethernet W5100 para criar um Servidor Web que terá como função fornecer uma página web contendo informações enviadas pelo Arduino UNO.

Respostar do servidor web - Página feita através do Arduino Uno em conjunto com o Ethernet Shield W5100
Resultado deste projeto.

[toc]

O que é um Servidor Web?

Ao navegarmos pelo gigante universo de possibilidades da internet, podemos não nos dar conta do que existe por trás disso tudo.

A internet é uma união de redes de computadores em nível mundial conversando entre si através de um conjunto próprio de protocolos de comunicação, como por exemplo, o TCP/IP, que por sua vez, consiste em um protocolo para transmissão de informações orientado à conexão, ou seja, cuja função consiste em permitir que as maquinas se comuniquem e gerenciem o estado atual da transmissão.

- Os Servidores

Um dos protagonistas desse universo são os servidores. A grosso modo, esses servidores são computadores responsáveis por fornecer e receber dados dos diversos clientes, atuando como centralizadores de informação.

servidor cliente
Conexão cliente/servidor

Indo um pouco a fundo, um servidor consiste em um software dentro um computador centralizador. Através de uma rede particular ou da internet,  esse servidor pode receber dados de clientes bem como fornecê-los.

O estabelecimento das relações entre o conjunto Servidor/Cliente é baseado em um sistema de recebimento, processamento e resposta, no qual, o servidor recebe, processa e responde a requisições feitas por um Cliente através de algum protocolo de comunicação.

- O HTTP - Protocolo de Transferência de Hipertexto

Um dos principais exemplos da relação Servidor/Cliente é a relação entre os computadores que atuam como servidores hospedando sites e os navegadores que utilizamos em nossos computadores ou celulares, os clientes. Neste tipo de relação, utiliza-se para estabelecer a comunicação, o procotolo o HTTP (Hypertext Transfer Protocol), o qual, é responsável pelo tratamento dos pedidos e respostas entre cliente e servidor na World Wide Web ou em uma rede localNesse contexto, chamamos os servidores de Servidores Web.

Comunicação requisição http servidor web
Utilização do protocolo HTTP.


- HTML - Linguagem de Marcação de Hipertexto

As informações que o Servidor Web envia para seu navegador a partir de uma requisição HTTP feita pelo mesmo, pode ocorrer em alguns determinados formatos que precisarão ser interpretados. Um desses formatos é o HTML (HyperText Markup Language), que por sua vez, é uma linguagem utilizada na construção de páginas na Web.

Por trás de uma Página web
Linguagem HTML.

O Shield Ethernet W5100

Como sabemos, os shields compatíveis com o Arduino UNO são placas de circuito que podem ser conectadas sobre o mesmo, encaixando-se perfeitamente, com o intuito de expandir suas capacidades em determinada vertente.

Neste tutorial, apresentamos o Shield Ethernet W5100, que por sua vez, consiste em um shield dotado de dois módulos, um módulo Ethernet que irá permitir a conexão do Arduino UNO, em um primeiro momento, com uma rede local e um módulo para cartão SD.

Sendo assim, perceba que é perfeitamente possível utilizar este módulo somente para ler/escrever dados em um cartão de memória ou apenas para conectar o Arduino UNO a uma rede local.

Shield Ethernet W5100 servidor web arduino
Shield Ethernet W5100.

Neste tutorial iremos utilizar apenas o módulo Ethernet do shield em questão, pois, iremos elaborar uma pagina simples para ser apresentada ao usuário através do navegador, no entanto, o módulo de cartão SD é muito útil para conter arquivos necessários para a construção de uma página mais rica em informações, como por exemplo, imagens.


Mãos à obra - Criando um Servidor Web com o Arduino UNO e o Shield Ethernet W5100

Nesta seção iremos demonstrar todos os passos que você deve seguir para aprender a criar um Servidor Web.

Componentes necessários

Para reproduzir este projeto, você irá precisar dos seguintes componentes:

Montando o projeto

Shield Ethernet W5100 no Arduino uno
Hardware utilizado.

Gostaríamos de sugerir que você tenha bastante cuidado no momento em que for encaixar o Shield Ethernet W5100 no Arduino UNO, pois, além da possibilidade de entortar os pinos do shield, você também pode se machucar.

Lembre-se que o shield ethernet W5100 possui uma série de pinos em sua parte inferior, tanto nas laterais como em sua parte dianteira, portanto, antes de pressionar o mesmo sobre o Arduino UNO, certifique-se de que os pinos estejam levemente posicionados em suas respectivas entradas para que então você possa ir realizando o encaixe lentamente.

Realizando as conexões

Para reproduzir este projeto, garanta que o seu Shield Ethernet W5100 esteja ligado corretamente a uma das portas LAN presentes no seu modem ou roteador.

Programando

Este programa foi elaborado a partir do código-exemplo da biblioteca Ethernet.h denominado WebServer.

Antes de utilizar este código, leia a seção Entendendo a fundo para adaptar os trechos necessários para o funcionamento da sua aplicação.

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 25, 16); 
EthernetServer server(80);     

void setup() 
{
    Ethernet.begin(mac, ip);  
    server.begin();           
} 

void loop() 
{
    EthernetClient client = server.available();  

    if (client) 
    { 
      
        boolean currentLineIsBlank = true;
        while (client.connected()) 
        {
            if (client.available())
            {   
                char c = client.read(); 
                
                if (c == '\n' && currentLineIsBlank) 
                {
                  
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Connection: close");
                    client.println();
                    client.println("<!DOCTYPE html>");
                    client.println("<html>");
                    client.println("<head>");
                    client.println("<title>Servidor Web VDS</title>");
                    client.println("</head>");
                    client.println("<body>");
                    client.println("<h1>Meu primeiro Servidor Web</h1>");
                    client.println("<p>Esperamos que voce tenha gostado deste tutorial</p>");
                    client.println("</body>");
                    client.println("</html>");
                    break;
                }
                
                if (c == '\n') 
                {
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') 
                {
                    currentLineIsBlank = false;
                }
            } 
        }
        
        delay(1);      
        client.stop(); 
        
    } 
}

Colocando para funcionar

Veja como ficou nosso primeiro Servidor Web.

Respostar do servidor web - Página feita através do Arduino Uno em conjunto com o Shield Ethernet W5100
Página da web criada.

Entendendo a fundo

Software

- Incluindo as bibliotecas a serem utilizadas no projeto

Inicialmente, observe que foi necessário incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca SPI.h é a responsável pela comunicação dos módulos do Shield Ethernet W5100 com o Arduino UNO utilizando o protocolo SPI e a biblioteca Ethernet.h atua possibilitando a conexão do conjunto, em um primeiro momento, com uma rede local.

#include <SPI.h>
#include <Ethernet.h>

- Definindo o endereço MAC do Arduino UNO

O próximo passo consiste em definir o endereço MAC que será atribuído ao Arduino UNO.

Na prática, o endereço MAC pode ser qualquer um, desde que seja único na rede. Como sugestão, copie a sentença abaixo.

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

- Definindo o endereço IP do Arduino UNO

Além do endereço MAC definido anteriormente, torna-se necessário definir um endereço IP para o nosso Arduino UNO. Isso é imprescindível para que seja possível estabelecer a conexão entre o mesmo e a rede.

Este endereço deve estar disponível na sua rede local para que possa ser utilizado

Existem várias maneiras de encontrar um endereço válido na sua rede local, de modo que, demonstraremos uma forma bastante simples de realizar este procedimento, confira abaixo:

  1. Acesse um computador que esteja conectado na sua rede local
  2. Abra o Prompt de Comando do Windows (supondo que o sistema operacional seja Windows)
  3. Digite ipconfig

Neste momento, um conjunto de informações será disponibilizado, no entanto, o dado que requer sua atenção é justamente o endereço IP da máquina que você está utilizando (ele estará apresentado pelo nome IPV4).

Verificando o ip a ser usado pelo ethernet shield w5100

Primeiramente, repare que o endereço IP destacado possui quatro partes separadas por pontos. Para encontrarmos um possível endereço disponível em nossa rede local, basta modificarmos a última parte do endereço encontrado, como por exemplo, o endereço 192.168.25.16 . Geralmente, este procedimento é suficiente para encontrar possíveis endereços disponíveis em redes locais pequenas, como as das nossas casas.

IPAddress ip(192, 168, 25, 16);

- Criando o objeto server

Neste momento, cria-se um objeto chamado server, que por sua vez, será responsável por representar o Servidor Web no código do Arduino UNO.

Note que ao criarmos o objeto, passamos o número 80 como parâmetro, pois estamos determinando a porta que o Servidor Web utilizará para enviar as páginas web que serão criadas posteriormente.

A título de curiosidade, quando digitamos o endereço de algum site no navegador, ele automaticamente procura a porta 80 do servidor no qual está se conectando, de modo que, se o serviço responsável por disponibilizar as páginas da web para o cliente estiver em outra porta, devemos especificar esta no endereço do site citado, por exemplo: www.exemplo.com.br:1234

EthernetServer server(80);

- Iniciando a comunicação com a rede local e o Servidor Web

Na função setup() iniciamos a conexão com a rede local através da função Ethernet.begin() (passando como parâmetro os endereços MAC e IP definidos anteriormente) e também iniciamos o Servidor Web por meio da sentença server.begin() (lembre-se que server é o objeto criado para representar o Servidor Web no código).

Ethernet.begin(mac, ip);
server.begin();  

Veja como ficou nossa função setup():

void setup() 
{
   Ethernet.begin(mac, ip);
   server.begin();
}

- Respondendo as requisições de um navegador

Verificando se existe requisição de conexão

Primeiramente, na função loop(), temos a sentença server.available() que verifica se existe tem algum cliente tentando fazer uma conexão. Como dito anteriormente, vamos chamar de cliente, o navegador que está tentando fazer a conexão com o Servidor Web através do endereço IP do mesmo. Repare que foi criada uma variável para conter o valor retornado pela função server.available().

EthernetClient client = server.available();

Em seguida, temos uma função if() cujo conteúdo será executado apenas no caso de termos um cliente tentando se conectar ao Servidor Web criado e iniciado anteriormente.

if (client)
{
   ***** Conteúdo da função if() *****
}

Supondo que temos um cliente tentando se conectar com o nosso Servidor Web, primeira sentença do conteúdo da função if() apresentada anteriormente consiste na declaração de uma variável de controle booleana que será utilizada na leitura da requisição feita pelo navegador.

boolean currentLineIsBlank = true;

Posteriormente, temos uma função while(), que por sua vez, fará com que a execução do programa fique restrita ao seu conteúdo enquanto o parâmetro passado para mesma for verdadeiro. O parâmetro citado corresponde à sentença client.connected(), responsável por retornar verdadeiro ou falso, caso o cliente esteja conectado ou não com o Servidor Web, respectivamente.

Portanto, enquanto o cliente estiver conectado com o nosso servidor, o programa ficará preso na função while().

while (client.connected())
{
       ***** Conteúdo da função while()
}

Imagine que a conexão do cliente (navegador) com o nosso Servidor Web tenha sido estabelecida. Neste momento o programa irá se preparar para receber a requisição feita pelo cliente, que por sua vez, é dada em forma de um grande texto, logo, utilizamos a função if() juntamente com a sentença client.available() para verificar se ainda existe alguma informação proveniente do navegador para ser lida. Caso exista, o conteúdo desta função será executado.

if (client.available())
{
      ***** Conteúdo da função if() *****
}

Lendo a requisição do cliente

Caso exista alguma informação para ser lida, utilizamos a sentença client.read() para ler caractere por caractere do grande texto de requisição citado anteriormente, de modo que, a cada passagem por esta sentença (lembre-se que isso é feito de maneira cíclica), um novo caractere será armazenado na variável do tipo char c.

 char c = client.read();

Após preenchermos a variável c com um determinado caractere da requisição, fazemos uma série de comparações deste com alguns parâmetros específicos para saber se o Arduino UNO recebeu o pacote de informações inteiro ou não.

O objetivo aqui não é entender tudo que esta vindo do cliente mas simplesmente entender que existe uma solicitação acontecendo e que após o término da mesma, vamos devolver como resposta uma pagina da web, sendo assim, devemos esperar que venha o texto completo de solicitação, até a ultima linha.

Caso a condição desta primeira função de tratamento da variável c seja verdadeira, quer dizer que recebemos o pacote completo e que o conteúdo desta função if() será executado.

if (c == '\n' && currentLineIsBlank)
{
      ***** Conteúdo da função if() *****
}

Enviando informações para o navegador

Neste momento, nós iremos criar as funções necessárias para que o nosso Arduino UNO envie uma página da web como resposta à solicitação do navegador. As instruções que utilizaremos para enviar informações ao navegador serão baseadas na sentença client.println().

Primeiramente, enviamos um cabeçalho padrão informando ao navegador que estamos mandando uma página da web utilizando o protocolo HTTP, feita utilizando a linguagem HTML.

                     client.println("HTTP/1.1 200 OK");
                     client.println("Content-Type: text/html");
                     client.println("Connection: close");  
                     client.println();

- Usando HTML para montar a página web

HTML é uma linguagem, porém, não exatamente uma linguagem de programação mas sim uma linguagem de marcação, ou seja, através desta nós enviamos comandos para um navegador, que por sua vez, irão orientar o mesmo na montagem da pagina.

Uso de tags em HTML

Em um primeiro momento, nós devemos saber que a linguagem HTML é composta por elementos que iremos chamar de tags. Estes consistem em comandos que são enviados para o navegador para informarmos alguma coisa ao mesmo, para pedirmos que ele mostre algo, para definirmos o formato de fonte que queremos, se é negrito, qual cor, entre outros.

Todos as tags em HTML são declaradas entre os sinais de maior e menor <nome_da_tag>. Torna-se importante ressaltar que muitas tags possuem uma abertura e um fechamento (este possui o mesmo nome da tag, porém, com uma "/" antes do respectivo nome, por exemplo, </nome_da_tag>), de modo que, tudo o que está entre a abertura e o fechamento de uma determinada tag será afetado pelo comando gerado pela função da mesma.

A estrutura da página em HTML

Vamos começar a entender a estrutura de uma pagina em HTML. Primeiramente, qualquer pagina em HTML precisa possuir a tag <html> cuja função é indicar para o navegador que estamos começando um bloco de programação utilizando a linguagem HTML (opcionalmente podemos utilizar também a tag <!DOCTYPE HTML> para informar o tipo documento, de modo que, se não colocarmos isto, o navegador entenderá da mesma forma) e o fechamento da mesma </html>, que por sua vez, indica o fim do bloco citado.

client.println("<!DOCTYPE HTML>");
client.println("<html>");
           . 
           .
***** Conteúdo da página *****
           .
           .
client.println("</html>"); 
 

Dentro do bloco citado anteriormente, temos o conteúdo da página que queremos enviar para o navegador, de modo que, neste, devemos ter pelo menos dois blocos, um responsável pelas informações gerais do documento, limitado pelo uso do par <head></head> e o outro, por sua vez, deve conter o corpo da página e está entre as tags <body> e </body>.

client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
           .
           .
   ***** Bloco 1 *****
           .
           .
client.println("</head>");
client.println("<body>");
           .
           .
   ***** Bloco 2 *****
           .
           .
client.println("</body>");
client.println("</html>"); 

Definido o título para a página

Neste momento, vamos utilizar apenas uma tag dentro do bloco 1, denominada <title>, cuja função consistirá em definir um título para a página (este título aparecerá na aba do navegador). Para executarmos a ação proposta, devemos colocar o título desejado entre o par <title></title>.

client.println("<!DOCTYPE HTML>");
client.println("<html>");

client.println("<head>");
client.println("<title>Servidor Web VDS</title>"); 
client.println("</head>");

client.println("<body>");
           .
           .
   ***** Bloco 2 *****
           .
           .
client.println("</body>");
client.println("</html>"); 

Veja como ficou o título da nossa página:

endereço IP do servidor web
Título da página.

Escrevendo o corpo da página web

Quanto ao corpo da página, a primeira coisa que faremos será colocar um título visível na própria página. Para realizar este procedimento, utilizaremos a tag <h1>, que por sua vez, consiste em uma tag de cabeçalho, cuja função consiste em apresentar um determinado texto em um modelo predefinido. Lembre-se que os textos que tiverem fora do par <h1></h1> serão apresentados fora do padrão citado.

client.println("<!DOCTYPE HTML>");
client.println("<html>");

client.println("<head>");
client.println("<title>Servidor Web VDS</title>"); 
client.println("</head>");

client.println("<body>");
client.println("<h1>Meu primeiro Servidor Web</h1>");  
client.println("</body>");

client.println("</html>");

Veja como está nossa página até agora

Shield Ethernet W5100 - tela acessada via navegardor
Primeiro texto da página.

Opções de cabeçalhos

Devemos ressaltar que não há nenhum problema em utilizar vários cabeçalhos iguais, portanto, você pode tranquilamente criar vários textos utilizando o cabeçalho h1, pois, ele apenas indica uma certa formatação. Além do cabeçalho que já utilizamos, temos também os cabeçalhos h2,h3,h4,h5,h6, os quais, nesta ordem, possuem fontes cada vez menores.

Escrevendo um texto simples

Por fim, utilizaremos uma tag voltada para a escrita de textos simples. Esta pode ser referenciada no código pelo par <p></p>.

client.println("<!DOCTYPE HTML>");
client.println("<html>");

client.println("<head>");
client.println("<title>Servidor Web VDS</title>"); 
client.println("</head>");

client.println("<body>");
client.println("<h1>Meu primeiro Servidor Web</h1>");  
client.println("<p>Esperamos que voce tenha gostado deste tutorial</p>");
client.println("</body>");

client.println("</html>"); 

Veja nosso resultado final:

Página da web criada.

- Verificando se a requisição foi finalizada

Após o desenvolvimento da nossa página, saímos da função if() utilizada para saber se a requisição foi finalizada e encontramos outras duas funções if() que cumprem o teste das condições não contempladas pela primeira, ou seja, atuam no tratamento da variável enquanto a requisição não foi finalizada.

if (c == '\n') 
{
    currentLineIsBlank = true; 
} 
else if (c != '\r')
{
    currentLineIsBlank = false;
}

Por fim utilizamos a função delay() para garantir que o navegador receba esta informação que estamos mandando e também a sentença client.stop() para parar a conexão.

delay(1);     
client.stop();

Considerações finais

Neste tutorial, demonstramos como você pode dar os primeiros passos na criação de um Servidor Web utilizando um Arduino UNO e um Shield Ethernet W5100. Esta foi apenas a primeira parte de uma série de artigos sobre a criação de Servidores Web, portanto, esperamos que continue nos acompanhando e sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.


Sensor de umidade do solo com Arduino - Higrômetro

Sensor de umidade do solo com Arduino - Higrômetro

Neste tutorial daremos o primeiro passo para desenvolver um sistema inteligente voltado para o monitoramento e controle das variáveis existentes em uma plantação. Começaremos aprendendo como usar o sensor de umidade do solo, também chamado de Higrômetro, em conjunto com um Arduino Nano.

[toc]

Sistemas automáticos na Agricultura

Plantas precisam de um solo de boa qualidade para crescerem de forma saudável e com qualidade, porém, existem vários tipos de situações ambientais que dificultam o seu crescimento, sendo algumas delas:

  • Irradiação solar excessiva;
  • Falta de nutrientes no solo;
  • Solo com baixa umidade;
  • Pragas;
  • Entre outros.

Todas as situações descritas anteriormente podem gerar prejuízo. Por este motivo, faz-se necessária a utilização de, sistemas automáticos os quais vêm sendo cada vez mais explorados que auxiliem o agricultor no monitoramento de seus cultivos visando obter uma eficiência cada vez maior e consequentemente a redução da ocorrência de situações indesejadas

Sensor umidade do solo - Higrômetro

Neste tutorial, iremos utilizar o sensor de umidade do solo, para aferir a condutividade do solo através de uma haste com dois eletrodos existentes no mesmo. O princípio de funcionamento deste circuito é bem simples, pois, resume-se ao fato de que, através da aplicação de uma determinada corrente X nos eletrodos citados, é possível estimar o quão úmido ou seco o solo estará em virtude da condutividade do solo em ambos os casos. Basicamente, quando o solo estiver úmido, teremos uma condutividade melhor devido a absorção da água e isso resultará em um fluxo maior de corrente entre os dois eletrodos. Entretanto se o solo estiver seco, teremos pouca ou até nenhuma corrente entre os eletrodos.

O sensor é composto basicamente duas hastes que ficaram presas ao solo que iremos monitorar e um circuito comparador que irá nos retornar o nível de condutividade do solo. Este circuito é composto por um total de 6 pinos, sendo dois destes utilizados para conectar a haste de metal ao circuito de comparação. As outras 4 entradas possuem as funções de alimentar o circuito e retornar o nível de umidade do solo.

A determinação do nível de umidade do solo pode ser feita de duas formas, sendo elas:

  • Um sinal digital que basicamente informa se o solo está seco ou não ( Menor precisão, porém não depende de um circuito ADC )
  • Um sinal analógico que pode ser utilizado para estimar o quão úmido o solo está ( Maior precisão, porém dependerá de um circuito ADC )
Sensor de umidade do solo com Arduino Higrômetro
Sensor de umidade do solo - Higrômetro

Especificações do dispositivo

  • Tensão de Operação: 3,3-5v
  • Sensibilidade ajustável via potenciômetro
  • Saída Digital TTL (D0) e Analógica(A0)
  • Led indicador de detecção de umidade

Mãos à Obra - Medindo a umidade do solo utilizando o Arduino - Higrômetro

Componentes utilizados

Montando o projeto

Nesta primeira parte do tutorial, iremos apenas conectar o sensor de umidade, desta forma,  iremos utilizar o seguinte esquema de ligação:

Mapa de ligação dos pinos

A montagem final do nosso sistema deve ser semelhante ao modelo abaixo

Sensor de umidade do solo com Arduino Higrômetro
Diagrama de montagem do sensor de umidade do solo - Higrômetro

Veja só como ficou o nosso sistema inicial.

Sensor de umidade do solo com Arduino Higrômetro
Montagem do circuito - sensor de umidade do solo - Higrômetro

Antes de ligar o seu circuito, verifique se todas as conexões foram feitas corretamente. Um curto circuito causado por uma ligação errada pode danificar todo o seu projeto.

Programando

Com a parte física do nosso projeto montada, iremos agora partir para a parte de codificação do sistema. Nesta primeira versão não iremos utilizar nenhuma biblioteca em especial, porém iremos utilizar funções para leitura de dados analógicos e também iremos construir o nosso sistema de leituras de uma forma um pouco diferente como pode ser visto no código abaixo:

/* Nome: Sistema de aferição de umidade de solo - Higrômetro
 * Feito por: Danilo Almeida
 * Data: 7/11/2017
 */
#define sensorUmidade A0 // Sensor de umidade de solo do módulo
unsigned long tempoAnterior = 0; // Variável utilizada para guardar o tempo anterior
unsigned long intervalo = 1000; // Intervalo de tempo em MS para cada leituraa
void setup() {
  Serial.begin(9600); // Inicialização da comunicação serial

}
void loop() {
  unsigned long tempoAtual = millis(); // Realizamos a leitura atual do tempo em que o nosso Arduino Nano está ligado
  if (tempoAtual-tempoAnterior > intervalo){ // Pequena lógica para realizar leituras temporizadas sem parar o microcontrolador
      tempoAnterior =tempoAtual; // Guardamos o tempo anterior como o ultimo intervalo de tempo lido
      int leitura = analogRead(sensorUmidade); // Leitura dos dados analógicos vindos do sensor de umidade de solo

      if (leitura<=1023 && leitura>=682){ // Se a leitura feita for um valor entre 1023 e 682 podemos definir que o solo está com uma baixa condutividade, logo a planta deve ser regada
        Serial.println("Nível de Umidade Baixo");
      }else{
        if (leitura<=681 && leitura>=341){ // Se a leitura feita for um valor entre 681 e 341 podemos definir que o solo está com um nível médio de umidade, logo dependendo da planta pode ou não ser vantajoso regar
        Serial.println("Nível de Umidade Médio");
        }
        else{
          if (leitura<=340 && leitura>=0){ // Se a leitura feita for um valor entre 0 e 340 podemos definir que o solo está com um nível aceitável de umidade, logo talvez não seja interessante regar neste momento
            Serial.println("Nível de Umidade Alto");
          }
        } 
      }
  }
}

Entendendo a Fundo

Software

- Definições e variáveis utilizadas no projeto

Inicialmente definimos todas as variáveis que iremos utilizar tanto para controlar as leituras que serão efetuadas quanto para realizar a leitura da entrada analógica do  sistema. Neste trecho de código definimos as variáveis  intervalo, tempoAnterior e criamos uma definição para o pino A0 do Arduino com o nome de sensorUmidade.

#define sensorUmidade A0 // Sensor de umidade de solo do módulo
unsigned long tempoAnterior = 0; // Variável utilizada para guardar o tempo anterior
unsigned long intervalo = 1000; // Intervalo de tempo em MS para cada leitura

- Função Setup - Inicialização da comunicação serial

Nesta primeira versão, iremos apenas verificar o nível de umidade do solo e com base nesta medição informar se o solo está úmido ou não. Para isso iremos utilizar a comunicação serial. Logo neste trecho de código basicamente inicializamos a comunicação serial do nosso Arduino.

void setup() {
  Serial.begin(9600); // Inicialização da comunicação serial

}

- Função Loop - Usando a função millis para contar o tempo

Nossa função loop tem como objetivo realizar o processo de leitura dentro de cada  intervalo de tempo definido na variável intervalo, porém diferente de como fazemos na maioria das implementações, não iremos utilizar o comando delay para sincronizar cada leitura realizada. Isso ocorre pois o comando  delay "congela" o microcontrolador o impedindo de executar outras ações, como por exemplo ler um outro sensor, ou receber dados da porta serial. Com isso neste projeto iremos utilizar a função millis para sincronizar as leituras e não "congelar"o microcontrolador, possibilitando assim com que ele faça outras tarefas enquanto aguarda o tempo de realizar uma nova leitura.

O processo de sincronizar a leitura de forma não bloqueante é feito de uma maneira bem simples:

  1. Inicialmente armazenamos o tempo atual ( que é retornado pela função millis ).
      unsigned long tempoAtual = millis(); // Realizamos a leitura atual do tempo em que o nosso Arduino Nano está ligado
    
  2. Com o tempo atual do microcontrolador armazenado, iremos agora realizar uma operação de subtração entre o tempo atual lido e o último tempo que armazenamos.
    if (tempoAtual-tempoAnterior > intervalo)
  3. Se a subtração entre o tempo atual do microcontrolador e o último tempo armazenado for maior que o intervalo de tempo para cada leitura, significa que já  é hora de realizar a leitura desejada, porém antes devo atualizar o meu tempo anterior já que realizei uma leitura.
    tempoAnterior =tempoAtual; // Guardamos o tempo anterior como o ultimo intervalo de tempo lido
    
  4.  Recomeçamos o processo no passo 1

- Leitura do nosso medidor de umidade de solo

Agora iremos realizar a leitura do nosso sensor de umidade de solo através da porta A0, esta leitura é feita através da função analogRead como mostra o código abaixo:

      int leitura = analogRead(sensorUmidade); // Leitura dos dados analógicos vindos do sensor de umidade

Esta função basicamente retorna um valor numérico entre 0 e 1023, que representa o valor tem Volts lido do sensor de umidade. O valor está entre 0 e 1023 devido a resolução do circuito ADC que já vem integrado ao Arduíno, se você precisar de uma resolução maior, pode também utilizar circuitos ADC's dedicados.

- Tomada de decisão baseada no valor medido pelo sensor de umidade

Já por fim ( porém não menos importante ), iremos mostrar através da porta serial, em qual intervalo de valores a sua leitura está contida. Para isso, basicamente dividimos o valor da resolução máxima do circuito ADC do Arduino 1024 valores por três, o que resulta em três estados chamados: umidade baixa, umidade média, umidade alta.

      if (leitura<=1023 && leitura>=682){ // Se a leitura feita for um valor entre 1023 e 682 podemos definir que o solo está com uma baixa condutividade, logo a planta deve ser regada
        Serial.println("Nível de Umidade Baixo");
      }else{
        if (leitura<=681 && leitura>=341){ // Se a leitura feita for um valor entre 681 e 341 podemos definir que o solo está com um nível médio de umidade, logo dependendo da planta pode ou não ser vantajoso regar
        Serial.println("Nível de Umidade Médio");
        }
        else{
          if (leitura<=340 && leitura>=0){ // Se a leitura feita for um valor entre 0 e 340 podemos definir que o solo está com um nível aceitável de umidade, logo talvez não seja interessante regar neste momento
            Serial.println("Nível de Umidade Alto");
          }
        } 
      }

Desafio

Agora que temos o nosso projeto montado e funcionando tente melhorar um pouco o nível de medição do sistema. Divida o valor máximo do conversor ADC por um valor maior que três e crie mais ifs para que você seja capaz de identificar melhor o nível de umidade do solo.

Considerações Finais

Este tutorial teve como objetivo apresentar e ilustrar o funcionamento do sensor de umidade do solo, que por sua vez, tem uma aplicação bastante interessante e importante que é identificar em qual momento uma planta deve ser regada, para que dessa forma ela tenha uma qualidade de vida melhor e seja capaz de produzir e aumentar a qualidade de sua produção. Como dito anteriormente, este projeto será uma série onde iremos construir um sistema de monitoramento em tempo real do solo e do ambiente onde nossa plantação está. Espero que tenham gostado do conteúdo apresentado, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.


SCT-013 - Sensor de Corrente Alternada com Arduino

SCT-013 - Sensor de Corrente Alternada com Arduino

Neste tutorial ensinaremos a você como medir corrente alternada e estipular a potência instantânea de um circuito utilizando o Sensor de corrente alternada não invasivo SCT-013 juntamente com Arduino. Para este projeto, iremos medir a corrente e a potência de um ferro de solda.

Esse tutorial é dividido em três partes.

  1. Introdução: Nessa parte você conhecerá um pouco mais o sensor SCT013
  2. Mãos à obra: Aqui você aprenderá a usar o Sensor de corrente SCT-013 na prática
  3. Entendendo a fundo: Por fim você entenderá como funciona o software e hardware usado na experiência da parte 2

[toc]

Sensor de corrente não invasivo SCT-013

O sensor de corrente SCT-013 é muito versátil e tem como principal vantagem o fato de não precisar de contato elétrico com o circuito para medir a corrente elétrica alternada. Ou seja, não precisamos abrir o circuito para ligá-lo em série com a carga, basta apenas "abraçar" um dos fios ligados ao equipamento a ser monitorado.

SCT013 sensor de corrente ac
Sensor de corrente SCT013

Um pouco de física

Para fazer a medição da corrente sem a necessidade de contato elétrico com o circuito esse sensor de corrente alternada utiliza as propriedades magnéticas da corrente elétrica.

- Lei de Ampère

A Lei de Ampère diz que todo condutor por onde flui uma corrente elétrica induz ao seu redor um campo magnético proporcional à corrente.

Linhas de campo geradas pela corrente elétrica
Linhas de campo geradas pela corrente elétrica

- Corrente Alternada

A corrente alternada tem uma peculiaridade de se comportar como uma senoide, sendo assim sua intensidade varia ao longo do tempo indo do máximo positivo ao máximo negativo. Esse comportamento oscilatório tem uma frequência que pode ser de 50Hz ou de 60Hz conforme o país ou região. No Brasil é adotado a frequência de 60Hz, ou seja: a corrente elétrica varia entre positivo e negativo 60 vezes em 1 segundo.

Corrente Alternada
Corrente Alternada

Como o campo magnético é proporcional ao valor de corrente, o campo magnético gerado ao redor do condutor percorrido por uma corrente alternada irá variar ao logo do tempo conforme a variação da mesma.

- Lei de Faraday - lei da indução eletromagnética

A lei de Faraday diz que um campo magnético que varia ao longo do tempo induz em uma espira uma força eletromotriz que gera um corrente elétrica proporcional a intensidade do campo magnético.

Lei de Faraday
Lei de Faraday

Na figura acima podemos entender essa lei na prática. Veja que ao aproximar o imã das espiras estamos variando o campo magnético e está sendo indicado uma tensão no voltímetro (força eletromotriz) chegando quase a 20V. Depois, ao afastar o imã temos a tensão indo quase a 20V no sentido contrário.

- Resumo

  1. Lei de Ampère: Um condutor percorrido por uma corrente induz a formação de um campo magnético ao seu redor de valor proporcional à corrente;
  2. Corrente Alternada: A corrente alternada varia ao longo do tempo gerando um campo magnético também variante ao longo do tempo;
  3. Lei da indução de Faraday: Um campo magnético variante no tempo induz numa espira uma tensão, e por consequência um corrente elétrica, proporcional à intensidade do campo magnético

Levando em conta essas três propriedades, podemos montar um transformador de corrente.

Transformadores de corrente

Existe uma grande gama de sensores de corrente que usam essas propriedades magnéticas. Esse sensores são conhecidos com TC (Transformador de Corrente), que em inglês é CT (Current Transformer).

Um transformador de corrente, nada mais é que um conjunto de espiras que são colocadas ao redor de um condutor ao qual queremos medir a corrente. O transformador de corrente (TC) terá em seus polos uma corrente alternada induzida Is, que é proporcional a corrente alternada Ic que percorre o condutor ao qual pretendemos medir a corrente elétrica.

 Esquema para exemplificar o SCT-013
Esquema para exemplificar o SCT-013

A corrente induzida no TC também será inversamente proporcional ao número de espiras de sua bobina.

Esse sensores são divididos em 2 modelos: Os split-core (núcleo dividido) e os solid-core (núcleo sólido).

Solid-core CT - Transformador de núcleo sólido ou núcleo anel - Não possui possibilidade de abertura
Split-core CT - Transformador de corrente de núcleo dividido - Permite a abertura

Transformador de corrente SCT-013

SCT é a sigla para Split-core Current Transformer, ou seja, Transformador de corrente de núcleo dividido. Para fazer fazer a medição da corrente elétrica o SCT-013 possui uma bobina interna em sua estrutura, como podemos ver na figura abaixo.

Bobina do Sensor de corrente não invasivo SCT-013
Bobina do Sensor de corrente não invasivo SCT013

Podemos ver essa bobina com mais detalhes na foto a seguir

Dentro do Sensor de corrente SCT-013
Dentro do Sensor de corrente SCT013

O circuito é bem simples:

Circuito interno do SCT-013
Circuito interno do SCT-013

- Os Modelos de SCT-013

Com base nesse princípio de funcionamento, foram criados diferentes tipos de sensores não-invasivos, como pode ser observado em seu datasheet, com o objetivo de atenderem os mais diversos cenários, de forma que não exista um "melhor", mas sim o mais recomendado para a aplicação recorrente.

Tabela com os diferentes modelos do sensor de corrente não-invasivo

As duas principais diferenças são a Corrente eficaz máxima a ser medida (Input current) -  e o Tipo de saída do sensor (Output type).

É possível observar que somente o modelo SCT-013-000 apresenta uma variação de corrente em sua saída de 0-50mA, já os outros modelos apresentam uma variação tensão de 0-1V, onde por meio destas variações é possível mensurar a corrente elétrica.

Para sabermos qual será a taxa variação tanto de corrente quanto de tensão basta dividirmos o valor máximo  da saída pelo valor máximo a ser medido. Abaixo temos alguns exemplos deste cálculo:

  • SCT-013-000:
    • 0,05 / 100 = 0,5mA. A cada um Ampere a mais ou a menos, sua saída será de 0,5mA para mais ou a menos;
  • SCT-013-005:
    • 1 / 5 = 0,2V. A cada um Ampere a mais ou a menos, sua saída será de 0,2V para mais ou a menos;
  • SCT-013-050:
    • 1 / 50 = 0,02V. A cada um Ampere a mais ou a menos, sua saída será de 0,02V para mais ou a menos.

- SCT-013-000 - 100A / 0-50mA

Para esse tutorial usaremos o SCT-013-000. Ele poder medir valores de 0 até 100A de corrente alternada. Em sua saída teremos valores entre 0 a 50mA proporcionais ao valor de corrente percorrido no condutor principal.

Como nosso Arduino só lê valores de tensão, iremos precisar montar um circuito auxiliar para que essa corrente percorra um resistor e assim possamos converter os valores de correntes gerado pelo sensor em valores de tensão. Explicaremos o passo a passo de como dimensionar esse circuito no tópico Entendendo o Hardware.


Mãos à Obra - Monitorando a corrente AC com o Sensor de corrente SCT-013

Componentes necessários

Serão necessários os seguintes componentes para a execução deste projeto:

Utilizaremos o SCT-013 100A e o Arduino Uno, além de um aparelho que terá sua corrente elétrica medida, no nosso caso, um ferro de solda. Você poderá medir a corrente elétrica de outros dispositivos.

O resistor de 330Ω foi dimensionado por meio de uma sequência de cálculos com o propósito de aumentar a precisão das medidas deste sensor de corrente. Os cálculos poderão ser visto na sessão "Entendendo o SCT-013".

*Caso o seu SCT-013 seja de outro modelo ao invés de 100A, o passo a passo será diferente.

sct013 sensor de corrente

Montando o projeto

Esse sensor de corrente normalmente vem com um plugue P2 do tipo macho em sua ponta. Para esse tutorial nós removemos ele e conectamos os dois fios presentes no interior do cabo diretamente na protoboard. Caso você não queira remover o plugue P2, recomendamos que você adquira um plugue P2 do tipo fêmea para poder utilizar esse sensor de corrente.

Com os componentes em mãos, montaremos o seguinte circuito na protoboard:

Após realizar esta montagem, é necessário conectar o SCT-013 ao condutor por onde a corrente elétrica a ser medida passará.

AVISO: Não conecte este sensor de corrente de acordo com a imagem abaixo, pois não será possível medir a corrente elétrica. A explicação do por quê será feita mais abaixo.

Como a corrente elétrica produz campo magnético conforme seu sentido e o sentido da corrente em um fio é o oposto ao sentido do outro fio, os campos magnéticos produzido pelos dois acabam se anulando. Se não há campo magnético, não há indução magnética no transformador do sensor de corrente, fazendo com que não circule a corrente Is necessária para a medição da corrente Ic consumida. Por esse motivo não podemos conectar este sensor aos dois fios de alimentação.

Com isso finalizamos o hardware do nosso projeto. Agora, bora programar!

Programando

- Bibliotecas necessária

É necessário baixar a biblioteca EmonLib (download). Após baixar, descompacte e mova para a pasta libraries da IDE do Arduino. A EmonLib será utilizada para nos auxiliar a calcular o valor da corrente elétrica consumida.

- Código utilizado

Para sabermos quantos Amperes estão passando pelo condutor, basta realizar a seguinte programação:

#include "EmonLib.h"

EnergyMonitor SCT013;

int pinSCT = A0;   //Pino analógico conectado ao SCT-013

int tensao = 127;
int potencia;

void setup()
{
    SCT013.current(pinSCT, 6.0606);

    Serial.begin(9600);
}

void loop()
{
    double Irms = SCT013.calcIrms(1480);   // Calcula o valor da Corrente
    
    potencia = Irms * tensao;          // Calcula o valor da Potencia Instantanea    

    Serial.print("Corrente = ");
    Serial.print(Irms);
    Serial.println(" A");
    
    Serial.print("Potencia = ");
    Serial.print(potencia);
    Serial.println(" W");
   
    delay(500);

    Serial.print(".");
    delay(500);
    Serial.print(".");
    delay(500);
    Serial.println(".");
    delay(500);
}

Após compilar e enviar o código ao Arduino, os valores de corrente elétrica e potência instantânea serão mostrados no Monitor Serial da IDE do Arduino, e serão atualizados a cada 2 segundos.

Colocando para funcionar

Código compilado e circuito montado! Veja abaixo o resultado.

Circuito montado na prática
Circuito montado na prática
Monitor Serial aberto

Entendendo a fundo

Software

– Incluindo as bibliotecas a serem utilizadas no projeto

Inicialmente, observe que foi necessário incluir uma biblioteca no código para que o mesmo pudesse funcionar corretamente. A biblioteca EmonLib.h é a responsável por realizar os cálculos para encontrar o valor eficaz da corrente a ser medida, baseando-se nas amostras colhidas no pinSCT.

#include "EmonLib.h"

– Declarando o objeto SCT013

Em seguida, cria-se um objeto que será utilizado posteriormente para representar o sensor de corrente SCT-013 no código.

Lembre-se: SCT013 é apenas um nome, sendo assim, é importante ressaltar que este objeto poderia ser chamado por qualquer outro nome, como por exemplo, sensorSCT.

EnergyMonitor SCT013;

– Definindo as configurações iniciais

Declaramos pinSCT = A0 para poder facilitar e tornar intuitivo o uso da porta analógica do arduino.

int pinSCT = A0;    //Pino analógico conectado ao SCT-013

Declaramos duas variáveis, uma chamada Tensao, e atribuímos o valor de 127, que equivale a tensão da rede aqui no nosso estado, e outra chamada Potencia, que será utilizada para reservar o resultado da multiplicação da tensão e da corrente.

int tensao = 127;
int potencia;

No void setup(), chamamos a função SCT013.current(pinSCT, 6.0606) da biblioteca EmonLib, para que seja realizado o cálculo do valor eficaz da corrente, onde ele se baseará nas amostras lidas do pinSCT, e é empregado um valor de calibração de 6.0606 que ensinaremos como encontra-lo mais abaixo.

SCT013.current(pinSCT, 6.0606);

Habilitamos também a comunicação serial entre o arduino e o computador por meio do comando Serial.begin(9600).

Serial.begin(9600);

Caso você tenha dúvidas sobre como utilizar a comunicação serial do arduino, recomendamos que veja o tutorial Comunicação Serial Arduino (clique aqui), presente no portal.

– Aquisição do valor de corrente

Na função void loop(), utiliza-se primeiramente a função SCT013.calcIrms() para atribuir o valor de corrente à variável Irms. O valor entre parênteses representa o número de amostras que a função irá ler do pinSCT.

    double Irms = SCT013.calcIrms(1480);

Veja que SCT013 é o nome que definimos para o objeto. Para usar uma função ligada a esse objeto, colocamos seu nome seguido de ponto e o nome da função. Ex: nomeobjeto.calcIrms().

- Cálculo da potência instantânea

Por meio da multiplicação da corrente Irms pela tensão estipulada, conseguimos descobrir a potência do dispositivo.

    potencia = Irms * tensao;

Em seguida imprimimos o valor de corrente e da potência no monitor serial:

    Serial.print("Corrente = ");
    Serial.print(Irms);
    Serial.println(" A");

    Serial.print("Potencia = ");
    Serial.print(potencia);
    Serial.println(" W");

Esperamos um tempo para a próxima medição.

    delay(500);
    Serial.print(".");
    delay(500);
    Serial.print(".");
    delay(500);
    Serial.println(".");
    delay(500);

Hardware

- Corrente gerada pelo sensor

O sensor é calibrado para medir a corrente alternada máxima de 100A AC. Esse valor de 100A é o valor RMS, que também é chamado de valor eficaz. O valor RMS é igual ao máximo valor que a corrente pode alcançar (corrente de pico) dividido pela raiz quadrada de dois. 

sensor de corrente SCT013

Então, temos que a corrente de pico máxima medida é de 141.4A:

i (medido) = √2 * i (rms) = 1,414 * 100A = 141,4 A

Sabendo que para uma corrente de 100A no primário, ele produz 50mA no secundário, é só jogarmos na fórmula de relação de transformação. O resultado será:

N1 / N2 = I2 / I1

  • I1 = corrente no primário (corrente a ser medida);
  • I2 = corrente no secundário;
  • N1 = número de votas do primário (no caso deste sensor, N1 será igual a 1);
  • N2 = número de voltas do secundário.

N2 = 2000 espiras.

A corrente na saída do sensor é inversamente proporcional ao número de voltas (aqui é 2000):

i (sensor) = i (medido) / numero_de_espiras = 141,4A / 2000 = 0,0707A

Teremos na saída do sensor o sinal da corrente induzida semelhante ao da figura a seguir:

Sinal na saída do sensor de corrente SCT para um valor de corrente eficaz máxima de 100A
Sinal na saída do SCT013 para um valor de corrente eficaz  de 100A

- Transformando corrente em tensão - Calculando a resistência de carga

O Arduino UNO só realiza, em seus pinos de entrada analógica, a leitura de níveis de tensão (entre 0V a 5V). Dessa forma, precisamos converter o sinal de corrente alternada do SCT-013 para um valor de tensão que seja legível para o Arduino.

O primeiro passo é adicionar um resistor de carga entre os polos do sensor de corrente:

Sensor sct013 esquema de ligação

Como a corrente alterna em torno de zero, vamos escolher um resistor que de na saída um valor máximo de tensão de 2,5V.

R(carga) = U(sensor)/I(sensor) = 2,5V / 0,0707A = 35,4Ω

 

O resistor de carga ideal é de 35,4Ω para uma corrente de até 100A, nesse caso usariamos um resistor de 33Ω. Dessa forma teremos o seguinte sinal de tensão sobre o resistor de carga:

Sinal de tensão sobre o resistor de 33
Sinal de tensão sobre o resistor de carga de 33Ω para uma corrente eficaz de 100A

OBS: Para nosso projeto, não iremos medir valores maiores que 10A. Dessa forma, podemos considerar que nossa corrente máxima é 10 vezes menor. Logo:

i (sensor) = i (medido) / numero_de_espiras = 14,14A / 2000 = 0,00707A

R(carga) = U(sensor)/I(sensor) = 2,5V / 0,00707A = 354Ω

Portanto, para nosso projeto adotamos o resistor de 330Ω.

Ou seja, você pode calcular o resistor ideal para a faixa de operação que você precisa. Se for 100A, você pode adotar o de 33Ω, se for de 10A você pode usar um resistor de 330Ω. Para outros valores, basta você calcular.

Seguiremos essa explicação considerando a faixa de operação de 100A, que é o máximo para nosso sensor.

- Convertendo sinal de tensão AC para DC

Agora temos um sinal de tensão alternada variando entre 2,5V positivo e 2,5V negativo. O Arduino não pode medir tensão negativa, então precisamos somar 2,5 V ao sinal para que ele varie entre 0V a 5V.

O primeiro passo para isso é montar um divisor de tensão usando a alimentação de 5V que a placa Arduino fornece.  Assim, consideramos R1 e R2 iguais a 10kΩ, e com isso, a tensão sobre eles será igual, pois os 5V provenientes do Arduino se dividirá igualmente entre eles.

Circuito divisor de tensão
Circuito divisor de tensão

Em seguida adicionamos um capacitor entre o GND e a saída de 2,5V no meio do divisor de tensão:

Circuito de offset

Esse circuito funcionará como uma bateria de 2,5V adicionando essa tensão à fonte AC. Este valor de tensão que acrescentamos a forma de onda é chamado de offset.

Forma de onda da tensão no resistor de carga

 

Forma de onda com offset

Veja como vai fica nosso circuito:

Sensor sct013 esquema de ligação completo

Na figura a seguir mostramos o circuito com seus respectivos sinais:

Como explicado, o circuito de offset funciona como uma fonte tensão de 2,5V DC, somando essa tensão à senoide do SCT-013. O circuito poderia ser ilustrado como a figura a seguir:

- Calibrando o software

Agora que sabemos o sensor carga, modificamos a função SCT013.current onde definimos o pino de entrada e o valor de calibração.

SCT013.current(pinSCT, Valor_de_Calibracao);

Este valor é de calibração, destinado justamente para caso queiramos mudar o valor do resistor de carga. Para descobrir ele, basta dividir o número total de voltas (espiras) do secundário pelo valor do resistor de carga dimensionado:

  • Valor_de_Calibração = 2000 / 33
  • Valor_de_Calibração = 60,606

Dessa forma, teremos:

SCT013.current(pinSCT, 60,606);

obs: Para nosso projeto prático nosso resistor escolhido foi de 330Ω devido ao fato de trabalharmos com uma faixa de operação de 10A. Dessa forma o valor de calibração usado no projeto prático foi de 6,0606.

Valor_de_Calibração = 2000 / 330 = 6,0606

Mudando o range de medição

Calculamos até aqui o valor de uma resistência de carga e valor de calibração do software que possibilita nosso software medir valores de corrente eficazes de até 100A, que é o máximo valor de projeto do sensor. Só que conforme a aplicação, nunca chegaremos a correntes tão altas. Por isso, podemos calibrar nosso software e circuito para ler valores de máxima corrente distintos, desde que estejam dentro do permitido para esse sensor.

Talvez você tenha percebido inclusive que o valor de resistência encontrado em nossos cálculos (33Ω) foi 10 vezes menor que o usada em nossa experiencia (330Ω). Para nosso projeto adotamos uma corrente máxima de 10A, visto que a maiorias dos eletrodomésticos consomem correntes menores que esse valor.

Para calcular a resistência de carga adequada basta repetirmos os seguintes passos:

- Passo 1 - Escolher a corrente rms máxima que será medida pelo circuito

imax (rms) = 10A

- Passo 2 - Converter esta corrente para o valor de pico:

i (medido) = √2 * imax (rms) = 1,414 * 10A = 14,14 A

- Passo 3 - Descobrir o número total de espiras da bobina do secundário:

Sabendo que para uma corrente de 100A no primário, ele produz 50mA no secundário, é só jogarmos na fórmula de relação de transformação. O resultado será:

N1 / N2 = I2 / I1

  • I1 = corrente no primário (corrente a ser medida);
  • I2 = corrente no secundário;
  • N1 = número de votas do primário (no caso deste sensor, N1 será igual a 1);
  • N2 = número de voltas do secundário.

N2 = 2000 espiras.

- Passo 4 - Calcular a corrente de pico máxima do secundário do SCT-013:

i (sensor) = i (medido) / numero_de_espiras = 14,14A / 2000 = 0,00707A

- Passo 5 - Dimensionar o resistor de carga:

R(carga) = U(sensor)/I(sensor) = 2,5V / 0,00707A = 354Ω

Para o projeto, arredondamos este valor para 330Ω, que é um valor comercial de resistor.

R(carga) = 330Ω

- Passo 6 - Colocando o valor de calibração no software:

Agora que sabemos o sensor carga, modificamos a função SCT013.current onde definimos o pino de entrada e o valor de calibração.

SCT013.current(pinSCT, Valor_de_Calibracao);

Este valor é de calibração, destinado justamente para caso queiramos mudar o valor do resistor de carga. Para descobrir ele, basta dividir o número total de voltas (espiras) do secundário pelo valor do resistor de carga dimensionado:

Valor_de_Calibração = N2 / R(carga)

Valor_de_Calibração = 2000 / 330

Valor_de_Calibração = 06,0606

Dessa forma, teremos:

SCT013.current(pinSCT, 6.0606);

 

Pronto, agora você sabe como adaptar o hardware para o seu projeto.


Desafio

Desenvolva um projeto em que seja possível medir a potência requisitada por um determinado equipamento. Para isto, utilize o sensor de corrente SCT-013 (tratado com detalhes neste material) em conjunto com, por exemplo, o sensor de tensão GBK P8.

Considerações finais

Esperamos que este tutorial tenha esclarecido algumas dúvidas sobre os procedimentos necessários para realizar monitoramento das correntes elétricas utilizadas nos acionamentos dos seus equipamentos. Obrigado pela atenção e continue buscando conhecimento no portal do Vida de Silício.


Módulo Bluetooth HC-06 e HC-05 – Arduino

Módulo Bluetooth HC-05 e HC-06 – Acionando um módulo relé via Bluetooth

Dentre os mais diversos protocolos de comunicação atuais, o Bluetooth certamente é um dos mais populares. Sendo assim, neste tutorial, iremos aprender como montar um projeto com uma placa Arduino, usando um smartphone para ligar e desligar uma pequena bomba submersa com o auxílio de um módulo relé e do módulo Bluetooth HC-06 / HC-05 . Para estabelecer a comunicação entre nosso smartphone e o Arduino, iremos utilizar o aplicativo Bluetooth Controller. O aplicativo possui uma interface simples, onde com uma configuração básica seremos capazes de controlar o nosso módulo relé.

[toc]

A importância de um sistema de comunicação sem fio

Sistemas automáticos precisam de meios para interagir com o usuário ou com outros sistemas, de modo que, isso faz da comunicação um assunto muito importante quando estamos tratando de automação.

Ter uma forma de comunicação sólida em um projeto é muito importante, pois será através dela que iremos estabelecer a interface que permitirá a comunicação entre o usuário e o sistema.

Infelizmente, grande parte dos microcontroladores não possuem uma interface sem fio já embutida e como consequência temos a criação de uma grande dificuldade em projetos onde existe a necessidade de um canal de comunicação sem fio. Com isso, uma solução interessante é o uso do padrão Bluetooth, que é voltado para aplicações de baixo consumo. Um módulo capaz de suprir esta demanda, é o módulo HC-06, que veremos a seguir.

Simbolo do padrão Bluetooth
Simbolo do padrão Bluetooth

Seguindo a linha de raciocínio anterior, o padrão Bluetooth, tem como principais vantagens:

  • Baixo consumo energético
  • Velocidade de transmissão considerável
  • Integração com smartphones
  • Padrões retrocompatíveis

Com todas estas características, podemos considerar que o padrão Bluetooth é de fato um ótimo meio para se transmitir dados de forma fácil e com um baixo custo energético para o sistema. Porém, o padrão tem suas limitações, como:

  • Curto alcance
  • Conexão ponto a ponto ( apenas dois pares podem se comunicar por vez )

Protocolo Bluetooth e o uso com Arduino

Em suas versões mais simples, as placas Arduino não contam com uma conexão Bluetooth nativa. Porém, é possível a aquisição de módulos capazes de estabelecer a conexão e a troca de mensagens entre a sua placa Arduino e um outro dispositivo com interface Bluetooth.

Um módulo com este propósito é o HC-06, este circuito é capaz de abstrair toda a parte da comunicação sem fio necessária para a comunicação bluetooth, fornecendo uma interface serial para que o microcontrolador possa enviar ou receber dados.

Com o uso do Bluetooth, você pode desenvolver uma vasta gama de projetos, como por exemplo:

  • Controlar robôs:
Controlando um robô com módulo Bluetooth HC-05
Controlando um robô usando Bluetooth
  • Automatizar praticamente qualquer coisa que esteja conectada ao seu Arduino
Acendendo um LED usando o módulo Bluetooth HC-05 / HC-06
Acendendo um LED usando o módulo Bluetooth HC-05 / HC-06

Módulo Bluetooth HC-05 e HC-06

Estes módulos utilizam a versão 2 do padrão Bluetooth, que por sua vez, apesar de já estar ultrapassado, ainda é viável em projetos como o que será desenvolvido neste tutorial. Com eles você abstrai toda a parte da comunicação sem fio, bastando enviar os dados via comunicação serial para eles.

Esses módulos são muito semelhantes e para nosso projeto você poderá optar por qualquer um dos dois. A diferença entre eles, além da versão do firmware, é o número de pinos. Geralmente os módulos HC-06 possuem apenas 4 pinos, enquanto que geralmente os módulos HC-05 contam com 6 pinos.

É importante ressaltar que o módulo Bluetooth HC-06 não possui o modo de funcionamento master dessa forma se optar pelo seu uso, o módulo ficará restrito a sempre precisar solicitar uma conexão com o dispositivo para a requisição ou transmissão de dados. Caso tenha a necessidade de um módulo capaz de funcionar tanto no modo master quanto slave, você pode utilizar o módulo Bluetooth HC-05, que é capaz de operar nos dois modos.

- Módulo HC-05

O módulo Bluetooth HC-05, dispõe de 6 pinos de entrada e saída de dados, sendo dois deles para alimentação do sistema, dois para transmissão e recepção de dados via serial e dois para programa-lo em modo master. Logo abaixo temos a especificação do dispositivo:

Módulo Bluetooth HC-05
Módulo Bluetooth HC-05
  • Especificações
    • Bluetooth: 2.0V
    • Tensão de funcionamento: 3.3v~5v
    • Taxa de transmissão: 2Mbps
    • Frequência: 2,4 Ghz
    • Nível lógico: 3.3v
    • Pinos: VCC , GND , TXD , RXD;
    • Perfis suportados: Escravo (slave) e Mestre (master)

- Módulo HC-06

O módulo Bluetooth HC-06, dispõe de apenas 4 pinos de entrada e saída de dados, sendo dois deles para alimentação do sistema, e os outros dois para transmissão e recepção de dados via serial. Logo abaixo temos a especificação do dispositivo:

Módulo Bluetooth HC06
Módulo Bluetooth HC-06
  • Especificações
    • Bluetooth: 2.0V
    • Tensão de funcionamento: 3.3v~5v
    • Taxa de transmissão: 2Mbps
    • Frequência: 2,4 Ghz
    • Nível lógico: 3.3v
    • Pinos: VCC , GND , TXD , RXD;
    • Perfis suportados: Escravo (slave) e Mestre (master)

Módulo Relé

É comum, em projetos de automação, termos que acionar ou desligar dispositivos mediante algum parâmetro tal como a temperatura do ambiente, pressão, ou até mesmo a simples solicitação do usuário. Para que isso seja possível, podemos utilizar um circuito comumente conhecido como relé, que por sua vez, nada mais é do que uma simples chave eletromecânica acionada através de uma bobina em seu interior, permitindo ligar e desligar equipamentos elétricos, através da abertura ou fechamento de seu contato em virtude do fornecimento de energia a esta bobina.

Neste projeto, iremos também utilizar um módulo relé para realizar o acionamento da nossa bomba quando requisitado pelo usuário. Este módulo utiliza apenas três pinos, sendo dois para alimentação (5 Volts) e outro para acionamento.

Módulo Relé 1 canal

Mãos à obra - Acionando um módulo relé utilizando o módulo Bluetooth HC-06 ou HC-05 - Arduino

Como esse projeto irá usar o módulo Bluetooth no modo Slave, poremos usar tanto o HC-05 quanto o HC-06. Para nosso projeto usaremos o HC-06, mas você pode adotar os mesmos procedimentos para o HC-05.

Componentes utilizados

Montando o projeto

A montagem deste projeto, pode ser feita seguindo a seguinte ordem para os fios:

Esquema de montagem no Arduino Uno com HC-05
Esquema de montagem no Arduino Uno com HC-05

A montagem do sistema deve ficar semelhante a imagem abaixo

ATENÇÃO: Tanto o módulo HC-06, quanto o HC-05 utilizam o nível lógico de 3.3 volts, logo para utilizar o pino de transmissão TX, você deve adicionar ao projeto um divisor de tensão, já que o nível lógico do Arduino Uno ( 5 Volts ) pode danificar o seu módulo. Porém como neste tutorial não iremos transmitir informações do arduino para o telefone, não iremos precisar do divisor de tensão.

Esquema de montagem do projeto como módulo Bluetooth HC-06 e módulo relé no Arduino Uno na prática
Projeto montado na prática com Módulo Bluetooth HC-06 e Arduino Uno

Sempre monte seu projeto com a alimentação desligada para evitar possíveis curtos circuitos que podem danificar o seu dispositivo.

Programando

Agora que temos o nosso circuito montado, iremos partir para o código responsável por receber os dados através do Bluetooth e determinar se o relé deve ser acionado ou não. Neste exemplo em especial, não será necessária nenhuma biblioteca de terceiros, ou seja todas as bibliotecas que iremos utilizar já se encontram disponíveis na IDE do Arduino. O código abaixo ilustra todo o processo de funcionamento do nosso sistema:

#include <SoftwareSerial.h>
#define RX 8
#define TX 9
#define RELE 7
SoftwareSerial bluetooth(RX, TX); // RX, TX

void setup() {
  Serial.begin(9600); // Inicializa a serial nativa do Arduino
  pinMode(RELE,OUTPUT); // Inicializamos o pino 7 do relé como output
  digitalWrite(RELE,HIGH); // Inicializa a chave como desligada
  bluetooth.begin(9600); // Inicializa a serial via software (Onde está conectado o nosso módulo bluetooth)
}

void verificaBluetooth(){ // Verifica se existe algum dado a ser lido da serial
  if (bluetooth.available()){ // verifica se existem bytes a serem lidos da porta serial virtual
     char dados = bluetooth.read(); // Lê 1 byte da porta serial
     Serial.print(dados); // Mostra esse dado lido na porta serial
     if (dados=='0'){ // Se o byte lido for igual a 0
       digitalWrite(RELE,HIGH); // Desliga a chave
     }
     else{
        if (dados=='1'){ // Se o byte lido for igual a 1
          digitalWrite(RELE,LOW); // Liga a chave e aciona a bomba
        }
     }
  }
}

void loop (){
  verificaBluetooth();
}

Conectando o celular ao Arduino

Agora que temos o código que irá rodar no Arduino, devemos agora instalar o aplicativo que iremos utilizar no controle da bomba. Para instalar o aplicativo basta seguir os seguintes passos:

  • Na play store pesquisar por Bluetooth Controller, e instalar o aplicativo que está marcado

Bluetooth Controller intalando

instalando o Bluetooth Controller

  • Com o aplicativo instalado, iremos agora criar dois botões que serão utilizados para ligar e desligar a nossa mini bomba submersa, para isso devemos clicar no botão SET KEYS:

Configurando o Bluetooth Controller

  • Ao clicar em SET KEYS, seremos direcionados para a tela onde configuramos os botões q serem utilizados. Neste primeiro caso, iremos configurar apenas dois botões, sendo eles responsáveis por ligar e desligar o relé, o tipo de dado enviado também deverá corresponder ao que o nosso código espera, logo enviaremos 1 quando quisermos que a bomba seja ligada, e 0 quando quisermos que a bomba seja desligada.

configurando as saídas do Bluetooth Controller

  • Agora com todos os botões configurados, iremos buscar o dispositivo que queremos nos conectar, para isso selecionamos a opção SCAN   

Bluetooth Controller

  • Ao clicar no botão SCAN, seremos novamente redirecionados para outra tela, sendo esta no caso para selecionar o dispositivo com o qual desejamos nos conectar. No meu caso o dispositivo se chama Controle rele, porém pode ser que o seu se chame HC-05 ou HC-06 dependendo do qual esteja usando.

Na primeira conexão, você deverá fornecer uma senha para que o pareamento seja feito com sucesso, por padrão esta senha é 1234.

Bluetooth Controller procurando por dispositivos

  • Com a conexão estabelecida, agora podemos ligar e desligar a nossa bomba sem a necessidade de contato direto com ela.

Bluetooth Controller pareado com o Arduino e HC06

Colocando para funcionar


Entendendo a fundo

Software

- Incluindo as bibliotecas necessárias

Neste código, em especial, iremos apenas incluir uma única biblioteca, chamada SoftwareSerial. Neste exemplo iremos simular uma porta serial, através dos pinos 8 e 9 do Arduino, desta forma, mantemos a serial em hardware livre para ser utilizada no debug e gravação do código a ser executado. Essa biblioteca é nativa da IDE Arduino.

#include <SoftwareSerial.h>

- Parâmetros de configuração

Para facilitar o uso dos pinos selecionados para este sistema, iremos definir as seguintes constantes como mostra o código logo abaixo:

#define RX 8 
#define TX 9 
#define RELE 7

- Objeto bluetooth

Como dito anteriormente, iremos utilizar uma biblioteca que simula uma comunicação serial, desta forma evitamos a utilização da serial nativa, que pode ser utilizada posteriormente para depuração do código. O trecho de código abaixo, cria o objeto bluetooth, que será responsável por enviar os dados a serem transmitidos através pelo módulo HC-06. Algo que é importante ressaltar é que o módulo HC-06 abstrai toda a parte de comunicação do usuário, bastando apenas com que ele envie os dados que deseja transmitir utilizando a comunicação serial.

SoftwareSerial bluetooth(RX, TX); // RX, TX

-  Inicializando portas de comunicação e configurando relé para desativado

Na função setup, iremos inicializar as duas portas de comunicação (nativa e a que conectamos o nosso módulo bluetooth), através dos comandos Serial.begin(9600) e bluetooth.begin(9600). Também inicializamos o pino onde o módulo relé está conectado como OUTPUT, e inicializamos o módulo relé no estado HIGH. Algo que também deve ser levado em consideração, é o fato de que este módulo relé, diferente dos outros é ativo no nível lógico LOW, por isso inicializamos ele como HIGH.

void setup() { 
Serial.begin(9600); // Inicializa a serial nativa do arduino 
pinMode(RELE,OUTPUT); // Inicializamos o pino 7 do módulo relé como output 
digitalWrite(RELE,HIGH); // Inicializa a chave como desligada 
bluetooth.begin(9600); // Inicializa a serial via software (Onde está conectado o nosso módulo bluetooth) 
}

- Função Verifica loop

Já na função verificaBluetooth, iremos seguir a seguinte lógica:

  1. Verificamos se existe algum dado a ser lido em nossa serial virtual
    1. Se existir nós iremos ler apenas o primeiro byte desta mensagem através do comando bluetooth.read()
    2. Mostramos este dado lido na tela afim de ver se ele é realmente o que enviamos
    3. Logo em seguida verificamos se este valor é 0
      1. Se o valor for igual a 0 iremos abrir a chave do módulo relé ( desligar a bomba )
      2. Caso seja 1 iremos fechar a chave do módulo relé ( ligar a bomba )
      3. Caso não seja nenhum dos dois casos, iremos manter o sistema como está
void verificaBluetooth(){ // Verifica se existe algum dado a ser lido da serial
  if (bluetooth.available()){ // verifica se existem bytes a serem lidos da porta serial virtual
     char dados = bluetooth.read(); // Lê 1 byte da porta serial
     Serial.print(dados); // Mostra esse dado lido na porta serial
     if (dados=='0'){ // Se o byte lido for igual a 0
       digitalWrite(RELE,HIGH); // Desliga a chave
     }
     else{
        if (dados=='1'){ // Se o byte lido for igual a 1
          digitalWrite(RELE,LOW); // Liga a chave e aciona a bomba
        }
     }
  }
}

Considerações Finais

Este tutorial, teve como objetivo mostrar a utilização do módulo Bluetooth HC-06 e HC-05 no modo slave, em um contexto onde a utilização do Arduino é muito aplicada, que é a automação de equipamentos. Com este código apresentado como base, podem ser criados diversos projetos, como automatização residencial e controle de robôs, utilizando um smartphone. Espero que tenham gostado do conteúdo apresentado, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.

Caso esteja começando com Arduino recomendamos que conheça a Apostila Arduino Básico.


Módulo Cartão micro SD com NodeMCU - Construindo um datalogger

Módulo Cartão micro SD com NodeMCU - Construindo um datalogger

Neste tutorial, iremos desenvolver um datalogger bem simples, voltado ao armazenamento de informações de temperatura e umidade de um ambiente, coletados através de um sensor DHT11, usando um módulo leitor de cartão micro SD ou módulo cartão SD em conjunto com um NodeMCU.

Apesar de usarmos um NodeMCU, esse projeto pode ser facilmente adaptado para outras plataformas como ESP32 ou Arduino.

Você pode conhecer mais sobre o NodeMCU no tutorial: Conhecendo a Família ESP8266

[toc]

Armazenando informações

Ao desenvolver projetos voltados a coleta de informações, iremos precisar armazenar estas informações geradas para uma análise posterior. Se o volume de informações não for muito grande, podemos armazenar estes dados utilizando a própria memória não volátil que grande parte das plataformas já disponibilizam. Porém, dependendo do tempo que o nosso projeto esteja coletando dados, o volume de informação gerada, será tão grande, que não seremos capazes de armazenar todos estes dados apenas utilizando a memória nativa. Com isso, uma solução barata e eficiente, é o uso de cartões SD ou micro SD, que devido ao baixo custo e alta capacidade de armazenamento, permitem que o sistema armazene informações de forma estruturada e fácil.

Módulo micro SD

Para construir o nosso sistema de datalogger, iremos utilizar o módulo leitor cartão micro SD, que irá funcionar como ponte entre o microcontrolador e o cartão SD. A comunicação entre microcontrolador e módulo é feita através do protocolo SPI utilizando um total de 6 pinos, sendo dois para alimentação do circuito e os outros para comunicação.

módulo cartão SD ou módulo cartão micro SD
Módulo cartão micro SD

Sensor de temperatura e umidade DHT11

DHT11 é um sensor básico e de baixo custo que utiliza um termistor e um sensor capacitivo para medir a temperatura e a umidade do ar ambiente. Ele é bem simples de usar mas reque atenção com o tempo entre duas leituras consecutivas, uma vez que é necessário um intervalo de, no mínimo, 1 segundo entre uma leitura e outra.

Sensor de temperatura e umidade DHT11
Sensor de temperatura e umidade DHT11

Mãos à obra - Construindo a estrutura do nosso datalogger

Componentes utilizados

Montando o projeto

Neste projeto, teremos dois módulos conectados ao nosso NodeMCU, com base nisso iremos utilizar a seguinte ordem de conexão dos fios:

A montagem final do sistema, deve estar semelhante a figura abaixo:

Esquema de montagem no NodeMCU com DHT11 e Módulo cartão micro SD
Esquema de montagem no NodeMCU com DHT11 e Módulo cartão micro SD

Veja só como ficou a montagem de todo o circuito:

NodeMCU na prática com DHT11 e Módulo cartão SD
NodeMCU na prática com DHT11 e Módulo cartão micro SD

Antes de ligar o seu circuito, verifique se todas as conexões foram feitas corretamente. Um curto circuito causado por uma ligação errada pode danificar todo o seu projeto.

Programando

- Bibliotecas

Neste tutorial iremos utilizar duas bibliotecas para construir o sistema. Uma dessas bibliotecas SD, já é nativa do arduino logo não precisamos realizar a sua instalação. Já a biblioteca utilizada pelo sensor DHT 11 será necessária a instalação, que pode ser feita da seguinte forma:

  •  Na ide do arduino, navegamos até a opção Sketch, selecionamos a opção Incluir biblioteca e navegamos até a opção Gerenciar Bibliotecas como mostra a figura abaixo:
  • Ao selecionar a opção Gerenciar bibliotecas, será aberto um painel como mostra a figura a seguir:

  • Nesta janela, iremos buscar pela biblioteca DHT sensor library by Adafruit, e realizar seu download/instalação

-  Código utilizado

Agora que temos o nosso sistema montado, e as bibliotecas já instaladas, podemos partir para o código. Observem o código a seguir que utilizaremos como base para o nosso datalogger.

#include "DHT.h"          // Biblioteca Adafruit para sensor de temperatura DHT11
#include <SPI.h>          // Biblioteca de comunicação SPI Nativa
#include <SD.h>           // Biblioteca de comunicação com cartão SD Nativa


#define DHTPIN 0          // Define para o pino D3 do nodeMCU -> D3 
#define DHTTYPE DHT11     // DHT 11 que será utilizado para comunicação 
const int chipSelect = 4; // Constante que indica em qual pino está conectado o Chip Select do módulo de comunicação

DHT dht(DHTPIN, DHTTYPE); // Objeto responsável pela comunicação microcontrolador/sensor
File dataFile;            // Objeto responsável por escrever/Ler do cartão SD

bool cartaoOk = true;

void setup()
{
  Serial.begin(9600);     // Inicialização da porta de comunicação Serial
  dht.begin();            // Inicialização do objeto de comunicação com sensor

  // Se não for possível se comunicar com o cartão SD o código não deve prosseguir
  if (!SD.begin(chipSelect)) {
    Serial.println("Erro na leitura do arquivo não existe um cartão SD ou o módulo está conectado corretamente ?");
    cartaoOk = false;
    return;
  }
}

void loop()
{
  // Caso o cartão esteja ok é criado um arquivo no cartão SD com o nome datalog.csv em modo de escrita
  if (cartaoOk){
      dataFile = SD.open("datalog.csv", FILE_WRITE); 
      Serial.println("Cartão SD Inicializado para escrita :D ");
  }

  //Limpando Variáveis 
  String leitura = "";    // Limpo campo contendo string que será armazenada em arquivo CSV
  float temperatura = 0 ; // Limpo variável de temperatura a cada nova leitura
  float umidade = 0;      // Limpo variável de umidade a cada nova leitura

  //Leitura do sensor
  temperatura = dht.readTemperature(); // Função que realiza a leitura da temperatura do sensor dht11
  umidade = dht.readHumidity();        // Função que realiza a leitura da umidade do sensor dht11
 
  // Caso os valores lidos do sensor não sejam válidos executamos as seguintes linhas
  if (isnan(temperatura) || isnan(umidade)){ 
    Serial.println ("Falha na leitura do sensor");  // Informar ao usuário que houve uma falha na leitura do sensor
    delay(1500);    // Aguardamos 1,5 segundos
    return ;        // Retornamos a função para o seu ponto inicial
  }

  // Se tudo estiver ok, escrevemos os dados a serem armazenados em uma String
  leitura = String(millis()) + ";" + String(temperatura) + ";" + String(umidade) + ";"; 

  // Se o arquivo estiver realmente aberto para leitura executamos as seguintes linhas de código
  if (dataFile) {   
    Serial.println(leitura);    // Mostramos no monitor a linha que será escrita
    dataFile.println(leitura);  // Escrevemos no arquivos e pulamos uma linha
    dataFile.close();           // Fechamos o arquivo
  }

  delay(1500); // Aguardamos 1,5 segundos para executar o loop novamente
}

Colocando pra funcionar

Se tudo estiver montado corretamente, o nosso sistema já deve estar funcionando e coletando informações sobre a temperatura e umidade do ambiente. Uma coisa interessante, é que o arquivo construído está no formato CSV, então podemos abrir ele utilizando o excel, ou o software editor de planilhas de sua preferência.


Entendendo a Fundo

Software

- Incluindo bibliotecas necessárias

Inicialmente, adicionamos as bibliotecas que iremos utilizar para comunicação com o módulo DHT11 e o módulo micro SD. Todas elas são essenciais para que a comunicação com os dispositivos possa ser feita de forma transparente. Como a biblioteca SD e SPI já são nativas do arduino não é necessária a sua instalação. Porém a biblioteca do sensor dht deveremos instalar como mostrado anteriormente.

#include "DHT.h" // Biblioteca do sensor DHT 11 da Adafruit
#include <SPI.h> // Biblioteca de comunicação SPI Nativa
#include <SD.h> // Biblioteca de comunicação com cartão SD Nativa

Existem diversas implementações da biblioteca DHT, utilizei esta em especial por achar mais simples o seu funcionamento. Porém fica a critério do usuário :)

- Criando parâmetros de configuração e  objetos de comunicação

Inicialmente iremos criar dois parâmetros para configurar os pinos onde estão conectados o sensor DHT11 e o módulo micro sd. Neste caso o sensor dht11 está conectado ao pino 0 e o pino Chip Select está conectado ao pino 4.

#define DHTPIN 0 // Define para o pino D3 do nodeMCU -> D3
#define DHTTYPE DHT11 // DHT 11 que será utilizado para comunicação 
const int chipSelect = 4; // Constante que indica em qual pino está conectado o Chip Select do módulo de comunicação

Logo em seguida, iremos criar dois objetos pelos quais iremos nos comunicar com o módulo dht11 e o módulo micro SD. Também criamos uma variável do tipo bool, responsável por informar se a comunicação com o cartão SD está funcionando ou não.

DHT dht(DHTPIN, DHTTYPE); // Objeto utilizado para comunicação entre sensor e microcontrolador
File dataFile;            // Objeto responsável por escrever/Ler do cartão SD
bool cartaoOk = true;

O objeto dht, tem como objetivo realizar a comunicação entre o microcontrolador e o sensor de temperatura/umidade. Ele recebe como parâmetros em seu método construtor, o pino com o qual está conectado ao microcontrolador e o tipo de sensor DHT que está sendo utilizado (neste caso o dht11).

- Função setup

A função setup, será utilizara para inicializarmos a comunicação com o cartão micro SD e a comunicação serial (caso você queira debugar o que está acontecendo no microcontrolador no momento). Com base nisso, este código executa o seguinte fluxograma

  1. Inicializamos a comunicação serial na taxa de comunicação padrão
  2. Inicializamos o objeto dht para comunicação microcontrolador/sensor
  3. Tentamos inicializar a comunicação com o cartão sd
    1. Se estiver tudo ok, a comunicação é inicializada e a escrita pode começar
    2. Caso o cartão não esteja presente ou exista alguma conexão errada, o sistema irá escrever na serial que houve um erro na comunicação com o cartão SD e a variável cartaoOk  é marcada como falso
void setup()
{
  Serial.begin(9600);     // Inicialização da porta de comunicação Serial
  dht.begin();            // Inicialização do objeto de comunicação com sensor

  // Se não for possível se comunicar com o cartão SD o código não deve prosseguir
  if (!SD.begin(chipSelect)) {
    Serial.println("Erro na leitura do arquivo não existe um cartão SD ou o módulo está conectado corretamente ?");
    cartaoOk = false;
    return;
  }
}

- Condição inicial ( É possível escrever no arquivo ? )

Este trecho de código, será utilizado para identificar se é possível escrever no arquivo ou não. Caso seja possível iremos abrir o arquivo para escrita na linha 2 com o comando SD.open("datalog.csv", FILE_WRITE). Caso não seja possível realizar a escrita no arquivo o código irá pular esta condição

// Caso o cartão esteja ok é criado um arquivo no cartão SD com o nome datalog.csv em modo de escrita
if (cartaoOk){
      dataFile = SD.open("datalog.csv", FILE_WRITE); 
        Serial.println("Cartão SD Inicializado para escrita :D ");
  }

- Variáveis de armazenamento

A leitura dos dados é feita a cada intervalo de 1,5 segundos, e a cada leitura realizada precisamos limpar a leitura feita anteriormente, para isso dentro da função loop do código adicionamos o trecho de código que será responsável por limpar as variáveis a cada leitura realizada.

  //Limpando Variáveis 
  String leitura = "";
  float temperature = 0;
  float humidity = 0;

- Leitura da temperatura

Neste bloco de código, iremos realizar a leitura da temperatura utilizando o sensor, o processo é bem simples, realizamos a leitura utilizando a função, readTemperature(). Que irá nos retornar um valor válido, ou inválido caso ocorra algum problema na comunicação com o sensor

 temperatura = dht.readTemperature(); // Função que realiza a leitura da temperatura do sensor dht11

- Leitura da umidade

O processo de leitura da umidade será feito de forma semelhante ao que foi feito na leitura da temperatura. a única mudança será no método utilizado, que no caso será readHumidity();

  umidade = dht.readHumidity(); // Função que realiza a leitura da umidade do sensor dht11

- Validando a leitura dos dados

Já com os dados de temperatura e umidade lidos, iremos agora validar se estes dados são válidos ou não. Para isso, iremos utilizar o método isnan(), ou is not a number. Esta função, tem como objetivo verificar se o valor contido dentro de uma variável é realmente um número ou não. Como a função readTemperature() e readHumidity(), apenas retornam números válidos se a leitura for feita com sucesso, podemos considerar que a leitura será válida apenas quando as variáveis temperatura e umidade forem valores reais. Com base nisso, este trecho de código verifica se as variáveis lidas são realmente números válidos, caso não sejam todo o código dentro do if será executado.

  // Caso os valores lidos do sensor não sejam válidos executamos as seguintes linhas
  if (isnan(temperatura) || isnan(umidade)){ 
    Serial.println ("Falha na leitura do sensor");  // Informar ao usuário que houve uma falha na leitura do sensor
    delay(1500);    // Aguardamos 1,5 segundos
    return ;        // Retornamos a função para o seu ponto inicial
  }

- String para gravação

Após uma leitura ser feita com sucesso, iremos prosseguir para o processo de estruturação dos dados a serem armazenados no arquivo .csv, para isso iremos utilizar o seguinte comando:

// Se tudo estiver ok, escrevemos os dados a serem armazenados em uma String
  leitura = String(millis()) + ";" + String(temperatura) + ";" + String(umidade) + ";";

Com este comando, estamos basicamente criando uma String que irá armazenar todas as informações que queremos armazenar em nosso arquivo csv. O ";" que está sendo utilizado como separador será compreendido pela aplicação de tabelas utilizada como uma nova posição na tabela, ou seja estamos separando o tempo, a temperatura e a umidade em células diferentes.

- Gravando dados em arquivo

Por fim, mas não menos importante, devemos gravar os dados gerados em nosso cartão micro sd. Para isso iremos antes verificar se está tudo ok com o arquivo ( utilizando aquele flag que criamos anteriormente)

 // Se o arquivo estiver realmente aberto para leitura executamos as seguintes linhas de código
  if (dataFile) {   
    Serial.println(leitura);    // Mostramos no monitor a linha que será escrita
    dataFile.println(leitura);  // Escrevemos no arquivos e pulamos uma linha
    dataFile.close();           // Fechamos o arquivo
  }

Se estiver tudo ok, iremos gravar a nossa String criada utilizando o comando

dataFile.println(leitura);      // Escrevemos no arquivos e pulamos uma linha

e em seguida fechamos o arquivo com:

dataFile.close();               // Fechamos o arquivo

Por fim, aguardamos o nosso intervalo de 1,5 segundos para recomeçar todo o processo novamente, e para isso utilizando o comando

delay(1500);

Desafio

Neste tutorial, utilizamos o tempo de funcionamento do microcontrolador para contabilizar o tempo onde foi feita a leitura das variáveis de temperatura e umidade. Uma proposta que seria bem interessante e usual, seria utilizar um relógio de tempo real, ou até mesmo o protocolo NTP para obter o horário real da leitura. Como desafio, proponho a modificação deste código para que ao invés do tempo do microcontrolador ele grave com a data e hora real em que foi feita a leitura. Como base para este desafio, vocês podem utilizar os tutoriais já apresentados aqui no blog como:


Considerações finais

Este tutorial, teve como objetivo mostrar a estrutura de um datalogger bem simplificado, onde utilizamos sensores para obter dados do ambiente e um módulo para armazenar estes dados de forma transparente para o desenvolvedor. Espero que tenham gostado do conteúdo apresentado, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.


Sensor de Gás MQ-135 e a Família de sensores MQ

Sensor de Gás MQ-135 e a família MQ de detectores de Gás 

O sensor gás MQ-135 é capaz de detectar a concentração de vários gases tóxicos em um ambiente tais como: amônia, dióxido de carbono, benzeno, óxido nítrico e também fumaça ou álcool. Neste tutorial vamos aprender como usa o módulo sensor de gás MQ-135 junto a um Arduino.  Esse tutorial também pode ser aplicado para outros sensores de gás, com alguns ajustes, tais como: MQ-2, MQ-3, MQ-4, MQ-5, MQ-6, MQ-7, MQ-8,MQ-9, etc.

Detector de gás / sensor de gás MQ-135
Detector de gás / sensor de gás MQ-135

[toc]

A importância dos sistemas de proteção

Os processos industriais envolvem o uso e fabricação de substâncias altamente perigosas, especialmente produtos inflamáveis, tóxicos e oxidantes. Os gases fazem parte desses ambientes como participantes de reações, catalisadores ou produtos finais. Outras vezes são resíduos ou subprodutos indesejáveis. Escapes ocasionais de gás ocorrem e criam um perigo potencial para a planta industrial, seus funcionários e pessoas que vivem nas proximidades. Incidentes e acidentes em todo o mundo, envolvendo asfixia, intoxicação, explosões e perdas de vidas é um lembrete constante desse problema.

Por isso, sistemas automáticos de detecção de gases são fundamentais para a proteção das pessoas envolvidas nesses processos. É necessário que tenhamos sensores adequados e que sejam posicionados em lugares estratégicos, de preferência com redundância.

É claro que esse tipo de proteção não se limita a industria. Podemos ver facilmente a aplicação de sensores de gás e fumaça em uma cozinha residencial ou em ambientes públicos. Enfim, podemos usar a automação a favor da vida, evitando assim acidentes.

Sensor de gás MQ

Existe uma grande gama de sensores de gás, estre eles, temos os MQ's. Esses sensores de detecção modernos e de baixo custo para gás combustível, são do tipo eletro-catalítico. Eles são feitos de uma bobina de fio de platina aquecido eletricamente, coberto primeiro com uma base de cerâmica, tais como alumina e, em seguida, com um revestimento final exterior do catalisador de paládio ou ródio disperso em um substrato de tório.

- Por dentro do sensor MQ

Na figura a seguir podemos entender um pouco melhor como é por dentro de um sensor de gás MQ.

Dentro de um sensor de gás MQ

Na vertical temos um resistência elétrica que aquece o ar. Essa resistência é ligada através da alimentação dos pinos H's, um vai no 5V e o outro no GND (0V).

De A para B temos nosso sensor de gás. Em uma atmosfera onde possa haver gás poluidor, a resistência do sensor de gás diminui conforme a concentração do gás poluente aumenta. Ou seja, quanto mais gás poluente, menor será a resistência entre A e B. Podemos conferir as variação da resistência conforme a concentração de gases no gráfico à seguir retirado da folha de dados do MQ-135:

Comportamento da resistência entre A e B conforme a concentração de alguns gases. para o sensor de gás MQ135
Comportamento da resistência entre A e B conforme a concentração de alguns gases.

Sendo assim, podemos montar um circuito onde temos uma tensão que será proporcional à quantidade de gases  poluentes.

Esquema interno de um sensor de gás MQ 135
Esquema interno de um sensor de gás MQ

Conforme a resistência entre A e B diminuir (mais gases poluentes), maior será a tensão em cima do resistor RL. Falamos um pouco sobre esse tipo de circuito, o divisor de tensão, no tutorial sobre o sensor de luz LDR.

- Encapsulamento dos sensores MQ

Em geral, os sensores da família MQ possuem o formato como o da figura a seguir:

Encapsulamento de um MQ-135
Encapsulamento de um sensor de gás MQ-135

Como você pode ver, na parte de baixo temos alguns pinos. Ao todo são seis. Esse seis pinos dão acesso ao circuito interno já explicado.

Dentro do encapsulamento do MQ-135
Dentro do encapsulamento do sensor de gás MQ-135

Para facilitar o uso, podemos adquirir esse sensores junto a uma placa que já conta com o circuito necessário para seu pronto funcionamento alem de contar com um circuito comparador.

Família de sensores de gás MQ
Família de sensores de gás MQ

Lista de sensores de Gás

Aqui está a lista de alguns dos sensores de gás que você pode encontrar. Você pode escolher o mais adequado para o seu projeto.

Nome do Sensor  Sensível para
MQ-2 Detecção de gases inflamáveis: GLP, Metano, Propano, Butano, Hidrogênio, Álcool, Gás Natural, outros inflamáveis e fumaça.
MQ-3 Detecção de Álcool , Etanol e fumaça.
MQ-4 Detecção de Metano, Propano e Butano.
MQ-5 Detecção de GLP e gás natural
MQ-6 Detecção de gás GLP (Gás de Cozinha), Propano, Isobutano e Gás Natural Liquefeito
MQ-7 Detecção do gás Monóxido de Carbono
MQ-8 Detecção do gás hidrogênio
MQ-9 Detecção de Monóxido de Carbono e gases inflamáveis
MQ-131 Detecção de ozônio
MQ-135 Detecção de Gás Amônia, Óxido Nítrico, Álcool, Benzeno, Dióxido de Carbono e Fumaça
MQ-136 Detecção de Gás Sulfídrico H2S
MQ-137 Detecção de Gás Amônia
MQ-138 Detecção de n-hexano, benzeno, NH3, álcool, fumaça, CO, etc.

Módulo sensor de Gás MQ-135 - Gases tóxicos e Fumaça

O modulo utilizado, MQ-135 funciona bem detecção de fumaça e outros gases tóxicos, especialmente amônia, vapor de sulfeto e benzeno. Sua capacidade de detectar vários gases nocivos e menor custo faz do MQ-135 uma escolha ideal de diferentes aplicações de detecção de gás.

Ele pode detectar concentrações na faixa de 10 a 1.000ppm (partículas por milhão), possuindo um range de tensão de 0 - 5V. Os módulos do MQ135 são capazes de operar na faixa de temperatura de -10 a 70ºC, consumindo uma corrente aproximada de 150mA.

mq-135
Módulo sensor de amônia MQ-135

O módulo também conta com um potenciômetro para regular a sensibilidade do  sensor, girando ele para um dos lados o sensor ficara mais sensível aos gases.

Atrás dp Sensor de Gás MQ-135 - Gases tóxicos e Fumaça
Por trás do módulo Sensor de Gás MQ-135

Mãos a Obra - Desenvolvimento do Projeto

Componentes necessários

Montando o projeto

A montagem do circuito é bem simples e direta. Basta seguir o esquemático abaixo.

Esquema de montagem do Arduino com o Sensor de Gás MQ-135 - Gases tóxicos e Fumaça

O modulo MQ 135 possui 4 pinos: dois pinos para alimentação (Vcc e GND) e dois pinos para emissão dos sinais elétricos, sendo um sinal digital (D0) e o outro um sinal analógico (A0). Para realizar a montagem, iremos conectar os pinos na seguinte ordem:

Pinos do Sensor de Gás MQ-135 - Gases tóxicos e Fumaça

Em nossa experiência conectamos os pinos do sensor direto na placa Uno, sem o auxilio do protoboard, tal como indicado na tabela anterior. Veja como ficou o nosso montado:

Projeto montado na prática com um Arduino Uno e Sensor de Gás MQ-135 - Gases tóxicos e Fumaça

Programando

Segue o código que utilizamos nesse projeto para fazer a detecção de gás no ambiente.

#define MQ_analog A2
#define MQ_dig 7

int valor_analog;
int valor_dig;

void setup() {
   Serial.begin(9600);
   pinMode(MQ_analog, INPUT);
   pinMode(MQ_dig, INPUT);
}

void loop() {
   valor_analog = analogRead(MQ_analog); 
   valor_dig = digitalRead(MQ_dig);

   Serial.print(valor_analog);
   Serial.print(" || ");
   if(valor_dig == 0)
     Serial.println("GAS DETECTADO !!!");
   else 
     Serial.println("GAS AUSENTE !!!");
   delay(500);

}

Colocando para funcionar

Primeiramente precisamos deixar que a resistência interna do sensor de gás esquente o suficiente para que as medições se estabilizem. Espere por 3 minutos. Chamamos essa espera de tempo de queima. Explicaremos isso mais a frente.

Após deixar o sensor de gás esquentar, vamos testa-lo forçando o ambiente com um fosforo/isqueiro para gerar CO2 (fumaça). O monitor serial irá indicar o valor analógico lido pelo sensor e também indicara se o gás foi detectado ou não, isso é uma resposta ao sinal digital emitido pelo módulo, e esse será calibrado conforme nos quisermos ao girar o potenciômetro. Para calibrar a detecção digital vamos estimular o sensor com o gás do isqueiro e quando acharmos que a estimulação seja suficiente, giramos o potenciômetro até que ele altere o estado entre NÃO DETECTADO <-> DETECTADO, assim esse passa a ser o novo ponto de referencia digital.

Testando o Sensor de Gás MQ-135 - Gases tóxicos e Fumaça para calibrar
Sensor de gás sendo exposto à fumaça da queima do fósforo

As imagens a seguir mostram a sequência que o sensor digital teve alternando o estado de LOW <->HIGH quando o valor analógico estava próximo de 82, neste exemplo eu mantive o fosforo acesso por alguns segundos próximo ao sensor apenas. Veja que na sequência de valores analógicos chega até 380, então de acordo com a duração e proximidade do fosforo ao sensor podemos ir calibrando o sensor digital dele.

Detectando a fumaça
Durante a detecção da fumaça
Deixando de detectar a fumaça

Entendo a fundo

Software

– Nomeando os pinos utilizados através da diretiva #define

O primeiro passo do programa consiste fazer o uso das diretivas #define para nomear os pinos que serão utilizados no projeto, ou seja, o pinos que estarão conectados ao sensor apresentado anteriormente. Sendo assim, neste caso temos que o pino de entrada analógica do Arduino UNO A2 passa a ser identificado no código através do nome MQ_analog, enquanto, o pino de entrada digital 7 do mesmo será referenciado no código pelo nome MQ_dig.

#define MQ_analog A2
#define MQ_dig 7

– Declarando a variável responsável por armazenar o estado do sensor

Em seguida, declaramos duas variáveis para armazenar os valores que forem lidos pelas portas do Arduino UNO, sendo uma delas do tipo inteiro, para a parte analógica e a outra, booleana, para a parte digital.

int valor_analog;
bool valor_dig;

– Configurando o sistema

Dentro da função void setup() vamos configurar as portas do Arduino e a comunicação serial. Vamos iniciar a comunicação serial numa taxa de 9600 bits por segundo e as portas utilizadas devem ser setadas como ENTRADAS (INPUT), afinal eles irão receber sinais elétricos para o Arduino.

void setup() {
   Serial.begin(9600);
   pinMode(MQ_analog, INPUT);
   pinMode(MQ_dig, INPUT);
}

– Rodando o programa principal

Dentro do void loop() teremos o programa rodando em loop infinito, sendo assim iremos faremos a leitura das portas do Arduino e imprimiremos na serial os valores para que possamos ter parâmetros mensuráveis. Com a função analogRead() fazemos a leitura analógica da porta A2. Utilizaremos esse valor apenas como parâmetro para calibrar a sensibilidade digital do sensor.

valor_analog = analogRead(MQ_analog);

Utilizando a função digitalRead() temos a leitura booleana do sensor, quando a resposta for 1 o gás esta sendo detectado, e quando for 0 o gás está ausente. Veremos mais adiante que a sensibilidade do sensor precisa ser ajustada com o potenciômetro do modulo.

valor_dig = digitalRead(MQ_dig);

Por fim fazemos a impressão dos valores lidos na serial, para que assim, possamos ver o resultado das leituras.

if(valor_dig == 0)
 Serial.println("GAS DETECTADO !!!");
 else 
 Serial.println("GAS AUSENTE !!!");
Detectando o gás
Detectando o gás

Hardware

– Calibrando o módulo digital

Como dito antes é necessário calibrar o sensor digital do módulo MQ 135. Para isso rode o programa anterior e abra o monitor serial e, com auxilio de uma pequena chave Philips, gire o potenciômetro na parte de trás do módulo até que o você encontre um ponto que altere de 0 pra 1. O valor analógico irá servir como base para mediar a sensibilidade do sensor.

Atrás do sensor de gás e fumaça MQ 135 - Resistência de calibração
Atrás do módulo MQ 135 - Resistência de calibração

- Tempo de queima - Burn-in time

Para que o sensor esteja pronto para fazer as medições é necessário aguardar um tempo denominado como Burn -in time (Tempo de queima) ou preheat (pré aquecimento). Esse tempo varia de modelo para modelo, mas para testes mais simples, como para familiarizar com o sensor, podemos aguardar cerca de 3 minutos. Esse é o tempo necessário para que a resistência do sensor aqueça até a temperatura ideal de funcionamento do sensor. Durante esse período as medições podem oscilar muito.

Para aplicações oficiais, tal como implementação de um detector de incêndio, onde precisamos de uma precisão de medição maior e mais confiável,  é recomendado pelos fabricantes que o tempo de queima seja de pelo menos 24 horas. Esse é o tempo necessário para que o sensor alcance a plena estabilização das medições entre os terminais internos A e B.


Considerações finais

Este projeto apresenta uma utilização básica do sensor MQ 135. Esperamos que você tenha gostado deste conteúdo, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.

Caso esteja começando com Arduino recomendamos que conheça a Apostila Arduino Básico.


Banco de dados MySQL com Arduino e Shield Ethernet W5100

Banco de dados MySQL com Arduino e Shield Ethernet W5100 – Registrando temperatura em um banco de dados

Sabemos que a utilização de placas Arduino é bastante difundida nos dias atuais, de modo que, o seu uso está presente em uma grande diversidade de aplicações, que vão desde trabalhos acadêmicos até projetos comerciais e industriais, no entanto, um grande problema surge em todas estas vertentes quando nos deparamos com a necessidade de armazenar informações inerentes a um determinado processo. Sendo assim, neste tutorial iremos aprender como fazer o registro de informações, mais especificamente, de temperatura em um banco de dados MySQL com o auxilio do shield ethernet W5100.

[toc]

O que são bancos de dados?

De uma maneira bem simples, pode-se entender um banco de dados como sendo um local onde podemos armazenar uma série de informações de maneira estruturada, organizada, que por sua vez, estejam à disposição para serem utilizadas tanto por softwares quanto por usuários diferentes. Podemos, por exemplo, armazenar os valores de temperatura coletados ao longo de um dia por uma placa Arduino e armazenar os mesmos numa tabela juntamente com a hora da medição.

Pense em uma industria com centenas de sensores que fazem medições de dados do processo a todo instante. É necessário que os dados estejam organizados de forma adequada e que os mesmos estejam acessíveis sempre que necessário, pois, caso contrario, estes seriam uma gama de informações sem utilidade prática.

Sendo assim, podemos perceber que os bancos de dados são recursos muito importantes e essenciais para o funcionamento dos mais variados tipos de estabelecimentos, desde os menores até as grandes indústrias, hospitais e etc, pois, através dos dados presentes nos mesmos, realiza-se o controle, por exemplo, de funcionários, de material, de custos e além disso, é possível até mesmo auxiliar nas tomadas de decisão em virtude de uma análise estatística feita sobre os mesmos.

Para realizarmos este tutorial deve-se ter em mente que os bancos de dados ficam armazenados em um servidor, portanto, antes de acessarmos um banco de dados, devemos acessar primeiramente o servidor onde estes estão inseridos. Em contrapartida, as estruturas intrínsecas a um banco de dados são as tabelas (estas são, de fato, tabelas, dotadas de linhas e colunas).

Estrutura de um banco de dados MySQL

O MySQL, nosso Banco de dados

Quando realizamos algumas pesquisas sobre o que é o MySQL encontramos algumas fontes dizendo que o mesmo se trata de um banco de dados, enquanto outras, classificam o mesmo como um sistema gerenciador de banco de dados (SGBD) que utiliza a linguagem SQL como interface para realizar manipulação dos dados armazenados. Neste tutorial, como não estamos focados em toda parte teórica por trás deste assunto, basta encararmos o MySQL como um banco de dados, que não teremos maiores problemas.

 

Para utilizamos o MySQL, é necessário instalarmos um servidor, responsável por entre outras coisas, armazenar os dados e responder às requisições feitas por um cliente conectado com mesmo (conforme falando anteriormente, tanto softwares quanto usuários podem interagir com um servidor). O MySQL possui uma versão gratuita para a comunidade, que por sua vez, inclui diversos elementos, entre eles, o servidor e uma interface gráfica para ser utilizada como cliente.

A nossa sugestão é que você realize o download do instalador completo e instale o mesmo no seu computador.


Mãos à obra – Registrando informações no banco de dados

Neste momento, iremos demonstrar todos os passos para que você consiga realizar o objetivo que estamos propondo neste tutorial.

Componentes utilizados:

Montando o projeto

Esquema de montagem do Arduino Uno com Shield W5100 e Sensor de temperatura LM35
Esquema de montagem do Arduino Uno com Shield W5100 e Sensor de temperatura LM35

Programando

Antes de adentrarmos na apresentação do código, disponibilizamos uma seção para ajudar aqueles que são iniciantes no assunto. Sinta-se livre para prosseguir caso você já tem domínio da IDE do Arduino.

Conectando o Arduino ao computador

Primeiramente, conecte seu Arduino ao computador e abra a IDE Arduino. Em seguida, é necessário selecionar a porta COM na qual o Arduino está conectado (este procedimento pode ser feito clicando no menu Ferramentas (tools) e em seguida escolhendo-se a porta correspondente no submenu Porta (port). Neste caso, a porta na qual está o Arduino é apresentada da seguinte maneira: COM3 (Arduino UNO).

IDE Arduino configurando porta de comunicação

Por fim, garanta também que o tipo de placa apropriado esteja selecionado (isso pode ser feito acessando o menu Ferramentas (tools) e o submenu Placa (board)).

Configurando a placa Arduino UNO na IDE Arduino

- Biblioteca

Para desenvolver o projeto proposto  utilizou-se uma biblioteca capaz de atuar sobre um servidor MySQL fazendo com que o Arduino possa manipular dados existentes nas tabelas dos bancos de dados MySQL. Esta biblioteca pode ser encontrada aqui.

Adquirindo e instalando a biblioteca que será utilizada

Para adquirir a biblioteca em questão, basta acessar o link apresentado anteriormente, clicar no botão clone or Download e por fim, no botão Download ZIP, conforme a figura abaixo.

Baixando a biblioteca responsável pela comunicação com o banco de dados MySQL
Baixando a biblioteca responsável pela comunicação com o banco de dados MySQL

Após a realização do download dos arquivos compactados no formato ZIP, abra a IDE do Arduino, selecione o menu Sketch, o submenu Incluir Bilioteca e por fim, basta clicar na opção Adicionar biblioteca .ZIP (Add ZIP Library) e encontrar o arquivo que acabou de ser baixado.

Uma outra forma de fazer isso é extrair o conteúdo do arquivo ZIP dentro da pasta Libraries (onde foi instalada a IDE do Arduino).

– Preparação (VOCÊ DEVE LER ESTA PARTE)

Antes de partir para o código desta aplicação, devemos entender uma coisa: A placa Arduino utilizada não é capaz de criar bancos de dados e tabelas, conforme será visto adiante, portanto, para que seja possível registrarmos valores de temperatura em um banco de dados MySQL, devemos criar manualmente o banco de dados no servidor MySQL e também a tabela na qual serão efetuados os registros.

Além disso, devemos também realizar a criação de um usuário para ser utilizado neste nosso projeto.

O primeiro passo para que seja possível realizar a integração do Arduino com um banco de dados MySQL consiste em criar um usuário para acessar o servidor, bem como, a sua senha de acesso.

Quando nós instalamos um servidor MySQL em um computador, um usuário padrão chamado root (juntamente com uma senha definida pelo usuário) é criado no momento da instalação, porém, recomenda-se que criemos um novo usuário para entrar no servidor através do mesmo. Este procedimento deve ser realizado por dois motivos, onde o primeiro é que o próprio desenvolvedor da biblioteca recomenda que isto seja feito e segundo por que existem vários relatos de que o Arduino não consegue se conectar ao servidor através do usuário root.

Para realizar este procedimento, basta entrar no terminal do servidor MySQL. Isto pode ser feito, primeiramente, acessando o Prompt de comando e percorrendo o caminho até a pasta onde o servidor foi instalado e em seguida, utilizando o comando apresentado na figura a seguir:

Após a realização do passo anterior, você deverá digitar a senha do usuário root (definida na instalação do servidor) e então será possível acessar diretamente o terminal.

Na figura anterior, criamos um usuário chamado arduino, o qual, está atrelado a uma senha também nomeada arduino. O símbolo determina que qualquer IP pode entrar no servidor MySQL através deste usuário. Obviamente, em termos de segurança, este não é o procedimento mais adequado, no entanto, para nossa demonstração, é suficiente.

Agora que já criamos o usuário, devemos criar um banco de dados dentro do servidor, chamado banco_arduino. Este procedimento é bastante simples e pode ser realizado da seguinte maneira:

Por fim, devemos criar uma tabela (que será preenchida pelo Arduino UNO), que por sua vez, será o local onde serão inseridas as informações referentes aos valores de temperatura provenientes do sensor de temperatura LM35. Queremos uma tabela com o seguinte formato:

Exemplo de medições no banco de dados MySQL
Exemplo de medições no banco de dados MySQL

Para isto, devemos proceder conforme a figura abaixo:

Veja como ficou a tabela criada

Neste momento, temos todos os pré-requisitos necessários para começarmos a realizar a aplicação proposta neste tutorial.

– Código do projeto

Segue o código a ser utilizado no Arduino para registrar valores de temperatura em um banco de dados MySQL

#include <Ethernet.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <SPI.h>

#define LM35 A0

int leitura;
float leituraconvertida
char sentenca[128];
char valortemp[10];

byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server_addr(192,168,25,5);  
char user[] = "arduino";              
char password[] = "arduino";        

char INSERIR_TEMP[] = "INSERT INTO registrotemp (temperatura) VALUES (%s)";
char BANCODEDADOS[] = "USE banco_arduino";

EthernetClient client;
MySQL_Connection conn((Client *)&client);

void setup() 
{ 
   Serial.begin(115200);
   while (!Serial); 
   Ethernet.begin(mac_addr);
   Serial.println("Conectando...");
   if (conn.connect(server_addr, 3306, user, password)) 
   {
      delay(1000);
      
      MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
      cur_mem->execute(BANCODEDADOS);
      delete cur_mem;
   }
   else
   {
      Serial.println("A conexão falhou");
      conn.close();
   }
}


void loop() 
{
   Serial.println("Executando sentença");

   leitura = analogRead(LM35);
   leituraconvertida = (float(analogRead(LM35))*5/(1023))/0.01;

   dtostrf(leituraconvertida, 4, 1, valortemp);
   sprintf(sentenca, INSERIR_TEMP, valortemp);
   
   MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
   cur_mem->execute(sentenca);
   delete cur_mem;

   delay(2000);
}

Entendendo a fundo

Software

Neste momento, iremos explicar o funcionamento do código apresentado, porém, de maneira bastante detalhada.

- Incluindo as bibliotecas a serem utilizadas no projeto

Primeiramente, para desenvolvermos uma aplicação como esta, devemos incluir todas as bibliotecas que serão utilizadas no código, para que assim, o mesmo possa funcionar de maneira adequada. A biblioteca Ethernet.h é responsável pela comunicação que será estabelecida entre o Arduino UNO e a rede através do Shield ethernet wiznet w5100. Já a biblioteca SPI.h  tem como função coordenar a integração do shield citado com o Arduino UNO por meio do protocolo de comunicação SPI.

As bibliotecas MySQL_Connection MySQL_Cursor têm como função promover a conexão Arduino UNO/servidor MySQL e executar as sentenças de manipulação de informações em um banco de dados.

#include <Ethernet.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <SPI.h>

- Nomeando o pino de entrada analógica através da diretiva #define

Em seguida, utilizamos a diretiva #define para associar o pino de entrada analógica A0 ao nome LM35 (vale ressaltar que isso é apenas um recurso para facilitar a didática da programação, portanto, não obrigatório).

#define LM35 A0

- Declarando as variáveis a serem utilizadas no projeto

Posteriormente, temos um bloco onde ocorre a declaração das variáveis que serão utilizadas no decorrer do programa. As variáveis leitura (tipo inteiro) e leituraconvertida (tipo float) são responsáveis por armazenar o valor obtido da porta de entrada analógica A0 (através da função analogRead(), portanto, contido no intervalo de 0 a 1023) e o valor já convertido em temperatura, respectivamente.

int leitura;
float leituraconvertida;

Observe que também foram criados dois vetores do tipo char, estes são: sentenca e valortemp. Os elementos citados servirão para conter as frases (lembre-se que um vetor de elementos do tipo char é um vetor de caracteres) necessárias para a construção das sentenças que serão utilizadas para manipular os dados no servidor MySQL.

O tamanho dos vetores deve ser tal que os mesmos consigam armazenar as mensagens que serão utilizadas, sendo assim, não existe um valor certo para os mesmos, mas sim, um valor que atenda as necessidades conforme será visto mais adiante. Note que também é possível não declarar um valor para o tamanho, deixando que o programa calcule automaticamente a dimensão do mesmo.

char sentenca[128];
char valortemp[10];

- Definindo o endereço MAC do Arduino UNO

O próximo passo consiste em definir o endereço MAC que será atribuído ao Arduino UNO para que a conexão entre o mesmo e a rede possa ser estabelecida. No desenvolvimento deste projeto, conectamos o Shield Ethernet em nosso modem.

Na prática, este endereço pode ser qualquer um, desde que seja único na rede.

byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

- Definindo os parâmetros para a conexão com o servidor MySQL

Após a realização dos procedimentos listados anteriormente, deve-se definir os parâmetros necessários para que o Arduino UNO consiga ser conectado ao servidor MySQL existente. A primeira informação essencial é IP do servidor MySQL (caso o servidor esteja rodando, por exemplo, no seu laptop, o IP a ser inserido neste campo será justamente o IP do seu computador na rede local e para consulta-lo basta abrir o prompt de comando, digitar ipconfig e copiar o Endereço IPV4 (se estiver em inglês, IPV4 Address)).

IPAddress server_addr(192.168.25.5);

Veja como esta informação pode ser obtida:

Em seguida, escolhe-se um dos usuários cadastrados e a senha do mesmo, para que o Arduino UNO entre no servidor MySQL através destas informações. Neste caso, utilizamos o usuário chamado arduino cuja senha atribuída ao mesmo é arduino.

char user[] = "arduino";             
char password[] = "arduino";

- Criando as sentenças para manipulação de dados

Agora, devemos criar as sentenças que serão utilizadas pelo Arduino UNO para registrar as informações no banco de dados existente no servidor MySQL. 

A primeira sentença informa ao Arduino UNO qual dos bancos de dados existentes no servidor MySQL será manipulado, neste caso, o banco chamado banco_arduino.

Quando estamos interagindo diretamente com um servidor MySQL através do seu terminal, utilizamos a sentença "USE <nome do banco de dados>;" para selecionar um determinado banco de dados existente no servidor em questão. Sendo assim, declaramos um vetor de variáveis do tipo char, sem tamanho definido, para que este armazene a sentença citada anteriormente, de modo que, quando necessário, o Arduino UNO seja capaz de utilizá-la.

char BANCODEDADOS[] = "USE banco_arduino";

A segunda sentença é responsável por preencher uma linha de uma determinada tabela existente dentro de um banco de dados, neste caso, a tabela chamada registro.

Quando manipulamos uma tabela de um banco de dados através do terminal de um servidor MySQL, utilizamos a sentença "INSERT INTO <nome da tabela> <coluna a ser preenchida da tabela> VALUES <valor a ser colocado na interseção da coluna definida anteriormente com próxima linha vazia não preenchida>;" para preencher uma determinada linha da mesma. Desta maneira, assim como no item anterior, declaramos um vetor de variáveis do tipo char para que seja possível armazenar a sentença adequada para o propósito citado.

char INSERIR_TEMP[] = "INSERT INTO registrotemp (temperatura) VALUES (%s)";

- Declarando os objetos client e conn

Neste momento, cria-se dois objetos que serão utilizados posteriormente, de modo que, um destes é do tipo EthernetClient, chamado client (que representará o elemento responsável pela comunicação via ethernet no código) e outro do tipo MySQL_Connection, chamado conn (que será responsável pela conexão com o servidor MySQL).

Lembre-se: client e conn são apenas nomes, sendo assim, é importante ressaltar que, os objetos identificados por client e conn poderiam ser chamados de quaisquer outros nomes, como por exemplo, conexaoethernet e conexaomysql, respectivamente.

EthernetClient client;
MySQL_Connection conn((Client *)&client);

- Estabelecendo a conexão com o servidor MySQL

Primeiramente, utilizamos a função Serial.begin() para inicializar a comunicação serial. Neste caso, determinamos como parâmetro da função uma taxa de 115200 baud/s em virtude deste valor ter sido utilizado pelo desenvolvedor da biblioteca presente neste tutorial. Em seguida, recorremos à função while() com o argumento !Serial, para que o programa só continue sendo executado após a comunicação serial ter sido estabelecida.

Não só estes procedimentos, como todos os outros que envolvem a manipulação da porta serial, servem apenas para testes, isto é, para que você possa verificar se o programa está com algum tipo de erro ou se está funcionando perfeitamente, portanto, as linhas referentes aos mesmos podem ser comentadas caso o programa esteja funcionando da maneira desejada.

 Serial.begin(115200);
 while (!Serial); // wait for serial port to connect

Em seguida, utilizamos a função Ethernet.begin() para iniciar a comunicação com a rede via Ethernet. Observe que o parâmetro desta função é o endereço MAC definido anteriormente.

Ethernet.begin(mac_addr);

Para facilitar na visualização da execução do programa, imprimimos na porta serial a seguinte informação: "Conectando..."

Serial.println("Conectando...");

A próxima linha de código conta com uma função if(), cujo argumento é uma outra função, responsável pela conexão do Arduino com o servidor MySQL, de modo que, nesta função são passados como parâmetros o endereço IP da máquina onde está o servidor, a porta para o acesso do mesmo (geralmente, na instalação do servidor, a porta que vem definida como padrão é a 3306), o usuário e a senha do mesmo. Caso esta função consiga ser executada com exito, isto é, caso a conexão com o servidor ocorra sem problemas, o argumento testado na função if() será verdadeiro e o seu conteúdo será executado.

if (conn.connect(server_addr, 3306, user, password)) 
{
    ****** Conteúdo da função if() ******
}

O conteúdo da função if() começa com a utilização de uma função delay() para estabelecer um atraso na execução do programa e garantir o estabelecimento da conexão com o servidor MySQL.

delay(1000);

Em seguida, criamos um objeto do tipo MySQL_Cursor, chamado cur_mem. Este cursor será responsável por executar as sentenças que serão utilizadas para manipular as informações do banco de dados.

MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);

Posteriormente, utilizamos a função execute(), de modo que, o parâmetro da mesma é justamente a variável do tipo char BANCODEDADOS. Lembre-se que o conteúdo desta variável é a frase "USE banco_arduino", que por sua vez, é o comando responsável por selecionar o banco de dados banco_arduino, entre os outros eventuais bancos existentes no servidor.

cur_mem->execute(BANCODEDADOS);

Por recomendação do desenvolvedor da biblioteca, após a execução da sentença desejada, apagamos o cursor criado anteriormente, em virtude do uso de memória.

delete cur_mem;

Confira o conteúdo completo da função if()

if (conn.connect(server_addr, 3306, user, password)) 
{ 
    delay(1000);
  
    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
    cur_mem->execute(BANCODEDADOS);
    delete cur_mem;
}

Caso a condição da função if() não seja satisfeita, isto é, se a conexão com o servidor não tiver ocorrido com sucesso, executa-se o conteúdo da função else, que por sua vez, consiste nas funções Serial.println() para imprimir uma mensagem de falha na conexão e a função close(), responsável por encerrar a tentativa de conexão.

{
     Serial.println("A conexão falhou");
     conn.close();
}

Observe como está a nossa função setup():

void setup() {
 
  Serial.begin(115200);
  while (!Serial); 
  Ethernet.begin(mac_addr);
  Serial.println("Conectando...");
  if (conn.connect(server_addr, 3306, user, password)) 
  {
     delay(1000);
   
     MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
     cur_mem->execute(BANCODEDADOS);
     delete cur_mem;
  }
  else
  {
     Serial.println("A conexão falhou");
     conn.close();
  }
}

- Registrando a temperatura em banco de dados MySQL

O primeiro procedimento a ser executado na função loop() é o envio de uma mensagem através da porta serial avisando ao usuário que algum tipo de manipulação no banco de dados está sendo executada.

Serial.println("Executando sentença");

Em seguida, realiza-se a leitura da porta de entrada analógica (através da função analogRead()) na qual está conectado o sensor e armazena-se o resultado na variável leitura.

leitura = analogRead(LM35);

Posteriormente, realizamos a conversão do valor inteiro adquirido para valores de temperatura. O cálculo apresentado e toda explicação sobre o sensor de temperatura LM35 estão presentes no nosso tutorial LM35 - Medindo a temperatura com Arduino.

leituraconvertida = (float(analogRead(LM35))*5/(1023))/0.01;

O próximo passo consiste na conversão do valor de temperatura de float para string. Isso deve ser feito para que este valor possa ser inserido em uma sentença (lembre que elas são montadas sobre um vetor de char) e assim, possa ser utilizado para manipular as informações do banco de dados.

A função utilizada para cumprir este propósito é a dtostrf(). Nesta função, existem quatro parâmetros, onde estes são: a variável do tipo float que queremos converter, o número de algarismos que o resultado da conversão deve ter (incluindo a vírgula), o número de casas após a vírgula e o vetor de char em que será armazenada a informação retornada por esta função.

dtostrf(leituraconvertida, 4, 1, valortemp);

Veja com mais detalhes o funcionamento desta função:

Após a conversão do valor citado, utilizamos a função sprintf() construir a sentença contendo a instrução que será utilizada na manipulação do banco de dados. O primeiro parâmetro desta função consiste na variável do tipo char na qual será armazenada a sentença após ser construída, o segundo, deve conter a variável que armazenou a parte textual da frase e o local onde será inserida a variável (%s) e o terceiro parâmetro é justamente a variável que será inserida no local especificado no segundo parâmetro.

sprintf(sentenca, INSERIR_TEMP, valortemp);

Veja um esquema detalhado do funcionamento da função:

Em seguida, realizamos o mesmo procedimento apresentado anteriormente para manipular o banco de dados, onde, primeiramente criamos o cursor, executamos uma sentença (deste vez é a sentença para incluir uma linha na tabela) e por fim, deletamos o cursor criado.

MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
cur_mem->execute(sentenca)
delete cur_mem;

Por fim, utilizamos a função delay() para fazer com que o banco de dados seja preenchido apenas a cada 2 segundos

delay(2000);

Veja como ficou a nossa função loop()

void loop() {
 
  Serial.println("Recording data.");

  leitura = analogRead(LM35);
  conversao = (float(analogRead(LM35))*5/(1023))/0.01;

  dtostrf(conversao, 1, 1, temperatura);
  sprintf(sentenca, INSERIR _TEMP, temperatura);
  
  // Initiate the query class instance
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  // Execute the query
  cur_mem->execute(query);
  // Note: since there are no results, we do not need to read any data
  // Deleting the cursor also frees up memory used
  delete cur_mem;
delay(2000);
}

Considerações finais

Neste tutorial demonstramos um conteúdo novo e muito interessante para aqueles que gostam de desenvolver aplicações com uma placa Arduino mas não sabem como, por exemplo, registrar informações para uso posterior. Aqui, apresentamos os procedimentos necessários para fazer com que seja possível elaborar um projeto integrando o processo de aquisição de dados com o Arduino UNO e o armazenamento dos mesmos em um banco de dados de um servidor MySQL. Esperamos que você tenha gostado deste conteúdo e sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.


Display LCD 20x4 e 16x2 com Adaptador I2C

Display LCD 20x4 e LCD 16x2 com Adaptador I2C – Utilizando o display com Arduino

No tutorial sobre a utilização de um display lcd 16x2 com Arduino aprendemos a importância dos displays e como usar um LCD de caracteres, em especial o 16x2. Apesar de esse LCD ser prático e simples, ele possui um problema, uma grande demanda por ligações. Para resolver isso, podemos usar um módulo adaptador I2C que facilita ainda mais o uso desse tipo de recurso. Nesse tutorial iremos aprender a usar o Display LCD 20x4 com Adaptador I2C junto a um Arduino.

O uso tanto do display LCD 16x2 tanto do display LCD 20x4 é muito semelhante, a diferença entre eles é o numero de caracteres que dispõem na tela. Como falamos sobre o modelo 16x2 no último tutorial, iremos aproveitar a oportunidade para mostrar um pouco mais sobre o modelo 20x4. Caso você tenha em suas mão o 16x2, você poderá facilmente adaptar o programa usado nesse tutorial para você.

[toc]

Porque usar comunicação I2C para controlar seu LCD?

Display LCD 20x4 Azul
Display LCD 20x4 Azul

Na figura acima, percebemos a existência de uma grande quantidade de contatos para realização do seu acionamento. Para facilitar o seu uso, iremos trabalhar com o adaptador I2C para display LCD.

Para usar esse LCD diretamente no Arduino, você irá precisa, além das ligações de alimentação,  de 6 pinos: RS, EN, D7, D6, D5, e D4 para que seu LCD converse com seu Arduino. Se você estiver trabalhando com um projeto mais complexo, talvez você não terá tantos pinos disponíveis no seu Arduino para seu LCD da forma usual.

Com o módulo de interface I2C, você precisará de apenas 2 pinos (I2C) para imprimir as informações que deseja em seu LCD. Se você já tiver usando outros componentes I2C em seu projeto, esse pino não precisará usar mais nenhuma porta, visto que ele poderá usar os mesmo pinos já usado para o outro dispositivo I2C.

Adaptador I2C para Display LCD 20x4 e 16x2

Adaptador I2C para display LCD
Adaptador I2C para display LCD

Para que seja possível a comunicação entre o Arduino e o LCD, precisaremos de um adaptador I2C. Esse adaptador nada mais é  que um conversor cuja função consiste em manipular os contatos do LCD, de modo que, após este processo, teremos apenas 2 contatos para realizar a comunicação com uma placa Arduino através do protocolo I2C.

Ele conta com o chip PCF8574T ou PCF8574AT que é responsável por essa interface . Você pode encontrar vários modelos de módulos ligeiramente diferentes.

Em geral eles possuem o seguinte formato:

detalhamento Adaptador I2C LCD
detalhamento Adaptador I2C para display LCD

Como você pode ver na imagem, a maioria dos módulos de interface I2C para LCD possuem:

  • Pinos para conexão com o Display (16 pinos);
  • Pinos de Alimentação do Módulo (GND e VCC);
  • Pinos de comunicação I2C (SDA e SCL);
  • Trimpot para ajuste de contraste da tela;
  • Jumper para ligar e desligar a luz de fundo (Backlight);
  • Led indicador de módulo ligado.
  • Chip de Interface (PCF8574T ou PCF8574AT )

Endereço do módulo I2C

Para alguns modelos ainda é possível configurar o endereço do módulo I2C através de A0, A1 e A2. Abaixo você pode conferir a tabela de endereços possíveis para cada um dos chips (PCF8574T ou PCF8574AT ):

Endereços configuráveis para os chips PCF8574T e PCF8574AT.( L para 0V e H para 5V)

A0, A1 e A2 são portas do nosso Chip:

Portas do chip PCF8574T e PCF8574AT
Portas do chip PCF8574T e PCF8574AT

Que em geral vem ligados a alimentação do módulo (VCC):

Esquema de ligação dos pinos de endereço
Esquema de ligação dos pinos de endereço

Quando conectamos o ponto 1 com 1, 2 com 2 ou 3 com 3, estamos colocando um nivel lógico baixo em A0, A1 ou A2 respectivamente. Na figura anterior, os pinos A0, A1 e A2 estão conectados ao chip do módulo. Veja que segundo esse esquemático, estamos com 5V em cada um dos 3 pinos. Ou seja, nosso endereço será 0x27 caso o chip seja o PCF8574T ou 0x3F caso o chip seja o PCF8574AT.

tabela do lcd i2c

Para alterar o endereço podemos colocar um ponto de solda para conectar os pinos A0, A1 ou A2 ao GND para as placas que tenha essa opção:

Opção para alteração de endereço

Para conectar os pinos A0, A1 ou A2 ao GND, você precisa pode usar solda de estanho para ligar o ponto de baixo com o de cima, tal como na figura a seguir:

Adaptador com chip PCF8574T com A0, A1 e A2 conectados ao GND. logo o endereço será 0x20.

Display LCD 20x4 com adaptador I2C

Para o nosso tutorial, iremos usar um LCD que já possui o adaptador soldado ao módulo display. Para o display que usaremos não temos a opção de mudança de endereço:

Display LCD 20x4 com adaptador
Display LCD 20x4 com adaptador

Veja em detalhes o módulo I2C usado:

Repare que ele não tem a opção de mudança de endereço. O chip dele é o PCF8574T, ou seja, iremos usar o endereço 0x27.

Display LCD 16x2 com adaptador I2C

Você também pode usar a versão do Display LCD 16x2 com adaptador I2C. A maior diferença é a quantidade de caracteres. Explicaremos mais a frente como adaptar o programa que usamos nesse tutorial para o display LCD 16x2.

O endereçamento funcionará da mesma forma que o explicado anteriormente. Verifique o modelo do seu adaptador para descobrir o endereço do mesmo.

Display LCD 16x2 Azul + Adaptador I2C
Display LCD 16x2 Azul + Adaptador I2C

Mãos à obra – Imprimindo informações no display LCD 20x4 I2C

Componentes utilizados

Caso tenha um LCD 16x2 ou 20x4 e queira adapta-lo, basta adquirir o Módulo i2C separado.  Módulo I2C para Display LCD compativel com 16x02 e 20x4

Montando o projeto

Na figura abaixo, o leitor poderá conferir como foi realizada a montagem do projeto apresentado neste tutorial.  Lembre-se de montar o projeto com o seu Arduino desligado.

Esquema de montagem do Display LCD 20x4 Azul + Adaptador I2C com Arduino Micro
Esquema de montagem do Display LCD 20x4 Azul + Adaptador I2C com Arduino Micro

Esquema de montagem do Display LCD 20x4 Azul + Adaptador I2C com Arduino UNO
Esquema de montagem do Display LCD 20×4 Azul + Adaptador I2C com Arduino UNO

Veja como ficou o nosso:

Projeto montado com Display LCD 20x4 Azul + Adaptador I2C com Arduino Micro

Programando

Antes de adentrarmos na apresentação do código, disponibilizamos uma seção para ajudar aqueles que são iniciantes no assunto. Sinta-se livre para prosseguir caso você já tem domínio da IDE do Arduino.

Conectando o Arduino ao computador

Primeiramente, conecte seu Arduino ao computador e abra a IDE Arduino. Em seguida, é necessário selecionar a porta COM na qual o Arduino está conectado (este procedimento pode ser feito clicando no menu Ferramentas (tools) e em seguida escolhendo-se a porta correspondente no submenu Porta (port). Neste caso, a porta na qual está o Arduino é apresentada da seguinte maneira: COM3 (Arduino Micro).

Por fim, garanta também que o tipo de placa apropriado esteja selecionado (isso pode ser feito acessando o menu Ferramentas (tools) e o submenu Placa (board)).

- Biblioteca

Para desenvolver o projeto proposto com o Display LCD I2C 20X4 utilizou-se uma biblioteca capaz de atuar sobre o protocolo I2C para facilitar os processos de endereçamento e troca de dados que fazem parte do funcionamento do protocolo citado. Esta biblioteca pode ser encontrada aqui.

Adquirindo e instalando a biblioteca que será utilizada

Após a realização do download dos arquivos compactados no formato ZIP, abra a IDE do Arduino, selecione o menu Sketch, o submenu Incluir Bilioteca e por fim, basta clicar na opção Adicionar biblioteca .ZIP (Add ZIP Library) e encontrar o arquivo que acabou de ser baixado.

Uma outra forma de fazer isso é extrair o conteúdo do arquivo ZIP dentro da pasta Libraries (onde foi instalada a IDE do Arduino).

– Código do projeto

Segue o código a ser utilizado no Arduino para imprimir informações no Display LCD I2C 20x4.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Inicializa o display no endereco 0x27
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);
 
void setup()
{
 lcd.begin (20,4);
}
 
void loop()
{
  lcd.setCursor(0,0);
  lcd.print("********************");
  lcd.setCursor(9,1);
  lcd.print("VIDA");
  lcd.setCursor(5,2);
  lcd.print("DE SILICIO");
  lcd.setCursor(0,3);
 lcd.print("********************");
}

Entendendo a fundo

Software

- Incluindo as bibliotecas

Inicialmente, observe que foi necessário incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca wire.h é a responsável pela comunicação utilizando o protocolo I2C enquanto a biblioteca LiquidCrystal_I2C.h atua sobre a biblioteca wire.h simplificando o processo de comunicação através do protocolo citado, para que assim, o usuário possa utilizar o Display LCD I2C 20x4 de maneira mais fácil.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

- Criando o objeto lcd 

Em seguida, cria-se um objeto que será utilizado posteriormente para representar o Display LCD I2C 20x4 no código.

Lembre-se: lcd é apenas um nome, sendo assim, é importante ressaltar que este objeto poderia ser chamado por qualquer outro nome, como por exemplo, display.

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);

Essa função é padrão tanto para o LCD 20x4 como para o 16x2. Nela definimos o endereço do adaptador, que para o nosso equivale sempre 0x27.

Além do endereço, definimos, nesse comando, os  pinos no chip I2C usados para conexões no LCD. Como esse pinos sempre são os mesmos, temos esse comando sendo usado para definir apenas o endereço, que para alguns módulos pode ser alterado. As demais configurações são padrões.

// Define os pinos do chip I2C usados para as conexões do LCD:
//               (Endereço,en,rw,rs,d4,d5,d6,d7,bl, blpol)
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

- Definindo as configurações iniciais

Dentro da função setup() utilizamos a função lcd.begin() (repare que o nome lcd corresponde ao objeto criado anteriormente) para inicializar o Display LCD I2C 20x4, de modo que, os parâmetros utilizados são o número de colunas e o número de linhas do display, nesta ordem.

void setup()
{
 lcd.begin (20,4);
}

Veja que, caso esteja usando um display LCD 16x2, aqui você definirá o tamanho do LCD com 16 colunas e 2 linhas:

void setup()
{
 lcd.begin (16,2); //configuração para display 16x2
}

- Imprimindo informações no Display

O primeiro passo na manipulação do display consiste em localizar o cursor no local adequado. Este cursor nada mais é do que o elemento que apontará para o espaço que será preenchido com um caractere, sendo assim, utilizamos a função setCursor() para determinar qual será o ponto de partida da escrita de uma sequência de caracteres.

Perceba que a as posições dos espaços para escrita são dadas da seguinte forma:

Desta maneira, ao utilizarmos "0" e "0" como parâmetros, estaremos definindo a coordenada (0,0) como ponto de partida para o começo da escrita.

lcd.setCursor(0,0);

Em seguida, utilizamos a função print() para poder escrever algo a partir da posição que definimos como ponto de partida. Neste caso, simplesmente preencheremos com '*'.

lcd.print("********************");

Posteriormente, utilizamos novamente a função setCursor() para posicionar o cursor na segunda linha.

lcd.setCursor(9,1);

Com o cursor posicionado, escrevemos a palavra 'VIDA'.

 lcd.print("VIDA");

Para continuar, posicionamos o cursor na próxima linha.

lcd.setCursor(4,2);

E escrevemos as palavras "DE SILICIO".

lcd.print("DE SILICIO");

Para finalizar, posicionamos o cursor no início da última linha.

lcd.setCursor(0,3);

Neste momento, iremos proceder da mesma maneira que fizemos na primeira linha, preenchendo a mesma com '*'.

lcd.print("********************");

Veja como ficou nossa função loop():

void loop()
{
  lcd.setCursor(0,0);
  lcd.print("********************");
  lcd.setCursor(0,1);
  lcd.print("aaaaaaaaaaaaaa");
  lcd.setCursor(0,2);
  lcd.print("ssssssssssssssss");
  lcd.setCursor(0,3);
  lcd.print("ddddddddddddddd");
}

Adaptando o programa para o display LCD 16x2

Para adaptar esse programa para o LCD 16x2 você precisa ter em mente que a tela é menor. Tendo 16 colunas e 2 linhas.

- Definindo as configurações iniciais

Dentro da função setup() utilizamos a função lcd.begin()  para inicializar o Display LCD I2C 16x2, de modo que, os parâmetros utilizados são o número de colunas e o número de linhas do display, nesta ordem.

void setup()
{
 lcd.begin (16,2); //configuração para display 16x2
}

- Imprimindo informações no Display

Na manipulação do display precisamos localizar o cursor no local adequado usando o comando setCursor() . Perceba que a as posições dos espaços para escrita são dadas da seguinte forma:

Em seguida basta usar o comando lcd.print().


Considerações finais

Neste tutorial buscamos elaborar um conteúdo semelhante ao que já temos sobre a utilização de displays LCD, no entanto, neste caso, utilizamos um display que ao invés de utilizar vários pinos numa placa Arduino, este necessita apenas de 4 pinos em virtude de a comunicação ser feita através do protocolo de comunicação I2C. Esperamos que você tenha gostado deste conteúdo, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.


Sensor de Presença PIR | HC-SR501

Sensor de presença com Arduino | PIR HC-SR501

Automação residencial é claramente uma das áreas mais exploradas entre os grandes amantes de tecnologia. Nesse tutorial iremos aprender a montar um dos sistemas de automação mais comuns em nosso cotidiano, os detectores de presença e movimento. Para isso iremos abordar a utilização do Sensor de presença, também chamado de sensor de movimento, mais especificamente o Sensor PIR HC-SR501 e ensinar os procedimentos básicos na manipulação do mesmo para uso junto com Arduino.

[toc]

Sensores de Presença

É comum em alguns ambientes, tais como, banheiros não residenciais, garagens ou até mesmo corredores de edifícios, as lâmpadas acenderem de forma automática e instantânea.

Os sensores de presença possuem diversas aplicações, entre as mais populares estão a de controlar sistemas de iluminação e a de detectar a presença de invasores em alarmes.  Com certeza você já viu um desses sensores.

sensor de presença
Sensor de presença

Além da preocupação com a segurança, este tipo de comportamento automático também contribui para a economia de energia elétrica, evitando o desperdício da mesma e consequentemente para a diminuição de gastos.

Existem diversos formatos, todos com a mesma finalidade: Detectar a presença de pessoas. E como ele é capaz de fazer isso?

Sensor PIR

Todos esses sensores possuem uma coisa em comum, um sensor Piroelétrico ou também conhecido como Sensor PIR. Esse sensor é um pequeno componente capaz de detectar níveis de irradiação infravermelha emitidas pelo corpo humano.

sensor pir
Sensor PIR

Dentro desse sensor temos dois elementos piroelétricos que podem detectar uma faixa em uma faixa especifica determinados espectros de radiação.

Quando alguém passa na frente desse sensor, primeiramente a pessoa passará na zona de detecção do primeiro elemento piroelétrico e depois na zona de detecção do segundo elemento. Quando a pessoa passa pelo primeiro, ele gera um pulso de tensão na saída, quando ele passa na frente do outro, ele gera um pulso de tensão de sinal contrário. Tal como podemos ver na imagem abaixo:funcionamento sensor pir sr501

Módulo Sensor PIR HC-SR501

Para nosso sistema automático iremos usar o módulo sensor de presença HC-SR501. Uma das vantagens desse sensor é a praticidade de usá-lo unido ao seu pequeno tamanho.

Sensor de presença pir - HC SR501
Sensor de movimento PIR HC-SR501

Tal como os demais detectores de presença, ele também possui um sensor piroelétrico por baixo desse domo branco. Vale ressaltar que esse domo branco tem uma função importante, ele aumenta a zona de alcance do sensor.

Sensor PIR dentro do módulo HC-SR501
Sensor de movimento PIR dentro do módulo HC-SR501

Este módulo já vem com todo sistema para tratamento do sinal e por isso o funcionamento deste sensor é bastante simples, de modo que, basta alimentar o mesmo, esperar a inicialização completa e a partir deste momento, quando algum corpo emissor de radiação infravermelha passar pelo alcance do sensor, o pino de saída deste proporcionará um sinal de nível alto em seu terminal, que por sua vez, pode ser utilizado por uma placa Arduino como sinalização da presença de algum elemento.

O sensor HC-SR501 possui dois potenciômetros na parte traseira onde, em um deles é possível selecionar o tempo em que o pino de saída citado ficará em nível alto quando o sensor detectar algo (este tempo pode variar de 5 segundos a 2 minutos e meio), enquanto o segundo possui a funcionalidade de ajustar a distância máxima de percepção do sensor, de modo que, é possível configurar esta sensibilidade para valores em torno de 3 a 7 metros.

Módulo sensor de presença PIR HC-SR501
Módulo sensor de presença PIR HC-SR501

Mãos à obra – Detectando elementos com o Sensor de presença - Sensor PIR HC-SR501

Componentes utilizados:

Montando o projeto

Na figura abaixo, o leitor poderá conferir como foi realizada a montagem do projeto apresentado neste tutorial.  Lembre-se de montar o projeto com o seu Arduino desligado.

esquema de montagem do sensor de presença e movimento pir HC-SR501 com o Arduino micro

Veja como ficou o nosso:

montagem do projeto de sensor pir na prática

Programando

Antes de adentrarmos na apresentação do código, disponibilizamos uma seção para ajudar aqueles que são iniciantes no assunto. Sinta-se livre para prosseguir caso você já tem domínio da IDE do Arduino.

Conectando o Arduino ao computador

Primeiramente, conecte seu Arduino ao computador e abra a IDE Arduino. Em seguida, é necessário selecionar a porta COM na qual o Arduino está conectado (este procedimento pode ser feito clicando no menu Ferramentas (tools) e em seguida escolhendo-se a porta correspondente no submenu Porta (port). Neste caso, a porta na qual está o Arduino é apresentada da seguinte maneira: COM3 (Arduino Micro).

Por fim, garanta também que o tipo de placa apropriado esteja selecionado (isso pode ser feito acessando o menu Ferramentas (tools) e o submenu Placa (board)).

– Código do projeto

Segue o código a ser utilizado no Arduino para Detectar um elemento com o sensor de Presença PIR - HC-SR501

bool estadoSensor;

void setup() {
   
  pinMode(2,OUTPUT);
  pinMode(3,INPUT);
 
}
 
void loop() {  
   
  estadoSensor = digitalRead(3);

  if (estadosensor == HIGH)
  {
      digitalWrite(2, HIGH);
  } 
  else 
  {
      digitalWrite(2, LOW);
  }

Entendendo a fundo

Software

- Declarando a variável responsável por armazenar o estado do sensor

O primeiro passo no desenvolvimento do código apresentado anteriormente consiste em criar uma variável booleana, ou seja, uma variável que pode assumir apenas dois estados (nível alto e nível baixo, 1 e 0, high e low, entre outras nomenclaturas). Esta variável será utilizada para armazenar a informação proveniente do sensor de presença.

bool estadoSensor;

- Definindo as configurações iniciais

O definição das configurações iniciais do programa ocorre dentro da função setup(). Em um primeiro momento, determinamos o modo de operação do pino 2 como um pino de saída digital (este pino estará conectado ao led responsável por sinalizar quando o sensor detectou algo).

pinMode(2,OUTPUT);

Em seguida, definimos o pino conectado ao sensor de presença como um pino de entrada digital, também através da função pinMode().

pinMode(3,INPUT);

Veja como ficou nossa função setup()

void setup() {
   
  pinMode(2,OUTPUT);
  pinMode(3,INPUT);
 
}

- Detectando a presença

O primeiro procedimento para realizar a detecção de presença corresponde à leitura do nível lógico retornado pelo sensor em um determinado instante. Isto é feito por meio da função digitalRead().

estadoSensor = digitalRead(3);

Posteriormente, utilizamos a função if() para conferir o valor referente ao estado do sensor (armazenado na variável estadoSensor), de modo que, caso o mesmo esteja em nível alto, o conteúdo da função if() será executado.

 if (estadosensor == HIGH)
 {
      ****** Conteúdo da função if() ******
 }

Caso a sentença da função if() seja verdadeira, o Arduino deverá acender o led através da função digitalWrite().

digitalWrite(2, HIGH);

Em contrapartida, caso a condição da função if() não seja satisfeita, ou seja, caso a saída do sensor de presença seja um sinal em nível baixo, deve-se apagar o led.

else 
{
      digitalWrite(2, LOW);
}

Desafio

Agora que sabemos usar o sensor de presença e movimento, que tal usar um módulo relé para acender uma lâmpada? Seria uma boa ideia para automatizar o seu quarto, o que acha?

Faça isso:

  • Ligue uma lâmpada quando detectar movimento no ambiente (Leia nosso Tutorial sobre módulo relé) .

Considerações finais

Neste tutorial demonstramos os procedimentos básicos para utilizar o sensor de presença e movimento HC-SR501 com o Arduino. Esperamos que você tenha gostado deste conteúdo, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.


RTC3231 Registrando data e hora

RTC DS3231 - Registrando data e hora com Arduino

RTC DS3231 - Registrando data e hora com Arduino 

Bem sabemos como o tempo é a variável mais importante do mundo e da nossa vida. Nos organizamos a partir de horários e datas e por isso precisamos de relógios e agendas para nos guiar a todo momento. Se queremos construir sistemas inteligentes que auxiliam nossas atividades cotidianas, é fundamental saber como manter nosso Arduino sincronizado com a hora e a data do local onde estamos.  Pensando nisso, elaboramos este tutorial voltado para contemplar o uso de um Relógio de Tempo Real (Real-Time Clock) em conjunto com uma placa Arduino, em especial o RTC DS3231.  

Neste conteúdo será demonstrado como utilizar o RTC em questão para adquirir valores de data e hora, assim como, envia-los, por exemplo, através da porta serial para que o leitor possa conferir o resultado do projeto.  Além disso, explicaremos também a importância desse módulo.

[toc]

O que é um RTC?

Um RTC, do inglês Real-Time Clock, é um elemento que possibilita o registro de valores de data e hora no decorrer do tempo. Em poucas palavras, um RTC é um relógio em que o usuário indica os valores iniciais de data e hora, para que então, a partir destes, o mesmo passe a contar o tempo por conta própria (geralmente este dispositivo possui uma fonte de energia própria (como a apresentada na figura abaixo) para manter continuamente os valores de data e hora, de modo que, se o equipamento ao qual o RTC está conectado, ficar sem alimentação, a contagem do tempo não é interrompida).

Note que este tipo de dispositivo existe dentro de muitos aparelhos, como relógios digitais, despertadores, microondas,  entre outros, que mesmo após serem desligados, podem manter a contagem correta do tempo até serem ligados novamente .

 

Exemplo de uma bateria de um RTC em uma placa mãe de um computador

 

Caso você já tenha desmontando um computador certamente já viu uma bateria como a da imagem acima. Ela está associada ao circuito de um circuito RTC, que por sua vez, é responsável por manter seu computador com a data e a hora atualizadas mesmo estando desligado. Quando o horário e data do computador começam a ficar defasados dos valores reais da região, deve-se ficar atento, pois, este pode ser um sinal de que está na hora de trocar esta bateria.

As funções delay() e millis()

Quando um programa é desenvolvido para ser inserido em uma placa Arduino, de modo que, este tenha alguma relação com o conceito de tempo, fala-se, na maioria das vezes em progressão de tempo, por exemplo, pode-se determinar que o Arduino execute uma ação x após alguns segundos de ocorrência de uma condição y. Em grande parte destes casos, a função delay() é suficiente para atingir o objetivo proposto, ao passo que, em alguns casos é mais conveniente a utilização da função millis().

  • delay(): Pausa o programa por um certo tempo (especificado em milissegundos).
  • millis(): Retorna um número (em milissegundos) referente ao tempo que passou desde que o programa atual inserido na placa Arduino começou a rodar.

Note que a função millis() pode ser utilizada para determinar se uma certa quantidade de tempo já se passou, porém, sem que haja algum tipo de "congelamento" do programa que está rodando no Arduino.

Por que utilizar um RTC junto com um Arduino?

Como dito anteriormente, a função millis() atua como um contador, de modo que este, é incrementado a cada momento, no entanto, quando o Arduino for desligado, este contador começará novamente do zero. Por este motivo, pode-se utilizar um RTC para ter um controle melhor sobre a progressão do tempo.

Além disso, é importante saber que a função millis() retorna um elemento do tipo unsigned long (que representa a quantidade de milissegundos), que por sua vez, possui o tamanho de 32 bits. Com esta informação, pode-se chegar a conclusão de que com este tipo de dado pode-se realizar a contagem do tempo em aproximadamente 50 dias, ou seja, pouco menos de 2 meses até que o contador seja reiniciado. Em contrapartida, a autonomia de um RTC pode chegar a 10 anos dependendo do modelo do mesmo e da bateria utilizada.

Características do RTC DS3231

O RTC que será utilizado no desenvolvimento do projeto proposto neste tutorial é o RTC DS3231. Este RTC consiste em um relógio de tempo real de alta precisão, baixo consumo de energia e baixo custo. Este módulo é capaz de trabalhar com informações como segundos, minutos, horas, dias, meses, anos e ainda é capaz de ajustar-se automaticamente em casos de meses com menos de 31 dias e em situações de ocorrência de anos bissextos. Além disso, o RTC DS3231 pode operar tanto no formato 12 horas (utilizando a nomenclatura AM/PM) como no formato 24 horas.

RTC DS32312
RTC DS32312

Ao lado das características citadas, também deve-se ressaltar que o RTC DS3231 se comunica com uma placa Arduino através do protocolo I2C (onde os dados são transferidos através de um barramento bidirecional) e que o mesmo possui um compartimento para que seja inserida uma bateria externa (em caso de falha de energia no elemento principal, esta é automaticamente acionada para manter o controle sobre a passagem do tempo), um sensor de temperatura embutido, dois alarmes programáveis, além de outras características mais avançadas que serão apresentadas em tutoriais posteriores.


Mãos à obra - Realizando a aquisição dos valores de data e hora com o Arduino

Componentes utilizados:

Montando o projeto

Na figura abaixo, o leitor poderá conferir como foi realizada a montagem do projeto apresentado neste tutorial.  Lembre-se de montar o projeto com o seu Arduino desligado.

 

Veja como ficou o nosso:

 

Programando

Antes de adentrarmos na apresentação do código, disponibilizamos uma seção para ajudar aqueles que são iniciantes no assunto. Sinta-se livre para prosseguir caso você já tem domínio da IDE do Arduino.

Conectando o Arduino ao computador

Primeiramente, conecte seu Arduino ao computador e abra a IDE Arduino. Em seguida, é necessário selecionar a porta COM na qual o Arduino está conectado (este procedimento pode ser feito clicando no menu Ferramentas (tools) e em seguida escolhendo-se a porta correspondente no submenu Porta (port). Neste caso, a porta na qual está o Arduino é apresentada da seguinte maneira: COM3 (Arduino Micro).

 

 

Por fim, garanta também que o tipo de placa apropriado esteja selecionado (isso pode ser feito acessando o menu Ferramentas (tools) e o submenu Placa (board)).

 

- Biblioteca

Para desenvolver o projeto proposto com o RTC DS3231 utilizou-se uma biblioteca capaz de atuar sobre o protocolo I2C para facilitar os processos de endereçamento e troca de dados que fazem parte do funcionamento do protocolo citado. Esta biblioteca foi produzida por  Jarzebski e pode ser encontrada aqui.

Adquirindo e instalando a biblioteca que será utilizada

Para adquirir a biblioteca em questão, basta acessar o link apresentado anteriormente, clicar no botão clone or Download e por fim, no botão Download ZIP, conforme a figura abaixo.

Após a realização do download dos arquivos compactados no formato ZIP, abra a IDE do Arduino, selecione o menu Sketch, o submenu Incluir Bilioteca e por fim, basta clicar na opção Adicionar biblioteca .ZIP (Add ZIP Library) e encontrar o arquivo que acabou de ser baixado.

 

 

Uma outra forma de fazer isso é extrair o conteúdo do arquivo ZIP dentro da pasta Libraries (onde foi instalada a IDE do Arduino).

- Código do projeto

Segue o código a ser utilizado no Arduino para imprimir os valores de data e hora no Serial Monitor.

#include <Wire.h>        //Biblioteca para manipulação do protocolo I2C
#include <DS3231.h>      //Biblioteca para manipulação do DS3231

DS3231 rtc;              //Criação do objeto do tipo DS3231
RTCDateTime dataehora;   //Criação do objeto do tipo RTCDateTime

void setup()
{
  Serial.begin(9600);     //Inicialização da comunicação serial
  rtc.begin();            //Inicialização do RTC DS3231

  rtc.setDateTime(__DATE__, __TIME__);   //Configurando valores iniciais 
                                         //do RTC DS3231
}

void loop()
{
  dataehora = rtc.getDateTime();     //Atribuindo valores instantâneos de 
                                     //data e hora à instância dataehora


  Serial.print(dataehora.year);     //Imprimindo o Ano   
  Serial.print("-");
  Serial.print(dataehora.month);    //Imprimindo o Mês
  Serial.print("-");
  Serial.print(dataehora.day);      //Imprimindo o Dia
  Serial.print(" ");
  Serial.print(dataehora.hour);     //Imprimindo a Hora
  Serial.print(":");
  Serial.print(dataehora.minute);   //Imprimindo o Minuto
  Serial.print(":");
  Serial.print(dataehora.second);   //Imprimindo o Segundo
  Serial.println("");

  delay(1000);     //Tempo p atualização do valor enviado pela porta
                   //serial
}

Nota: é importante ler a seção Entendendo a fundo deste tutorial para entender como funciona o ajuste de data e hora.

Após escrever o código, salve e depois clique em Carregar (Upload) para que o programa seja transferido para seu Arduino.

Colocando para funcionar

Para verificar o resultado da gravação deste código no Arduino Micro basta acessar o Serial Monitor (para realizar este procedimento, basta utilizar o atalho Ctrl+Shift+M). Espera-se que o leitor consiga obter um resultado semelhante ao demonstrado a seguir.

 

RTC DS32312 resposta
RTC DS32312 resposta

Entendendo a fundo

Software

- Incluindo as bibliotecas a serem utilizadas no projeto

Inicialmente, observe que foi necessário incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca wire.h é a responsável pela comunicação utilizando o protocolo I2C enquanto a biblioteca DS3231.h atua sobre a biblioteca wire.h simplificando o processo de comunicação através do protocolo citado, para que assim, o usuário possa utilizar o RTC DS3231 de maneira mais fácil.

#include <Wire.h>
#include <DS3231.h>

- Declarando os objetos rtc e dataehora

Em seguida, cria-se dois objetos que serão utilizados posteriormente, de modo que, um destes é do tipo DS3231, chamado rtc (que representará o RTC DS3231 no código) e outro do tipo RTCDateTime, chamado dataehora (que será responsável por manipular os valores de data e hora existentes).

Lembre-se: rtc e dataehora são apenas nomes, sendo assim, é importante ressaltar que, os objetos identificados por rtc e dataehora poderiam ser chamados de quaisquer outros nomes, como por exemplo, modulo e informacaoatual, respectivamente.

DS3231 rtc;                //construindo o objeto rtc da classe DS3231
RTCDateTime dataehora;     //construindo o objeto dataehora da classe RTCDateTime

- Definindo as configurações iniciais

Primeiramente, na função setup(), utiliza-se a função Serial.begin() para inicializar a comunicação serial do Arduino Micro com o computador  (onde será possível ver o resultado do projeto)

 Serial.begin(9600);

Em seguida, utiliza-se a função rtc.begin() (repare que o nome rtc corresponde ao objeto criado anteriormente) para inicializar o RTC DS3231.

rtc.begin();

Posteriormente, recorre-se à função rtc.setDateTime() para configurar os valores iniciais do RTC DS3231, ou seja, os valores de data e hora que servirão de ponto de partida para o mesmo.

Conforme será explicado em seguida, na seção Ajuste de hora do RTC, ao passarmos __DATE__, __TIME__ como parâmetros da função rtc.setDateTime(), fazemos com que os valores iniciais de data e hora do RTC DS3231 sejam correspondentes ao momento da compilação do código.

rtc.setDateTime(__DATE__, __TIME__);

De acordo com a explicação dada, a função setup() deve possuir o seguinte conteúdo:

void setup()
{
  Serial.begin(9600);

  rtc.begin();

  rtc.setDateTime(__DATE__, __TIME__); 
}

- Aquisição dos valores de data e hora

Na função loop(), utiliza-se primeiramente a função rtc.GetDateTime() para atribuir os valores de data e hora de um determinado momento ao objeto dataehora. Neste momento é importante ressaltar que o objeto em questão irá conter várias informações (segundo, minuto, hora, dia, mês e ano), que por sua vez, podem ser acessadas separadamente.

dataehora = rtc.getDateTime();

Imagine que seja necessário extrair a informação referente ao ano que o RTC DS3231 está registrando. Para isso, basta referir-se ao objeto dataehora por dataehora.year. Portanto, se quisermos enviar o valor do ano através da porta serial, deve-se utilizar dataehora.year como argumento da função Serial.print().

Serial.print(dataehora.year);

Observe as demais correspondências na figura abaixo:

 

 

Por fim, veja como ficou a função loop() (perceba que ao final da mesma existe uma função delay() determinando a disponibilização das informações a cada um segundo).

void loop()
{
  dataehora = rtc.getDateTime();

  Serial.print(dataehora.year);   //Imprimindo o ano
  Serial.print("-");
  Serial.print(dataehora.month);  //Imprimindo o mês
  Serial.print("-");
  Serial.print(dataehora.day);    //Imprimindo o dia
  Serial.print(" ");
  Serial.print(dataehora.hour);   //Imprimindo a hora
  Serial.print(":");
  Serial.print(dataehora.minute); //Imprimindo os minutos
  Serial.print(":");
  Serial.print(dataehora.second); //Imprimindo os segundos  
  Serial.println("");

  delay(1000);
}

 

Hardware

As ligações realizadas no hardware em questão são bem simples, de modo que, deve-se lembrar apenas, que a comunicação entre o RTC DS3231 e uma placa Arduino é dada através do protocolo I2C, portanto, no Arduino Micro, além dos pinos referentes à alimentação do módulo, utilizou-se os pinos SDA (pino 3, responsável pela troca de dados entre os dispositivos) e SCL (pino 4, responsável pela sincronização entre os dispositivos). No RTC DS3231 estes pinos estão nomeados, portanto, são de fácil identificação.


Ajuste de hora do RTC

É importante que nosso RTC esteja com a hora correta, portanto, torna-se necessário saber como mante-lo com a hora ajustada.

Primeiramente, note que no código apresentado anteriormente, fizemos o uso um recurso muito interessante, disponibilizado pela biblioteca DS3231.h. Este recurso consiste na utilização dos parâmetros __DATE__ e __TIME__ dentro da função rtc.setDateTime(), que por sua vez, fazem com que os valores data e hora da compilação sejam usados para ajustar a data e a hora do nosso módulo RTC DS3231.

rtc.setDateTime(__DATE__, __TIME__);

Neste momento, o leitor deve estar atento a um pequeno detalhe: Apesar da função apresentada anteriormente determinar os valores iniciais de data e hora do RTC de acordo com o momento da compilação, caso o seu Arduino seja reiniciado, o ele irá definir novamente as informações de partida do módulo RTC DS3231 com os valores referentes ao momento da compilação realizada anteriormente (e não com as dados de data e hora de quando ele foi reiniciado, pois, sempre que o Arduino for ligado, o conteúdo da função setup() será executado e consequentemente, a função rtc.setDateTime() também), portanto, teremos um relógio desatualizado.

Solução para o ajuste dos valores de data e hora

O ideal é que a gravação do programa no Arduino seja feita duas vezes:

  1. Na primeira vez você deve enviar o código tal como apresentado anteriormente.
  2. Em seguida, você terá que modificar a função setup(), comentando ou excluindo a linha que contém a função de ajuste de data e hora, para então, gravar novamente o programa no Arduino.

Primeira gravação:

#include <Wire.h>        //Biblioteca para manipulação do protocolo I2C
#include <DS3231.h>      //Biblioteca para manipulação do DS3231

DS3231 rtc;              //Criação do objeto do tipo DS3231
RTCDateTime dataehora;   //Criação do objeto do tipo RTCDateTime

void setup()
{
  Serial.begin(9600);     //Inicialização da comunicação serial
  rtc.begin();            //Inicialização do RTC DS3231

  rtc.setDateTime(__DATE__, __TIME__);   //Configurando valores iniciais 
                                         //do RTC DS3231
}

void loop()
{
  dataehora = rtc.getDateTime();     //Atribuindo valores instantâneos de 
                                     //data e hora à instância dataehora


  Serial.print(dataehora.year);     //Imprimindo o Ano   
  Serial.print("-");
  Serial.print(dataehora.month);    //Imprimindo o Mês
  Serial.print("-");
  Serial.print(dataehora.day);      //Imprimindo o Dia
  Serial.print(" ");
  Serial.print(dataehora.hour);     //Imprimindo a Hora
  Serial.print(":");
  Serial.print(dataehora.minute);   //Imprimindo o Minuto
  Serial.print(":");
  Serial.print(dataehora.second);   //Imprimindo o Segundo
  Serial.println("");

  delay(1000);     //Tempo p atualização do valor enviado pela porta
                   //serial
}

Segunda gravação:

#include <Wire.h>        //Biblioteca para manipulação do protocolo I2C
#include <DS3231.h>      //Biblioteca para manipulação do DS3231

DS3231 rtc;              //Criação do objeto do tipo DS3231
RTCDateTime dataehora;   //Criação do objeto do tipo RTCDateTime

void setup()
{
  Serial.begin(9600);     //Inicialização da comunicação serial
  rtc.begin();            //Inicialização do RTC DS3231

  //rtc.setDateTime(__DATE__, __TIME__);   *******ESTA LINHA DEVE SER COMENTADA OU EXCLUÍDA*******
}

void loop()
{
  dataehora = rtc.getDateTime();     //Atribuindo valores instantâneos de 
                                     //data e hora à instância dataehora


  Serial.print(dataehora.year);     //Imprimindo o Ano   
  Serial.print("-");
  Serial.print(dataehora.month);    //Imprimindo o Mês
  Serial.print("-");
  Serial.print(dataehora.day);      //Imprimindo o Dia
  Serial.print(" ");
  Serial.print(dataehora.hour);     //Imprimindo a Hora
  Serial.print(":");
  Serial.print(dataehora.minute);   //Imprimindo o Minuto
  Serial.print(":");
  Serial.print(dataehora.second);   //Imprimindo o Segundo
  Serial.println("");

  delay(1000);     //Tempo p atualização do valor enviado pela porta
                   //serial
}


Considerações finais

Neste tutorial elaboramos um conteúdo introdutório sobre o RTC DS3231 visando apresentar os conceitos básicos de funcionamento do mesmo e como utiliza-lo em conjunto com uma placa Arduino. Esperamos que você tenha gostado deste conteúdo, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.

 


HC-SR04 - Sensor Ultrassônico com Arduino

HC-SR04 - Sensor Ultrassônico de distância com Arduino

O sensor ultrassônico HC SR04 é amplamente utilizado em aplicações onde se deseja medir distância ou evitar colisões, como na robótica móvel e de reabilitação. Neste tutorial aprenderemos como utilizar o Módulo Sensor HC-SR04 com Arduino.

Sensor Distância Ultrassônico HCSR04, HC-SR04 ou HC SR04
Sensor Distância Ultrassônico HC SR04

Sensor Ultrassônico HC-SR04

Tudo começa pela emissão de um pequeno pulso sonoro de alta frequência que se propagará na velocidade do som no meio em questão. Quando este pulso atingir um objeto, um sinal de eco será refletido para o sensor. A distância entre o sensor e o objeto pode então ser calculada caso saibamos o tempo entre a emissão e a recepção do sinal, além da velocidade do som no meio em questão. Afigura a seguir exemplifica o processo.

sensor ultrassônico HC-SR04 funcionamento
Sensor ultrassônico HC-SR04

Para uma melhor medição da distância, a área do objeto na qual a onda será refletida deve ser de pelo menos 0,5 m2.


Mãos à obra - Medindo distância com o HC-SR04

Componentes necessários:

Montando o projeto

Agora vamos conectar os componentes do projeto. Para isso, desligue o cabo USB de seu Arduino e monte seu circuito conforme a figura a seguir.

esquema de montagem do Arduino uno com Sensor ultrassonico HC-SR04, HCSR04

O HC SR04 possui 4 pinos sendo eles:

  • Vcc – Deve ser conectado a um pino 5V do Arduino.
  • Trig – Deve ser conectado a um pino digital configurado como saída. Utilizaremos o pino 8.
  • Echo – Deve ser conectado a um pino digital configurado como entrada. Utilizaremos o pino 7.
  • Gnd – Deve ser conectado a um pino GND do Arduino.

Programando

Crie um no programa (sketch) e salve com o nome de “programa_ultrassom_hcsr04”.

Nesse exemplo utilizaremos a biblioteca Ultrasonic.h. A utilização dessa biblioteca é bastante simples.

Clique aqui para baixa a biblioteca Ultrasonic.h
Clique aqui para baixar a biblioteca Ultrasonic.h

- Instalar a biblioteca pelo IDE do Arduino

Esse é o método mais fácil. Primeiramente, faça o download dos arquivos da biblioteca compactados no formato zip. Geralmente as bibliotecas já são distribuídas compactadas, porém às vezes é necessário fazer o download dos arquivos separadamente e compactá-los à parte. Em seguida, basta abrir o IDE e ir em “Sketch -> Incluir Biblioteca -> Adicionar biblioteca .ZIP” E selecionar o aquivo baixado:

Imagem explicando como adicionar uma biblioteca IDE Arduino

Com isso, a nova biblioteca foi instalada. Para utilizá-la, basta ir em “Sketch -> Incluir Biblioteca” e selecionar a biblioteca desejada.

Você pode ver mais detalhes sobre como adicionar uma biblioteca no tutorial Sensores DHT11 e DHT22 e o Uso de Bibliotecas.

- Código exemplo

Com o seu programa salvo, escreva nele o código abaixo:

//Leitura de distância com o sensor HC-SR04
#include <Ultrasonic.h>
 Ultrasonic ultrassom(8,7); // define o nome do sensor(ultrassom)
//e onde esta ligado o trig(8) e o echo(7) respectivamente

long distancia;

// Esta função "setup" roda uma vez quando a placa e ligada ou resetada
 void setup() {
 Serial.begin(9600); //Habilita Comunicação Serial a uma taxa de 9600 bauds.
 
 }

// Função que se repete infinitamente quando a placa é ligada
 void loop()
 {
   distancia = ultrassom.Ranging(CM);// ultrassom.Ranging(CM) retorna a distancia em
                                     // centímetros(CM) ou polegadas(INC)
   Serial.print(distancia); //imprime o valor da variável distancia
   Serial.println("cm");
   delay(100);
 }

Após escrever o código, salve e depois clique em Carregar (Upload) para que o programa seja transferido para seu Arduino.

Colocando para funcionar

Abra o Serial Monitor e coloque um obstáculo na frente do sensor ultrassônico. Se tudo deu certo, conforme você variar a distância do obstáculo em relação ao sensor, a distância medida aparecerá no serial monitor, tal como a figura a seguir.

monitor serial sensor ultrassônico HC-SR04 distância


Entendendo a fundo

Entendendo o Software

- Biblioteca Ultrasonic.h

Na elaboração do software utilizaremos a biblioteca Ultrasonic.h. Essa biblioteca implementa as funcionalidades do sensor ultrassom HC-SR04, tornando sua utilização extremamente simples.

- Declarando um Ultrassom

Para o uso dessa biblioteca devemos definir o nome do sensor e em quais pinos estão conectados os pinos trig e echo.

Ultrasonic nomesensor(trig,echo);

No exemplo a seguir, o nome do sensor é ultrassom, o pino do trig está conectado na porta 8 e o pino do echo na porta 7.

Ultrasonic ultrassom(8,7);

- Medindo a distância

Para ler a distância, basta chamar a função Ranging(CM). Para valor em centímetros, deve-se usar CM e para valor em polegadas, deve-se usar INC. Essa função retorna um valor de variável long.

long distancia = ultrassom.Ranging(CM); // distancia recebe o valormedido em cm

Observe que usamos o nome do sensor escolhido, no nosso caso ultrassom, seguido de ponto e o nome da função que queremos usar. Para o Arduino estamos falando que queremos usar determinada função do objeto mencionado, no nosso caso o ultrassom.

- Imprimindo na porta serial

Para imprimir o valor de distância lido usamos a função Serial.print().

Serial.print(distancia); //imprime o valor da variável distancia
Serial.println("cm");

Repare que na primeira linha imprimimos o valor da variável distância e na segunda linha imprimimos a palavra cm, que está entre aspas duplas. Sempre que quisermos imprimir um texto devemos colocá-lo dentro de aspas duplas, caso contrário o programa irá entender que o texto é o nome de uma variável.

Repare também que na segunda linha usamos o sufixo -ln depois de print. Esse sufixo informa que depois de escrito o texto, o programa deve pular uma linha.

Entendendo o Hardware

Como dito anteriormente, o sensor ultrassom mede a distância através da medição do tempo que uma onda leva para sair do emissor, colidir com um obstáculo e ser refletido, para, finalmente, ser detectado pelo receptor. Desta forma, podemos notar que nosso sensor ultrassom possui dois cilindros metálicos que se assemelham a olhos em sua placa. São, na realidade, dois altos falantes: um trabalha como o emissor do sinal ultrassom e o outro como receptor.

sensor ultrassônico HC-SR04
Sensor ultrassônico HC-SR04

- Fazendo a leitura do tempo

Para iniciarmos uma medição, o pino Trig, que funciona como gatilho do nosso sensor ultrassom, deve receber um pulso de 5V por pelo menos 10 microssegundos. Isso fará com que o sensor HC-SR04 emita 8 pulsos ultrassônicos em 40kHz (T piezzo) e o pino ECHO, que funcionará como nosso cronômetro, vai para 5V, iniciando assim a espera pelas ondas refletidas.

Assim que uma onda refletida for detectada, o pino Echo, que estava em 5V, será alterado para 0V. Desta forma, o período que o pino Echo fica em 5V é igual ao tempo que a onda emitida leva para ir até o obstáculo e voltar.

Veja a imagem abaixo para entender o que acontece no sensor HC-SR04.

gráfico de pulsos no sensor HCSR04, HC-SR04 ou HC SR04

Por fim, para sabermos quão longe nosso obstáculo está, basta contarmos quanto tempo (T) a tensão no pino Echo ficou em 5V. Em posse desse tempo, sabendo que ele é o dobro do tempo de ida e volta da onda do sensor ultrassônico até o obstáculo, e, considerando a velocidade do som igual a 340,29 m/s, temos:

formula som

Desta forma, temos que a distância até o obstáculo é igual a ΔS.

A função Ultrasonic.h faz exatamente o procedimento descrito, retornando apenas o valor da distância.

Outra opção de código

Poderíamos seguir o procedimento explicado usando o seguinte código:

// Leitura HC-SR04
const uint8_t trig_pin = 10;
const uint8_t echo_pin = 9;

uint32_t print_timer;

void setup() {
Serial.begin(9600); // Habilita Comunicação Serial a uma taxa de 9600 bauds.

// Configuração do estado inicial dos pinos Trig e Echo.
pinMode(trig_pin, OUTPUT);
pinMode(echo_pin, INPUT);
digitalWrite(trig_pin, LOW);
}

void loop() {
// Espera 0,5s (500ms) entre medições.
if (millis() - print_timer > 500) {
print_timer = millis();

// Pulso de 5V por pelo menos 10us para iniciar medição.
digitalWrite(trig_pin, HIGH);
delayMicroseconds(11);
digitalWrite(trig_pin, LOW);

/* Mede quanto tempo o pino de echo ficou no estado alto, ou seja,
o tempo de propagação da onda. */
uint32_t pulse_time = pulseIn(echo_pin, HIGH);

/* A distância entre o sensor ultrassom e o objeto será proporcional a velocidade
do som no meio e a metade do tempo de propagação. Para o ar na
temperatura ambiente Vsom = 0,0343 cm/us. */
double distance = 0.01715 * pulse_time;

// Imprimimos o valor na porta serial;
Serial.print(distance);
Serial.println(" cm");
}
}

Desafio

Sabendo como funciona um sensor ultrassônico, faça o programa que meça a distância sem o auxílio da biblioteca.

Fechamento

Esperamos que tenham gostado, deixe seu comentário com duvidas, sugestões ou com a foto ou vídeo de seu projeto!! Compartilhe à vontade.

 

Apostila Arduino Básico

 


DHT11 e DHT22 | Sensor de umidade e Temperatura com Arduino

DHT11 e DHT22,  Sensor de umidade e Temperatura com Arduino

Umidade e temperatura são duas grandezas que estão muito relacionadas quando o assunto é climatização. Nesse tutorial você aprenderá a medir essas duas grandezas através do sensor de umidade e temperatura DHT11 ou o DHT22 em conjunto com um Arduino.

[toc]

Sensores de umidade e temperatura DHT11 e DHT22

O sensor DHT11 e o sensor DHT22 são sensores básicos e de baixo custo que utilizam um termistor e um sensor capacitivo para medir a temperatura e a umidade do ar ambiente.

Esses sensores são bastante simples de usar, mas requer cuidado com o tempo entre duas leituras consecutivas, uma vez que é necessário um intervalo de, no mínimo, 1 segundo entre uma leitura e outra.

SensorDHT11 (azul) e DHT22 (branco)
Sensor DHT11 (azul) e DHT22 (branco)

Existem diferentes versões do DHT, similares na aparência e na pinagem, porém com características diferentes. As características do DHT11 e DHT22, dois modelos populares desse sensor, são:

Sensor DHT11

  • Muito baixo custo
  • Tensão de alimentação de 3V a 5V
  • 2.5mA de corrente máxima durante a conversão
  • Bom para medir umidade entre 20% e 80%, com 5% de precisão
  • Bom para medir temperaturas entre 0 e 50°C, com ±2°C de precisão
  • Taxa de amostragem de até 1Hz (1 leitura por segundo)
  • Dimensões: 15.5mm x 12mm x 5.5mm
  • 4 pinos com 0.1" de espaçamento entre eles

Sensor DHT22

  • Baixo custo
  • Tensão de alimentação de 3V a 5V
  • 2.5mA de corrente máxima durante a conversão
  • Bom para medir umidade entre 0% e 100%, com 2% a 5% de precisão
  • Bom para medir temperaturas entre -40 e 125°C, com ±0,5°C de precisão
  • Taxa de amostragem de até 0,5Hz (2 leituras por segundo)
  • Dimensões: 15.1mm x 25mm x 7.7mm
  • 4 pinos com 0.1" de espaçamento entre eles

Como pode ser observado, o DHT22 é um pouco mais preciso e trabalha em uma faixa um pouco maior de temperatura e umidade. Porém, ambos utilizam apenas um pino digital e são relativamente lentos, visto que é necessário um intervalo de tempo relativamente grande entre cada leitura.


Incluindo Bibliotecas

Uma grande vantagem das placas Arduino é a grande diversidade de bibliotecas disponíveis que podem ser usadas em seu programa. Isso faz com o trabalho pesado em programação seja abstraído e resumido em simples comandos.

Com isso, o desenvolvedor não precisa de conhecimento muito aprofundado em programação, podendo gastar menos tempo nisso, resultando em mais tempo para trabalhar com empenho na estratégia de controle.

A seguir, iremos aprender como adicionar uma biblioteca em sua IDE. Esse mesmo procedimento será usado para outros sensores ou módulos.

Incluindo a biblioteca DHT

Para trabalhar de forma fácil com o DHT, podemos baixar uma biblioteca para ele no GitHub do Rob Tillaart (https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib).

Baixar biblioteca DHTlib - Atualizada em 24/08/2017
Baixar biblioteca DHTlib - Atualizada em 24/08/2017

Há mais de uma forma de incluir bibliotecas no seu programa, a principal é:

Instalar a biblioteca pelo IDE do Arduino

Esse é o método mais fácil. Primeiramente, faça o download dos arquivos da biblioteca compactados no formato zip. Geralmente as bibliotecas já são distribuídas compactadas, porém às vezes é necessário fazer o download dos arquivos separadamente e compactá-los à parte. Em seguida, basta abrir o IDE e ir em "Sketch -> Incluir Biblioteca -> Adicionar biblioteca .ZIP":

Imagem explicando como adicionar uma biblioteca

Na janela que abrir, selecione a biblioteca a ser adicionada:

inserindo biblioteca dht.h

Com isso, a nova biblioteca foi instalada. Para utilizá-la, basta ir em "Sketch -> Incluir Biblioteca" e selecionar a biblioteca desejada:

biblioteca dht.h na ide arduino

Observe que o IDE adicionou no início do seu código a linha incluindo a biblioteca no seu programa.:

#include <dht.h>

Outras opções:

Instalar manualmente a biblioteca

Para instalar manualmente uma biblioteca, feche o IDE do Arduino e em seguida descompacte os arquivos da biblioteca. Se os arquivos .cpp e .h não estiverem dentro de uma pasta, crie uma e mova os arquivos para lá. Em seguida, basta mover a pasta para o local:

Windows: "Meus documentos\Arduino\libraries"

Mac: "Documents/Arduino/libraries"

Depois desse processo, a biblioteca estará disponível em "Sketch -> Incluir Biblioteca" na próxima vez que o IDE for aberto.

Incluir a biblioteca sem instalá-la

É possível também utilizar a biblioteca sem instalá-la no IDE do Arduino. Para isso, basta descompactar a biblioteca e colocar os arquivos .h e .cpp no mesmo diretório do programa, incluindo no início do mesmo a linha:

#include "nome_da_biblioteca.h"

Mãos à obra – Usando o Sensor de umidade e temperatura DHT11 com Arduino

Componentes necessários

Montando o projeto

Agora vamos conectar os componentes do projeto. Para isso, desligue o cabo USB de seu Arduino e monte seu circuito conforme a figura a seguir.

Esquemático do circuito DHT11 com Arduino uno

Conectando o Arduino ao computador

Conecte seu Arduino ao computador e abra a IDE Arduino.

Antes de carregar um programa, você precisa selecionar qual porta você deseja usar para fazer carregar o programa no Arduino (upload). Dentro do Arduino IDE, clique no menu Ferramentas (tools) e abra o submenu Porta(Port). Clique na porta que seu Arduino está conectado, tal como COM3 ou COM4. Geralmente aparece o nome da placa Arduino : “COM3 (Arduino/Genuino Uno)”.

Você também precisa garantir que o tipo de placa apropriado está selecionado em Ferramentas(Tools) no submenu Placa (Board).

Programando

Crie um programa (sketch) e salve com o nome de “programa_dht11”.

Com o seu programa salvo, escreva nele o código conforme escrito abaixo.

#include <dht.h> // Inclui a biblioteca no seu código
 
dht DHT; // Cria um objeto da classe dht
uint32_t timer = 0;
 
void setup()
{
  Serial.begin(9600); // Inicializa serial com taxa de transmissão de 9600 bauds
}
 
void loop()
{
  // Executa 1 vez a cada 2 segundos
  if(millis() - timer>= 2000)
  {
 
    DHT.read11(A1); // chama método de leitura da classe dht,
                    // com o pino de transmissão de dados ligado no pino A1
 
    // Exibe na serial o valor de umidade
    Serial.print(DHT.humidity);
    Serial.println(" %");
 
    // Exibe na serial o valor da temperatura
    Serial.print(DHT.temperature);
    Serial.println(" Celsius");
 
    timer = millis(); // Atualiza a referência
  }
}

Após escrever o código, clique em Carregar (Upload) para que o programa seja transferido para seu Arduino.

Colocando para funcionar

Caso tenha ocorrido tudo conforme esperado, poderemos fazer a leitura da temperatura através do monitor serial. Abra o monitor serial para verificar o que está sendo lido na entrada A0.


Entendendo a fundo

Entendendo o Software

millis()

Retorna o número de milissegundos desde a placa Arduino começou a funcionar com programa atual. Este número irá saturar (voltar para zero), após, aproximadamente, 50 dias.

 timer = millis();         //Atualiza a referência

Veja que usamos o millis como nossa referência de tempo. Toda vez que a diferença entre o millis e o timer for de 2000 milissegundos, entraremos no if e o timer irá assumir o valor atual de millis.

Desta forma, o programa irá executar o que está dentro do if de 2000 em 2000 milissegundos, ou seja, 2 em 2 segundos.

Esse tipo de estrutura é muito comum e será usada em outras experiências.

Biblioteca dht.h

Na elaboração do software utilizamos a biblioteca dht.h. Esta biblioteca implementa as funcionalidades do sensor DHT11 e DHT22 tornando sua utilização extremamente simples.

Declarando um DHT

Ao usar essa biblioteca trataremos cada sensor DHT como um objeto, dessa forma precisamos declará-lo no início do código.

dht DHT; // Cria um objeto da classe dht

Depois de declarado, sempre que quisermos mexer em alguma função desse DHT, devemos usar o nome da função precedida do nome do DHT e ponto.

DHT.exemplo(); // chama função exemplo() para o objeto DHT

Lendo o sensor

Para ler o sensor basta chamar o método de leitura (read11 se estiver utilizando o DHT11, ou read22 se estiver utilizando o DHT22) e em seguida ler os valores nos atributos temperature e humidity.

Importante: O sensor demora no mínimo 1 segundo de intervalo entre uma leitura e outra.

DHT.read11(A1); // chama método de leitura da classe dht,
                    // com o pino de transmissão de dados ligado no pino A1

Temos o valor de umidade em porcentagem armazenado em:

float umidade = DHT.humidity

Temos o valor de temperatura em graus Celsius armazenado em:

float temperatura = DHT.temperature

Exemplo de aplicação:

    // Exibe na serial o valor de umidade
    Serial.print(DHT.humidity);
    Serial.println(" %");
 
    // Exibe na serial o valor da temperatura
    Serial.print(DHT.temperature);
    Serial.println(" Celsius");

Fechamento

Esperamos que tenham gostado, deixe seu comentário com duvidas, sugestões ou com a foto ou vídeo de seu projeto!! Compartilhe à vontade.

Tutorial feito em parceria com Ronan Largura

Apostila Arduino Básico

 


Teclado Matricial e Multiplexação

Teclado Matricial e Multiplexação

Teclados são geralmente utilizados em aplicações na qual o usuário precisar interagir com um sistema, como computadores, calculadoras, controles remotos entre outros. Imagine que desejamos utilizar um teclado com 64 botões em nossa aplicação. Caso cada botão seja ligado diretamente a um pino do microcontrolador, gastaríamos 64 pinos o que tornaria a implementação dessa interface, em uma placa Uno por exemplo, impossível. Para evitar este problema podemos conectar as teclas no formato de matriz 8x8 gastando agora apenas 16 pinos e utilizar uma técnica chamada multiplexação para realizar a leitura das teclas. Para demonstrar essa técnica de leitura utilizaremos um teclado matricial de membrana 4x4 junto com um Arduino.

Esse tutorial requer conhecimento em assuntos explicados em posts anteriores. Caso tenha dificuldades em acompanhar os assuntos abordados aqui, confira alguns de nossos tutoriais anteriores:

[toc]

O Teclado Matricial

Este teclado como o nome indica é formado de botões organizados em linhas e colunas de modo a formar uma matriz. Quando pressionado, um botão conecta a linha com a coluna na qual está ligado. A figura 1 ilustra a ligação matricial.

Figura 1 - Ligação interna de um teclado matricial 4x4.
Figura 1 - Ligação interna de um teclado matricial 4x4.

O teclado matricial possui a seguinte pinagem:

  • Pino 1 (Esquerda) - Primeira Linha (L1)
  • Pino 2  - Segunda Linha (L2)
  • ...
  • Pino 5 - Primeira Coluna (C1)
  • ...
  • Pino 8 - Quarta Coluna (C4)
Figura 2 - Pinagem do teclado matricial de membrana.
Figura 2 - Pinagem do teclado matricial de membrana.

A Multiplexação

Essa técnica consiste no compartilhamento do mesmo barramento por vários dispositivos, entretanto apenas um deles utilizará o barramento por vez. No caso do teclado matricial, os barramentos serão as linhas do teclado e os dispositivos as colunas. Logo devemos permitir que apenas uma coluna se ligue as linhas por vez. Para desconectarmos as colunas que não devem ser lidas devemos configurá-las como entradas (alta impedância).


Mão à obra - Algoritmo de varredura simples

Componentes utilizados

Para esse projeto usaremos os seguintes componentes:

Programação

No início os pinos conectados as linhas serão configurados como entradas com pull up e as colunas como entradas (alta impedância). A varredura consiste em ativar uma coluna por vez (saída em nível lógico baixo) e checar se houve uma alteração nas linhas. Caso uma alteração em uma linha seja identificada, o bounce da tecla deve ser devidamente tratado para que possamos finalmente afirmar que o botão foi pressionado.

 

const uint8_t row_size = 4;                       // Quantidade de linhas.
const uint8_t col_size = 4;                       // Quantidade de colunas.
const uint8_t row_pin[row_size] = {4, 5, 6, 7};   // Pinos que estão ligados as linhas.
const uint8_t col_pin[col_size] = {8, 9, 10, 11}; // Pinos que estão ligados as colunas.
const char keys[row_size][col_size] = {           // Mapa de teclas do teclado.
 { '1', '2', '3', 'A' },
 { '4', '5', '6', 'B' },
 { '7', '8', '9', 'C' },
 { '*', '0', '#', 'D' }
};
 
bool stable[row_size][col_size];   // Guarda o último estado estável dos botões.
bool unstable[row_size][col_size]; // Guarda o último estado instável dos botões.
uint32_t bounce_timer;
 
// Executa o algoritmo de varredura simples.
void scan() {
  for (uint8_t e = 0; e < col_size; ++e) {   // Varre cada coluna.
    pinMode(col_pin[e], OUTPUT);
    digitalWrite(col_pin[e], 0);             // Habilita a coluna "c".
    for (uint8_t r = 0; r < row_size; ++r) { // Varre cada linha a procura de mudanças.
      if (changed(r, e)) {                   // Se houver uma mudança de estado.
        Serial.print(keys[r][e]);
        Serial.print(" : ");                 // Imprime a tecla que sofreu a alteração
        Serial.println(stable[r][e]);        // e seu estado atual.
      }
    }
    pinMode(col_pin[e], INPUT);              // Desabilita a coluna "c".
  }
}
 
// Checa se o estado do botão foi alterado além de tratar os efeitos de sua trepidação.
bool changed(const uint8_t& row, const uint8_t& col) {
  bool now = digitalRead(row_pin[row]);    // Lê o estado do botão na linha especificada.
  if (unstable[row][col] != now) {         // Checa se houve mudança.
    bounce_timer = millis();               // Atualiza timer.
    unstable[row][col] = now;              // Atualiza estado instável.
  }
  else if (millis() - bounce_timer > 10) { // Checa o tempo de trepidação acabou.
    if (stable[row][col] != now) {         // Checa se a mudança ainda persiste.
      stable[row][col] = now;              // Atualiza estado estável.
      return 1;
    }
  }
  return 0;
}
 
void setup() {
  Serial.begin(9600);
 
  // Configura o estado inicial das linhas como entradas com pull up.
  for (uint8_t r = 0; r < row_size; ++r) {
    pinMode(row_pin[r], INPUT_PULLUP);
  } 
 
  // Configura o estado inicial das linhas como entradas.
  for (uint8_t c = 0; c < col_size; ++c) {
    pinMode(col_pin, INPUT);
  }
 
  // Define estado inicial dos botões;
  for (uint8_t c = 0; c < col_size; ++c) {
    for (uint8_t r = 0; r < row_size; ++r) {
      stable[r] = 1;
    }
  }
}
 
void loop() {
  scan();
}

 


Pressionando várias teclas

Quando pressionamos 3 ou mais teclas um efeito conhecido como tecla fantasma pode ocorrer, vamos observar a animação a seguir para entender o porquê:

Figura 3 - Teclas fantasmas teclado matricial
Figura 3 - Teclas fantasmas

Infelizmente os problemas não acabam por aqui. Caso a tecla fantasma seja pressionada e em seguida uma das teclas anteriores for solta, a tecla que foi solta ainda será considerada como pressionada. Para solucionarmos este problema devemos adicionar um diodo em cada botão para evitar que estes caminhos indesejados sejam formados, como mostra a Figura 4.

Figura 4 - Solução para teclas fantasmas.

 


Bibliotecas

A biblioteca Keypad é uma biblioteca especializada no interfaceamento de teclados matriciais. Seu algoritmo de varredura  consegue detectar se uma tecla esta apertada, solta ou sendo segurada, entre outras funções.

Clique para baixar a biblioteca Keypad

Exemplo de aplicação

#include <Keypad.h>
 
const uint8_t row_size = 4;                       // Quantidade de linhas.
const uint8_t col_size = 4;                       // Quantidade de colunas.
const uint8_t row_pin[row_size] = {4, 5, 6, 7};   // Pinos que estão ligados as linhas.
const uint8_t col_pin[col_size] = {8, 9, 10, 11}; // Pinos que estão ligados as colunas.
const char keys[row_size][col_size] = {           // Mapa de teclas do teclado.
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};
 
Keypad keypad = Keypad(makeKeymap(keys), row_pin, col_pin, row_size, col_size);
 
void setup() {
  Serial.begin(9600);
}
 
void loop() {
  char key = keypad.getKey();   // Retorna a última tecla que foi apertada.
  if (key != NO_KEY) Serial.println(key); // Imprime tecla na porta serial.
}

Fechamento

Esperamos que tenham gostado, deixe seu comentário com duvidas, sugestões ou com a foto ou vídeo de seu projeto!! Compartilhe à vontade.

 

Apostila Arduino Básico

 


Ponte H L298N - Controlando a velocidade de um motor DC com PWM

Ponte H L298N - Controlando a velocidade de um motor DC com PWM

No último tutorial vimos como se faz para ligar um motor DC no Arduino com o auxílio de um módulo ponte H L298n, usando suas entradas para variar o sentido de giro. Mas na robótica, é comum termos que controlar, além do sentido, a velocidade do motor. Neste tutorial iremos ensinar, de forma simples e didática, como podemos controlar a velocidade de um motor DC usando o Driver motor com Ponte H L298n com Arduino.

[toc]

Como controlar a velocidade de um motor?

Um motor DC gira baseado em campos magnéticos gerados pela corrente que passa em suas bobinas. Para variar a velocidade do motor podemos alterar essa corrente que é diretamente proporcional a tensão sobre elas.

Esquema simplificado de um motor DC
Campo magnético motor DC

Dessa forma, com a mudança da tensão em cima do motor, teremos uma alteração de velocidade. mas como podemos fazer isso usando o Arduino e a Ponte H? A solução é simples e eficiente e se chama PWM.

O que é PWM?

PWM (Pulse Width Modulation – Modulação por Largura de Pulso) é uma técnica para obter resultados analógicos por meios digitais (Leia mais sobre Grandezas digitais e analógicas e PWM). Essa técnica consiste na geração de uma onda quadrada em uma frequência muito alta em que pode ser controlada a porcentagem do tempo em que a onda permanece em nível lógico alto. Esse tempo é chamado de Duty Cycle(Ciclo de trabalho) e sua alteração provoca mudança no valor médio da onda, indo desde 0V (0% de Duty Cycle) a 5V (100% de Duty Cycle) no caso do Arduino.

O duty cycle é a razão do tempo em que o sinal permanece na tensão máxima (5V no Arduino) sobre o tempo total de oscilação, como está ilustrado na figura abaixo:

Duty Cycle (%) = (x/x+y)*100% = (x/T)*100%

Vmédio = Vmáx*Duty Cycle(%)

O valor do Duty Cycle usado pelo Arduino é um inteiro armazenado em 8 bits, de forma que seu valor vai de 0 (0%) a 255 (100%).

Exemplo.: Para um sinal PWM de valor 200 temos:

Se 255 é 100%, 200 é aproximadamente 78,4%.

Como a tensão máx de saída do Arduino é 5V a tensão média do sinal PWM será:

Vmédio = Vmax*Duty Cycle(%)

Vmédio=5*78,4%

Vmédio=3,92V

Modulando a ponte H

No módulo Ponte H com CI L298N cada ponte H possui um pino que ativa ou não a ponte H. Caso tenha um sinal de 5V inserido nele, a ponte enta ligada, caso seja 0V a ponte esta desligada. Como temos 2 pontes H, temos o Enable A(Ativa A) e o Enable B (Ativa B).

Normalmente o Enable A e B fica em curto com um sinal de 5V da placa através de um jumper.

Módulo ponte H L298n
Jumpers Enable A e B

Se retiramos esse jumper e inserimos um sinal PWM nessa entrada, modularemos a tensão que é enviada para o motor no mesmo formato. Isso ocorre porque a ponte H só ira "funcionar" enquanto o sinal de Enable estive com 5V.

Sinal PWM entrando no Enable A do módulo Ponte H L298N para controlar velocidade
Sinal PWM entrando no Enable A em vermelho (5V) e a saída para o motor A em preto (12V).

Sendo assim, a saída para o motor será um sinal PWM com um Duty Cycle igual ao do Enable e terá tensão média calculada pela seguinte formula.

Vmédio = Vmax(tensão PonteH)*Duty Cycle(%)

Com essa modulação, podemos variar a velocidade do motor através de PWM.


Mãos à obra - Controle de velocidade com Módulo Ponte H L298N - Arduino

Neste segundo exemplo, vamos verificar o controle de velocidade dos motores A e B.

Componentes necessários

Para este exemplo, utilizaremos:

Montando o projeto

Prossiga com a montagem conforme esquema abaixo(caso você use apenas um motor, basta desconsiderar o motor B:

Garanta que seu Arduino e a fonte externa estejam desligados durante a montagem.

Esquema de montagem da ponte h l298n controlar velocidade
Esquema de montagem exemplo 1

 

Programando

Crie um programa (sketch) e salve com o nome de “exemplo1_Controle_velocidade”.

Agora vamos à implementação do programa. Dessa forma, dentro da IDE Arduino: escreva o seguinte código e ao final clique em Upload para que o programa seja transferido para seu Arduino.

/*Pinagem do arduino*/

//motor_A
int IN1 = 2 ;
int IN2 = 4 ;
int velocidadeA = 3;

//motor_B
int IN3 = 6 ;
int IN4 = 7 ;
int velocidadeB = 5;

//variavel auxiliar
int velocidade = 0;

//Inicializa Pinos
void setup(){
pinMode(IN1,OUTPUT);
pinMode(IN2,OUTPUT);
pinMode(IN3,OUTPUT);
pinMode(IN4,OUTPUT);
pinMode(velocidadeA,OUTPUT);
pinMode(velocidadeB,OUTPUT);
}

void loop(){

/*Exemplo de velocidades no motor A*/

//Sentido 2
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);

//Alta
analogWrite(velocidadeA,230);

//Intermediaria
analogWrite(velocidadeA,150);

//Baixa
analogWrite(velocidadeA,80);

/*Exemplo de variacao de velocidade no motor B*/

//Sentido 2
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);

//velocidade de 0 a 255
while (velocidade < 255){
analogWrite(velocidadeB,velocidade);
velocidade = velocidade + 10;
delay(50);
}
//velocidade de 255 a 0
while (velocidade > 0){
analogWrite(velocidadeB,velocidade);
velocidade = velocidade - 10;
delay(50);
}
}

Colocando para funcionar

Se tudo deu certo, teremos o motores fazendo os seguintes movimentos:

  • Motor A gira em velocidade alta
  • Motor A gira em velocidade intermediaria
  • Motor A gira em velocidade baixa
  • Motor B vai de parado para velocidade rápida gradativamente
  • Motor B vai da velocidade rápida até totalmente parado gradativamente

Entendendo a fundo

Entendendo o Software

Primeiro definimos as pinos que estão conectados à ponte H para controle de cada motor.

//motor_A
int IN1 = 2 ;
int IN2 = 4 ;
int velocidadeA = 3;

//motor_B
int IN3 = 6 ;
int IN4 = 7 ;
int velocidadeB = 5;

Veja que temos 3 pinos para cada motor. 2 para controle de sentido de giro e o terceiro para controle de velocidade.

Movimentando o motor

Para fazer o motor se movimentar, primeiro temos que informar para que direção ele deve girar:

//Motor_A
//Sentido 2
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);

Aqui vale lembrar da tabela de comandos apresentadas no tutorial  Módulo Ponte H L298N – Controlando Motores com Arduino :

Para controlar o sentido, temos as seguintes combinações para o motor A(IN1 e IN2)

É importante ter em mente essas combinações:

//Sentido 1
digitalWrite(IN1,LOW);  //0V
digitalWrite(IN2,HIGH); //5V

//Freia Motor
digitalWrite(IN1,HIGH); //5V
digitalWrite(IN2,HIGH); //5V

//Sentido 2
digitalWrite(IN1,HIGH); //5V
digitalWrite(IN2,LOW);  //0V

Em seguida definimos a velocidade através de um sinal PWM no pino Enable A. Tal como explicado anteriormente.

//Motor_A
//Velocidade Alta
analogWrite(velocidadeA,230);
Módulo drive motor Ponte H L298n
Pino Enable A e Enable B que são usados para o controle de Velocidade no módulo Ponte H L298N.

Quando não queremos controlar a velocidade, deixamos esse pinos com um jumper ligado ao 5V da placa. Assim garantimos que a ponte H trabalhe na velocidade máxima.

Como queremos controlar sua velociade, tiramos o Jumper e conectamos a uma porta PWM.

O comando para a saída PWM é:

analogWrite(pino_de_saida,PWM);

Onde PWM , que já foi explicado no inicio do tutorial, é um valor entre 0 à 255.  Onde 0 simboliza que o ciclo de trabalho é de 0% (desligado o tempo todo) e 255 simboliza que o ciclo de trabalho é de 100% (ligado o todo).

Ou seja, podemos brincar com a velocidade variando esse valor de PWM.

No exemplo usado temos um pedaço de código onde variamos a velocidade dos motores de parado (PWM=0) até a velocidade mais rápida (PWM=255), subindo de 10 em 10 a velocidade.

//velocidade de 0 a 255 
while (velocidadeB < 255){ 
 analogWrite(velocidadeB,velocidade);
 velocidade = velocidade + 10; 
 delay(50); 
}

Outra opção de Programa

Caso você queira fazer um código mais enxuto e modularizado, temos este exemplo de implementação um pouco avançado que usa funções. Em breve teremos um tutorial sobre o assunto.

#define MOTOR_A 1
#define MOTOR_B 2
#define HORARIO true
#define ANTIHORARIO false

//inicializa pinos
void setup(){
 for (int i = 2; i < 8; i++)
 pinMode(i,OUTPUT);
}

void loop(){

acionaMotor(MOTOR_A,HORARIO, 255);
 acionaMotor(MOTOR_B,ANTIHORARIO, 255);

}

//funcao para acionamento individual de cada motor
void acionaMotor(int motor, boolean sentido, int velocidade){
 if (motor == MOTOR_A){
 digitalWrite(2,sentido);
 digitalWrite(4,!sentido);
 analogWrite(3,velocidade);
 }
 else if (motor == MOTOR_B){
 digitalWrite(6,sentido);
 digitalWrite(7,!sentido);
 analogWrite(5,velocidade);
 }
}

Fechamento

Esperamos que tenham gostado, deixe seu comentário com duvidas, sugestões ou com a foto ou vídeo de seu projeto!! Compartilhe à vontade.

Editado por Allan Mota e revisado por Ícaro Lobo

 

Apostila Arduino Básico

 


Driver motor com Ponte H L298N - Controle de Motor DC com Arduino

Driver motor com Ponte H L298N - Controlando Motor DC com Arduino

Se você curte robótica, provavelmente deve estar louco para montar seu próprio robô. A ponte H é uma peça chave quando o assunto é robótica. Neste tutorial você aprenderá como controlar um motor DC usando o Driver motor L298n com um Arduino Uno. Esse tutorial é essencial  para quem quer montar seu robô com Arduino.

[toc]

O que é uma Ponte H?

Na maioria das abordagens em robótica faz-se necessária a utilização de motores DC em diversos tipos de locomoção de robôs, movimentação de braços mecânicos, etc. Os motores DC (direct current ou corrente continua) são cargas indutivas que, em geral, demandam uma quantidade de corrente superior à que as portas do Arduino conseguem fornecer.

Exemplo de motor DC que pode ser controlado por uma ponte H L298n
Exemplo de motor DC

Sendo assim, não devemos ligar estes motores diretamente nas portas do Arduino pois se o motor demandar uma corrente acima de 40mA nas portas digitais (máxima fornecida pelo Arduino) pode queimar a porta e danificar a placa.

Para solucionar a questão da alta corrente poderíamos usar transistores, porem é importante que seja possível controlar o sentido de giro do motor, função que não se faz possível usando apenas um transistor já que para inverter o sentido de giro devemos inverter a polaridade da alimentação do motor (onde era positivo se põe negativo e vice versa). Um transistor só seria suficiente para ligar e desligar o motor.

Para resolver nosso problema utilizamos um famoso circuito conhecido como Ponte H que nada mais é que um arranjo de 4 transistores. Este circuito é uma elegante solução por ser capaz de acionar simultaneamente dois motores controlando não apenas seus sentidos, como também suas velocidades. Além de seu uso ser simples no Arduino.

Mas como funciona a Ponte H? Porque este nome?

As pontes H em possuem este nome devido ao formato que é montado o circuito, semelhante a letra H. O circuito utiliza quarto chaves (S1, S2, S3 e S4) que são acionadas de forma alternada, ou seja, (S1-S3) ou (S2-S4), veja as figuras abaixo. Dependendo da configuração entre as chaves teremos a corrente percorrendo o motor hora por um sentido, hora por outro.

Circuito Ponte H L298n - drive motor
Circuito Ponte H

Quando nenhum par de chaves está acionado, o motor está desligado (a). Quando o par S1-S3 é acionado a corrente percorre S1-S3 fazendo com que o motor gire em um sentido (b). Já quando o par S2-S4 é acionado a corrente percorre por outro caminho fazendo com que o motor gire no sentido contrário (c).

Circuito integrado Ponte H L2398N

O CI L298N é muito utilizado para o propósito de controle de motores, ele nada mais é que uma ponte H em um componente integrado. Uma das vantagens do uso desse CI é o menor espaço ocupado, a baixa complexidade do circuito e o fato de ele já possuir dois circuitos H, podendo assim, controlar dois motores. Na figura a seguir você pode conferir o diagrama de blocos do CI L298N retirado de sua folha de dados (folha de dados L298N) :

Circuito interno de um CI Ponte H L298n
Circuito interno de um CI L298n

As funções dos principais pinos desse CI são descritas na tabela a seguir:

Driver motor Ponte H L298N
Funções dos principais pinos da Ponte H L298N [1]

Outra vantagem do L298N é a resposta a sinais de PWM. Se no lugar de usar sinais lógicos TTL for usado sinais de PWM, é possível regular a tensão de saída, e dessa forma regular a velocidade dos motores.

O PWM, Pulse Width Modulation (Modulação por Largura de Pulso), consiste basicamente em aplicar uma onda quadrada de amplitude Vcc e frequência alta no lugar da tensão continua Vcc. Leia mais sobre PWM na postagem Grandezas digitais e analógicas e PWM.

Ao usar um sinal de PWM nas entradas IN1 e IN2, por exemplo, teremos uma tensão de saída nos pinos OUT1 e OUT2 em PWM que será igual à Duty Cycle*Vcc. Dessa forma, podemos regular a diferença de potencial média aplicada nos motores, controlando as suas velocidades.

Existem outras opções de CI's de ponte H no mercado, é importante consultar as especificações deles em suas folhas de dados(Datasheet) para saber qual irá lhe atender melhor. Veja algumas opções de ponte H:

Módulos Driver motor com Ponte H 

Esses módulos são muito utilizados em aplicações de robótica. Esses módulos possuem dimensões pequenas e já possuem o circuito básico para o uso do CI, o que facilita na acomodação do módulo no robô ou em outros projetos e a sua utilização.

Existem varias opções disponíveis no mercado, com tamanhos e especificações diferentes. Algumas especificações são importantes ao escolher seu módulo, são elas:

  • Especificação de potência máxima fornecida;
  • Tensão máxima suportada;
  • Corrente máxima suportada;
  • Tensão lógica.

Um exemplo desses módulos é o oferecido em nossa loja, sua características são:

  • Ci L298N;
  • Tensão para os motores: 5 – 35V;
  • Corrente máxima para os motores: 2A;
  • Potencia máxima: 25W;
  • Tensão lógica: 5V;
  • Corrente lógica: 0-36mA;
  • Dimensões: 43x43x27 mm
  • Peso: 30g.
Módulo Ponte H com o CI L298N - driver motor
Módulo Driver motor com Ponte H L298N

Módulo Driver motor com Ponte H L298N

Agora que já sabemos como a Ponte H funciona, vamos entender  na prática como podemos usá-las em conjunto com o Arduino. Para isso iremos usar o Driver motor com Ponte H L298N.

Entradas e saídas

Para começa vamos entender função de cada pino bem como deve ser utilizado.

Módulo Ponte H com o CI L298N - driver motor
Entradas e saídas do módulo Driver motor com Ponte H L298n

 Motor A e Motor B: Conectores para os dois motores

    • 6-35V: Porta para alimentação da placa com tensão entre 6 a 35V.
    • Ativa 5V: Quando jumpeado, a placa utilizará o regulador de tensão integrado para fornecer 5v (na porta 5v) quando a porta 6-35V estiver sendo alimentada por uma tensão entre 6 e 35V. Neste caso, não se deve alimentar a porta 5V pois pode danificar os componentes. A tensão fornecida na porta 5V pode ser usada para alimentar o Arduino, por exemplo.
    • 5v: Em casos de não haver fonte de alimentação com mais de 6V podemos alimentar a placa com 5V por esta porta.
    • Ativa MA: Quando jumpeado aciona o motor A com velocidade máxima. Para controlar a velocidade do motor A basta remover o jumper e alimentar o pino com uma tensão entre 0 e 5v, onde 0V é a velocidade mínima (parado) e 5V a velocidade máxima.
    • Ativa MB: Quando jumpeado aciona o motor B com velocidade máxima. Para controlar a velocidade do motor B basta remover o jumper e alimentar o pino com uma tensão entre 0 e 5v, onde 0V é a velocidade mínima (parado) e 5V a velocidade máxima.
    • IN1 e IN2:são utilizados para controlar o sentido do motor A;
  • IN3 e IN4: são utilizados para controlar o sentido do motor B;

Veja que agora, no lugar das chaves S1-S3 e S2-S4 temos os pinos IN1 e IN2. Onde IN1 corresponde às chaves S1-S3 e a IN2 às chaves S3-S4.

Para controlar o sentido, temos as seguintes combinações para o motor A(IN1 e IN2)

Tabela de combinações controle ponte h
Tabela de combinações

Para o motor B (IN3 e IN4), a tabela funciona da mesma forma.


Mãos à obra – Driver motor com Ponte H L298N - Controlando Motores com Arduino

Vamos fazer um exemplo para testar na pratica a ponte h. Neste primeiro exercício queremos testar o controle do sentido de giro dos motores A e B através do Arduino.

Componentes necessários

Para este exemplo, utilizaremos:

Montando o projeto

Prossiga com a montagem conforme esquema abaixo. Caso você use apenas um motor, basta desconsiderar o motor B:

Garanta que seu Arduino e a fonte externa estejam desligados durante a montagem.

Esquema de montagem da Ponte H L298N controlando Motores com Arduino
Esquema de montagem exemplo 1

Conectando o Arduino ao computador

Conecte seu Arduino ao computador e abra a IDE Arduino.

Antes de carregar um programa, você precisa selecionar qual porta você deseja usar para fazer carregar o programa no Arduino (upload). Dentro do Arduino IDE, clique no menu Ferramentas (tools) e abra o submenu Porta(Port). Clique na porta que seu Arduino está conectado, tal como COM3 ou COM4. Geralmente aparece o nome da placa Arduino : “COM3 (Arduino/Genuino Uno)”.

Você também precisa garantir que o tipo de placa apropriado está selecionado em Ferramentas(Tools) no submenu Placa (Board).

Programando

Crie um programa (sketch) e salve com o nome de “exemplo1_ponteh”.

Em seguida, insira nele o código conforme escrito abaixo:

/*Pinagem do arduino*/

//motor_A
int IN1 = 2 ;
int IN2 = 3 ;

//motor_B
int IN3 = 4 ;
int IN4 = 5 ;

//Inicializa Pinos
void setup(){
 pinMode(IN1,OUTPUT);
 pinMode(IN2,OUTPUT);
 pinMode(IN3,OUTPUT);
 pinMode(IN4,OUTPUT);
}

void loop(){

 /*Inicio dos Estados do motor A*/
 //Sentido 1
 digitalWrite(IN1,LOW);
 digitalWrite(IN2,HIGH);
 delay(5000);

 //Freia Motor_A
 digitalWrite(IN1,HIGH);
 digitalWrite(IN2,HIGH);
 delay(5000);

 //Sentido 2
 digitalWrite(IN1,HIGH);
 digitalWrite(IN2,LOW);
 delay(5000); 

//Freia Motor_A
 digitalWrite(IN1,HIGH);
 digitalWrite(IN2,HIGH);
 delay(5000);
 /*Fim dos Estados do motor A*/

 /*Inicio dos Estados do motor B*/ 
 //Sentido 1
 digitalWrite(IN3,LOW);
 digitalWrite(IN4,HIGH);
 delay(5000);

 //Freia Motor_B
 digitalWrite(IN3,HIGH);
 digitalWrite(IN4,HIGH);
 delay(5000);

  //Sentido 2
 digitalWrite(IN3,HIGH);
 digitalWrite(IN4,LOW);
 delay(5000); 

//Freia Motor_B
 digitalWrite(IN3,HIGH);
 digitalWrite(IN4,HIGH);
 delay(5000);

/*Fim dos Estados do motor_B*/
}

Após escrever o código, clique em Carregar (Upload) para que o programa seja transferido para seu Arduino.

Colocando para funcionar

Se tudo deu certo, teremos o motores fazendo os seguintes movimentos:

  • Motor A gira em um sentido
  • Motor A freia
  • Motor A gira no sentido contrario
  • Motor A freia
  • Motor B gira em um sentido
  • Motor B freia
  • Motor B gira no sentido contrario
  • Motor B freia

Entendendo a fundo

Entendendo o Software

Primeiro definimos os pinos que estão conectados à ponte H para controle de cada motor.

//motor_A
int IN1 = 2 ;
int IN2 = 4 ;

//motor_B
int IN3 = 6 ;
int IN4 = 7 ;

Veja que temos 2 pinos para cada moto para controle de sentido de giro.

Movimentando o motor

Para fazer o motor se movimentar, primeiro temos que informar para que direção ele deve girar:

//Motor_A
//Sentido 1 
digitalWrite(IN1,LOW); //0V
digitalWrite(IN2,HIGH); //5V

Para controlar o sentido, temos as seguintes combinações para o motor A(IN1 e IN2)

É importante ter em mente essas combinações:

//Sentido 1
digitalWrite(IN1,LOW);  //0V
digitalWrite(IN2,HIGH); //5V

//Freia Motor_A
digitalWrite(IN1,HIGH); //5V
digitalWrite(IN2,HIGH); //5V

//Sentido 2
digitalWrite(IN1,HIGH); //5V
digitalWrite(IN2,LOW);  //0V

Fechamento

Que tal agora aprender a controlar a velocidade de um motor DC usando um módulo de Ponte H?

Esperamos que tenham gostado, deixe seu comentário com duvidas, sugestões ou com a foto ou vídeo de seu projeto!! Compartilhe à vontade.

Referências Bibliográficas

[1]        Guimarães, F. A. Desenvolvimento de Robô Móvel Utilizando para a Exploração de Ambientes Hostis – Dissertação de Mestrado em Engenharia de Processos Químicos e Bioquímicos, Escola de Engenharia Mauá do Centro Universitário do Instituto Mauá de Tecnologia, São Caetano do Sul, SP, Brasil, 2007.

Editado por Allan Mota e revisado por Ícaro Lobo

Apostila Arduíno básico