O que é Arduino e como funciona?
O que é Arduino e como funciona?
Amado por muitos estudantes e hobistas das áreas de eletrônica e robótica, a família Arduino vem ganhando cada vez mais adeptos, em especial, o Arduino Uno. Neste tutorial, iremos entender o que é Arduino, para que serve, como funciona e o que ele têm de tão especial?
https://www.youtube.com/watch?v=8dVo1PE5avI
Direto ao ponto: O que é Arduino?
Falando em termos práticos, as placas Arduino possuem funcionamento semelhante ao de um pequeno computador, no qual, pode-se programar a maneira como suas entradas e saídas devem se comportar em meio aos diversos componentes externos que podem ser conectados nas mesmas.
No site oficial da Arduino, encontramos a seguinte definição (traduzida):
Arduino é uma plataforma open-source de prototipagem eletrônica com hardware e software flexíveis e fáceis de usar, destinado a artistas, designers, hobistas e qualquer pessoa interessada em criar objetos ou ambientes interativos.
Ou seja, O Arduino é uma plataforma formada por dois componentes: A placa, que é o Hardware que usaremos para construir nossos projetos e a IDE Arduino, que é o Software onde escrevemos o que queremos que a placa faça.
A maior vantagem dessa plataforma de desenvolvimento sobre as demais é a sua facilidade de sua utilização, pois, pessoas que não são da área técnica podem aprender o básico e criar seus próprios projetos em um intervalo de tempo relativamente curto.
Antes do famoso Arduino
Há pouco tempo atrás, para se confeccionar um circuito interativo, era necessário fazer projetos do zero para uma aplicação específica. Além disso, para se fazer pequenas alterações nas funcionalidades do circuito era necessário um estudo crítico e bastante trabalho.
Com o advento dos microcontroladores, foi possível que problemas que antes eram tratados com soluções de hardware fossem tratados usando software de computadores. Dessa forma, um mesmo circuito poderia desempenhar funções totalmente diferentes, através da reprogramação e alteração de alguns parâmetros do programa.
No entanto, apesar da facilidade trazida pelos microcontroladores, trabalhar com os mesmos não é tão trivial.
Desta forma, um grupo de pesquisadores italianos teve a ideia de fazer um dispositivo que tornasse o seu uso simples e acessível a qualquer um. O resultado foram as placas Arduino.
Como o Arduino funciona?
Como já dito, os Arduinos possuem funcionamento semelhante ao de um pequeno computador capaz de interpretar entradas e controlar as saídas afim de criar sistemas automáticos. Para isso, você precisa programa-lo.
Programação nada mais é que falar ao controlador quais decisões devem ser tomadas em cada circunstancia. Para isso, escrevemos um código que segue uma sequência logica de tomada de decisões que leva em conta as vareáveis que serão lidas e/ou controladas.
Para programar essas placas, ou seja, ensiná-las a desempenharem a as funcionalidades que você deseja, basta utilizarmos a sua IDE (ambiente integrado de desenvolvimento), que por sua vez, é um software onde podemos escrever um código em uma linguagem semelhante a C/C++, o qual, será traduzido, após a compilação, em um código compreensível pela nossa placa.
Aplicações do Arduino
Por exemplo, um uso simples de um Arduino seria para acender uma lâmpada por um certo intervalo de tempo, digamos, 30 segundos, depois que um botão fosse pressionado. Nesse exemplo, o Arduino teria uma lâmpada e um botão conectados a ele. O circuito aguardaria pacientemente até que o botão fosse pressionado, de modo que, uma vez pressionado o botão, ele acenderia a lâmpada e iniciaria a contagem. Depois de 30 segundos, apagaria a lâmpada e aguardaria um novo apertar do botão.
Você também poderia utilizar essa mesma configuração para controlar uma lâmpada em um cômodo, por exemplo, usando um Sensor de Presença PIR | HC-SR501 no lugar do botão. Assim, quando a quando uma pessoa entrasse em um cômodo, o sensor detectaria a presença de uma pessoa e abra cadabra!! O ambiente seria automaticamente iluminado.
Outros inúmeros projetos podem ser feitos com essa plataforma, como um sistema de emergência com sensor de gás, um sistema de automação de uma horta capaz de medir a umidade do solo e medir temperatura e umidade ambiente para ligar e desligar uma bomba e um ventilador com o auxilio de um módulo relé.
Ou então painel solar que se move de acordo com a incidência da radiação proveniente do sol com o auxilio de um sensor de luz, uma planta que manda uma mensagem no twitter quando precisar ser regada, uma caixa de brinquedos aberta por leitura de impressão digital, um robô seguidor de linha, entre muitos outros. A imaginação é o limite!
Robótica Educacional
Robótica educacional nada mais é que o uso da robótica como ferramenta para potencializar o aprendizado dos estudantes. Sua principal proposta é incentivar o uso da robótica com o intuito de resolver problemas reais ou fictícios do dia-a-dia.
Devida a facilidade utilização, o Arduino tem entrado, cada vez mais, nas salas de aula do Brasil e do mundo, se tornando um dos protagonistas no ensino de robótica para crianças e adolescentes, mesmo considerando concorrentes de peso como o Lego.
O Lego, que também é uma ferramenta fenomenal, possui algumas limitações.
A primeira é a dificuldade de se integrar com outros equipamentos que não sejam da marca. Isso implica na dificuldade de se usar o Lego para desenvolver projetos de robótica e automação que usem equipamentos cotidianos, tais como: lâmpadas, ventiladores, entre outro equipamentos. O que limita muito a sua aplicação.
O Arduino possibilita a utilização de uma gama infinitamente maior de opções de sensores e por ser uma ferramenta mais robusta, pode ser facilmente conectado a vários periféricos .
Outro ponto fundamental é o preço. Um kit da Lego custa até 10 vezes mais que um kit Arduino.
É valido saber que é possível integrar o LEGO com o Arduino. Essa união pode criar resultados surpreendentes.
Quais os modelos mais famosos de placas Arduino?
Existem diversas modelos de placas Arduino, mas a mais popular é o Arduino Uno e será ela que iremos usar como referência nessa apostila, além dela, temos outras placas muito usadas, tais como o Arduino Mega, Arduino Nano e o Arduino Micro.
Apesar de diferentes modelos, os projetos que programamos em um modelo pode ser facilmente adaptado para outro. Só fique atento para as particularidades de sua Placa.
Arduino Uno - A placa mais popular
Definitivamente, a mais famosa das placas é o Arduino Uno, esse será o modelo que você mais encontrará nos nossos tutoriais ou em de outros sites.
O motivo dessa popularidade, muito provavelmente, está ligado a ela se a sucessora dos primeiros modelos de placas Arduino desenvolvidas, tal como o Arduino Duemilanove e o Arduino Diecimila, mantendo o mesmo layout.
Além disso, ela possui um tamanho didático e uma configuração boa o suficiente para atender a maior parte dos projetos.
A placa Uno está em sua terceira revisão. Por isso, é comum você encontrar essa placa descrita como Arduino UNO REV3. Porém, depois de tanto tempo da revisão, na grande maioria das vezes, as placas que encontrará, mesmo que não tenha o REV3 ou R3, sinalizando a revisão, provavelmente serão o modelo mais recente.
O Hardware do Arduino Uno
O hardware do Arduino Uno, como a da maioria dos modelos, é simples, entretanto muito eficiente.
Vamos analisar a partir desse momento o hardware do Arduino UNO Rev 3. Ele é composto pelos seguintes blocos:
-
Microcontrolador:
Esse é o cérebro do Arduino. Um computador inteiro dentro de um pequeno chip. Este é o dispositivo programável que roda o código que enviamos à placa.
Existem várias opções de marcas e modelos de microcontroladores, nessas placas foram adotados os microcontroladores da Microchip, que inicialmente eram produzidos pela Atmel, mas especificamente a linha ATmega. O modelo UNO, por exemplo, usa o microcontrolador ATmega328.
-
Conector USB:
Conecta a placa ao computador. É por onde o computador e o Arduino se comunicam com o auxílio de um cabo USB, além de ser uma opção de alimentação da placa.
-
Pinos de Entrada e Saída:
Pinos que podem ser programados para agirem como entradas ou saídas fazendo com que o Arduino interaja com o meio externo. O UNO R3 possui 14 portas digitais (I/O), 6 pinos de entrada analógica e 6 saídas analógicas (PWM).
-
Pinos de Alimentação:
Fornecem diversos valores de tensão que podem ser utilizados para energizar os componentes do seu projeto. Devem ser usados com cuidado, para que não sejam forçados a fornecer valores de corrente superiores ao suportado pela placa.
-
Botão de Reset:
Botão que reinicia a placa.
-
Conversor Serial-USB e LEDs TX/RX:
Para que o computador e o microcontrolador conversem, é necessário que exista um chip que traduza as informações vindas de um para o outro. Os LEDs TX e RX acendem quando o Arduino está transmitindo e recebendo dados pela porta serial respectivamente.
-
Conector de Alimentação:
Responsável por receber a energia de alimentação externa, que pode ter uma tensão de no mínimo 7 Volts e no máximo 20 Volts e uma corrente mínima de 300mA. Recomendamos 9V, com um pino redondo de 2,1mm e centro positivo. Caso a placa também esteja sendo alimentada pelo cabo USB, ele dará preferência à fonte externa automaticamente.
-
LED de Alimentação:
Indica se a placa está energizada.
-
LED Interno:
LED conectado ao pino digital 13.
Especificações da placa Arduino Uno:
Nesta placa, o microcontrolador ATmega328 é utilizado, este dispõem de 32kb de memória flash e 2kb de SRAM. De maneira simples, a memória flash é o local na qual nosso programa será salvo, já a SRAM é a memória na qual nossas variáveis serão salvas. A diferença básica entre esses dois tipos de memória é que a flash não perde seus dados caso o Arduino seja desligado ou reiniciado o mesmo não é válido para a SRAM.
IDE Arduino
Uma das grandes vantagens da plataforma Arduino está no seu ambiente de desenvolvimento, que usa uma linguagem baseada no C/C++, linguagem bem difundida, usando uma estrutura simples.
Por isso, mesmo pessoas sem conhecimento algum em programação conseguem, com pouco estudo, elaborar programas rapidamente.
Para baixar a IDE Arduino acesse o site oficial. No site, clique na aba software.
Na página software, procure pela última versão do Arduino IDE. No dia em que escrevo é a versão 1.8.4.
Escolha a IDE adequada a seu sistema operacional:
Na página que abará, clique em JUST DOWNLOAD
Windows
- Primeira Opção: baixar o instalador (Installer) que funciona como qualquer outro instalador de programa.
- Segunda Opção: Baixar todos os arquivos da IDE Arduino compactados para Windows (ZIP file), nessa versão basta baixar e descompactar na pasta que você desejar, inclusive no seu pen driver ou HD virtual. Eu costumo descompactar na Área de Trabalho.
- Terceira opção: Aplicativo para windows 10.
Mac OS X
Basta baixar e instalar
Linux
Baixar todos os arquivos da IDE Arduino compactados para Linux (32bit ou 64bit), nessa versão basta baixar e descompactar na pasta que você desejar, inclusive no seu pen driver ou HD virtual. Eu costumo descompactar na Área de Trabalho.
Entendendo a IDE Arduino
Em resumo, é um programa simples de se utilizar e de entender com bibliotecas que podem ser facilmente encontradas na internet. As funções da IDE do Arduino são basicamente três: permitir o desenvolvimento do software, de enviá-lo à placa para que possa ser executado e de interagir com a placa Arduino.
Como aprender a usar o Arduino
O Arduino é uma plataforma de fácil utilização e com infinitas possibilidades de aplicação. Há muito conteúdo disponível sobre ele na internet e isso o faz ainda mais especial.
Porém, ainda assim, as vezes não é fácil encontrar um material que organize de forma didática tudo que se precisa saber quando se está começando nesse mundo. Visto que proposta dessa placa é que qualquer um possa criar seu próprio projeto de automação, mesmo sem um conhecimento técnico muito profundo.
Levando isso em consideração, desenvolvemos uma séria de três apostilas gratuitas para que qualquer um possa aprender a usá-lo!
Elas abordam os assuntos mais básicos, levando em conta aqueles que não sabem nada sobre o assunto.
O melhor de tudo é que elas são gratuitas!! =D
Você pode saber mais sobre elas no link a seguir: Apostila Arduino
A comunidade Arduino
Existem varias outra placas concorrentes e que muitas vezes são melhores em hardware, tal como a Freescale, MSP, etc.
Então o que faz dessa placa tão famosa? A sua comunidade!
Portanto, você pode digitar qualquer tipo de dúvida sobre Arduino na internet que raramente não encontrará alguém falando sobre. Fóruns, blogs, portais, canais do Youtube, etc. Uma infinidade de opções de lugares onde você poderá encontrar pessoas falando sobre o mesmo assunto.
De alguma forma, existe algo em torno dessa plataforma que contagia as pessoas a compartilharem suas experiências.
Por exemplo, o portal Vida de Silício abre espaço para que qualquer um interessado em escrever tutorias se inscreva como autor.
A maioria dos tutoriais foram escritos por pessoas que se dispuseram a ajudar a comunidade. Existe um senso de que, dessa forma, estamos ajudando o mundo.
- Dica 1: Tutoriais em inglês
Mesmo que exista muito conteúdo em português, as vezes não encontramos algo que precisamos. Então, lembre-se de fazer uma pesquisa em inglês.
Você irá descobrir que existe muita gente no mundo falando sobre esse assunto e muito provavelmente alguém já enfrentou o mesmo problema que você.
- Dica 2: Sites referência
Alguns site onde você encontrará pessoas compartilhando conteúdo sobre projetos com Arduino:
- Portal Vida de Silício (Português): Claro que vamos puxar um pouco de sardinha para nosso lado, hehehe. Mas falando sério, tem muito tutorial bom aqui no portal. A galera se esforça para escrever conteúdos surpreendentes. Mas claro que existem muitos outros blogs na internet tal como o Br-Arduino e o Arduino & Cia que por diversas vezes nos serviu como material de consulta.
- Forum Arduino (em Português) : Esse é o forum oficial. Existem muitos outros foruns na internet, mas esse reuni uma grande quantidade de pessoas se ajudando e ótimos tópicos já resolvidos que você pode consultar.
- Instructables (Inglês): A proposta desse site é reunir em um só lugar tutoriais que ensinem a fazer praticamente qualquer coisa. Com isso, existem diversas aplicações criativas usando Arduino cujo o qual você pode se inspirar.
- Embarcados: O embarcado é algo como o Portal Vida de Silício, só que com conteúdos mais voltados para sistemas embarcados. Com certeza tem muita coisa bacana lá para você usar.
Fechamento
Enfim, aprendemos o que é Arduino e suas principais funcionalidades.
Esperamos que tenham gostado, deixe seu comentário com duvidas, sugestões ou com a foto ou vídeo de seu projeto!! Compartilhe à vontade.
Utilizando displays OLED 0.96" I2C em paralelo com Arduino
Utilizando displays OLED 0.96" I2C em paralelo com Arduino
O display OLED 0.96″ é considerado uma boa opção para estabelecer uma interface de visualização de dados, no entanto, o seu tamanho limita a quantidade de informações que podem ser exibidas em uma única tela. De forma a possibilitar o aproveitamento das vantagens que o uso do display fornece e garantir a exibição de uma maior quantidade de informações, neste tutorial, aprenderemos a modularizar mais de dois displays OLED 0.96″ com o Arduino UNO utilizando o demux CD4051E.
Displays OLED 0.96" I2C
A estrutura de um OLED (Organic Light-Emitting Diode, ou, Diodo Emissor de Luz Orgânico) é constituída basicamente de uma camada de semicondutor orgânico, situada entre dois eletrodos, sendo que um deles geralmente é transparente. Esse material orgânico ao ser estimulado por uma corrente ou campo elétrico, emite luz nas cores vermelho, verde e azul (RGB), dispensando a necessidade de haver luz traseira (backlight), ao contrário das telas dos displays LCD, por exemplo. Essa característica do OLED traz uma grande vantagem frente ao uso dos outros tipos de tela que é a considerável economia de energia.
Devido a presença de material orgânico na sua constituição, a vida útil do display OLED costuma ser menor do que a dos outros tipos de displays e também apresenta a desvantagem de ter baixa resistência à água. Entretanto, além do baixo consumo de energia, o display OLED proporciona uma melhor resolução, qualidade de cor, brilho, contraste e além disso, costuma ser mais leve e fino em relação aos outros displays.
O display utilizado neste projeto possui controlador SSD1306 e a tela tem 0.96 polegadas com resolução de 128x64 pixels (também pode ser encontrado com resolução de 128x32 pixels). A comunicação com o arduino é feita via interface I2C (também pode ser por SPI), portanto, além dos pinos de alimentação (VCC e GND), o display OLED conta com mais 2 pinos (SDA e SCL) para a conexão com o arduino. Certamente a pinagem reduzida do OLED é outra grande vantagem deste display frente aos outros disponíveis no mercado.
O display OLED pode apresentar dois endereços diferentes (0x3C ou 0x3D), possibilitando alternar entre eles a partir da modificação da configuração de resistores na parte traseira da placa. Sendo assim, o modo de endereçamento possibilita utilizar apenas dois displays em paralelo.
O multiplexador/demultiplexador CD4051E
Enquanto um demultiplexador (demux) é um sistema digital que contém apenas uma entrada (analógica ou digital) cujo conteúdo é passado para uma das saídas a partir da combinação dos sinais de controle, um multiplexador (mux) apresenta uma lógica inversa: contém uma saída que recebe o conteúdo de uma entre várias entradas (analógicas ou digitais) dependendo da configuração dos sinais de controle. O CD4051E é um CI (Circuito Integrado) que pode agir tanto como um demultiplexador quanto um multiplexador e nesse tutorial, usaremos ele como um demux.
O componente que iremos utilizar contém uma entrada analógica/digital e 8 saídas, além de 3 entradas de controle. Seguindo o diagrama da figura 3:
- O pino 16 (VDD) é o de alimentação (pode ser 5V ou 3.3V)
- O pino 8 (VSS) é o GND ou terra
- O pino 7 (VEE) é a tensão negativa para a geração de ruído entre as entradas e saídas (neste tutorial, o conectaremos ao GND)
- Os pinos 9 a 11 (A0, A1 e A2) são as entradas de controle digitais
- Os pinos 1, 2, 4, 5, 12 a 15 (Y0 a Y7) são as entradas/saídas (neste tutorial, serão saídas analógicas)
- O pino 3 (Z) é a entrada/saída que irá ser conectada ao arduino (neste tutorial, será entrada analógica).
- O pino 6 (E) é o pino de habilitação do CI (neste tutorial, o conectaremos ao GND)
Como iremos utilizar um demux de 8 canais, é possível utilizar até 8 OLEDs em paralelo. Entretanto, para facilitar o entendimento e simplificar a lógica, iremos modularizar apenas 3 OLEDs, portanto, utilizaremos 3 entradas do demux.
Mãos à obra - Imprimindo informações nos displays
Componentes necessários
- 3 x Display OLED 0.96” I2C
- 1 x Demultiplexador CD4051E
- 1 x Arduino UNO
- 1 x Protoboard
- Jumpers
Você também pode optar por utilizar outro demux da família do 4051 (por exemplo, o HEF4051B) ou outros da família do 4052 que são de 4 canais, mas atente-se a pinagem do componente que costuma ser diferente de uma família para outra. Se você escolher utilizar outro Arduino, verifique os pinos de comunicação I2C para estabelecer as ligações corretamente.
Montando o projeto
- Conecte os pinos de VCC dos displays e do demux ao 5V do arduino.
- Conecte os pinos de GND dos displays e os pinos 6, 7 e 8 do demux ao GND do arduino.
- Conecte os pinos SCL dos displays ao pino A5 do arduino (os pinos podem ser ligados em paralelo como mostra a figura 4).
- Conecte cada um dos pinos SDA dos displays aos pinos 12 a 14 do demux (você pode escolher qualquer combinação de 3 pinos dentre os pinos de saída do demux).
- Conecte o pino 3 do demux ao pino A4 do arduino.
- Conecte os pinos 9 a 11 do demux aos pinos digitais 2, 3 e 4 do arduino (você pode escolher qualquer combinação de 3 pinos digitais do arduino).
Verifique como ficou nossa montagem na prática:
Bibliotecas
Neste projeto, usaremos apenas a biblioteca “U8glib.h” para estabelecer a comunicação com os displays e imprimir informações nos OLEDs. Você pode baixar-lá no site: https://github.com/olikraus/u8glib/.
Instale a biblioteca no diretório padrão de suas bibliotecas. Geralmente, este diretório se encontra dentro da pasta “Arduino”, localizada em “Documentos”.
Programando
Segue o código a ser usado no projeto:
#include "U8glib.h" U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK); //Pinos do arduino conectados as entradas de controle do demux int a0 = 2; int a1 = 3; int a2 = 4; //Função que contém os comandos gráficos do display 1 void draw0() { u8g.setFont(u8g_font_fur25);//Seleciona a fonte de texto u8g.drawStr( 30, 42, "Vida");//Escreve uma palavra no display } //Função que contém os comandos gráficos do display 2 void draw1() { u8g.setFont(u8g_font_fur25); u8g.drawStr( 40, 42, "de"); } //Função que contém os comandos gráficos do display 3 void draw2() { u8g.setFont(u8g_font_fur25); u8g.drawStr( 20, 42, "Silicio"); } void setup(void) { //Declara os pinos do arduino como saídas pinMode(a0, OUTPUT); pinMode(a1, OUTPUT); pinMode(a2, OUTPUT); //Para inicializar o display 1 digitalWrite(a0, LOW); digitalWrite(a1, LOW); digitalWrite(a2, LOW); u8g.begin(); //Para inicializar o display 2 digitalWrite(a0, HIGH); digitalWrite(a1, LOW); digitalWrite(a2, LOW); u8g.begin(); //Para inicializar o display 3 digitalWrite(a0, LOW); digitalWrite(a1, HIGH); digitalWrite(a2, LOW); u8g.begin(); } void loop(void) { //Combinação dos sinais de controle para o display 1 (em binário) digitalWrite(a0, LOW); digitalWrite(a1, LOW); digitalWrite(a2, LOW); //Bloco de comandos necessário para a escrita no display 1 u8g.firstPage(); do { draw0();//Chama a função que contém os comandos gráficos } while ( u8g.nextPage() ); delay(500); //Combinação dos sinais de controle para o display 2 (em binário) digitalWrite(a0, HIGH); digitalWrite(a1, LOW); digitalWrite(a2, LOW); u8g.firstPage(); do { draw1(); } while ( u8g.nextPage() ); delay(500); //Combinação dos sinais de controle para o display 3 (em binário) digitalWrite(a0, LOW); digitalWrite(a1, HIGH); digitalWrite(a2, LOW); u8g.firstPage(); do { draw2(); } while ( u8g.nextPage() ); delay(500); }
Colocando para funcionar
Veja como ficou o resultado final:
Entendendo a fundo
Software
Para ter acesso a todas as funções que a biblioteca “U8glib” disponibiliza, consulte: https://github.com/olikraus/u8glib/wiki/userreference
- Objeto SSD1306, 128x64
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);
Os displays utilizados neste projeto apresentam controlador SSD1306, contém 128 por 64 pixels e se comunicam com o arduino via protocolo I2C. Para verificar quais controladores e tamanhos de tela são suportados pela biblioteca, consulte: https://github.com/olikraus/u8glib/wiki/device.
- Função .setFont()
u8g.setFont(u8g_font_fur25);
Esta função seleciona a fonte do texto que será impresso na tela do display. Para selecionar outra fonte de texto, consulte:
https://github.com/olikraus/u8glib/wiki/fontsize
- Função .drawStr()
u8g.drawStr( 30, 42, "Vida");
Esta função possibilita a escrita de uma palavra no display. Seus respectivos argumentos são: coordenada x, coordenada y e uma string.
- Função .begin()
u8g.begin();
Esta função é responsável por inicializar o OLED. É necessária utilizar-lá antes do comando de escrever no display.
- Função digitalWrite()
digitalWrite(a0, LOW);
Esta função escreve 1 (HIGH) ou 0 (LOW) no pino associado.
Considerações finais
Em suma, os displays OLED possibilitam a exibição de imagens e caracteres com muita nitidez e por apresentarem uma biblioteca com uma infinidade de funções é possível exibir qualquer tipo de informação que se deseja. Neste tutorial, com o objetivo de aproveitar as inúmeras vantagens que estes pequenos displays proporcionam e possibilitar a exibição de uma maior diversidade de informações, aprendemos a utilizar mais de dois displays em paralelo com a ajuda de um pequeno componente, que é o demux.
Espero que tenham gostado deste tutorial e não se esqueçam de deixar suas dúvidas, sugestões, críticas ou elogios nos comentários abaixo.
Módulo GSM SIM800L - Aplicações com Arduino
Módulo GSM SIM800L
Neste tutorial, iremos testar as principais aplicações do módulo GSM SIM800L diretamente com os comandos AT pela UART , assim, podemos fazer o mesmo código para diversos microcontroladores como PIC, ESP8266/32, ARM, AVR, etc, mudando apenas os métodos de utilização da UART de MCU para MCU, já que os comandos AT serão sempre iguais. Para esse tutorial usaremos o Arduino Mega como controlador.
[toc]
O que vamos aprender?
As principais aplicações deste módulo são:
- SMS (receber e enviar).
- Obter horário da rede, similar ao NTP ou RTC.
- Obter localização por triangulação da rede.
- Conexões TCP/UDP (inclusive SSL/TLS).
- Ligações com entrada e saída de áudio.
Neste tutorial, Aprenderemos os 3 primeiros itens separadamente encontrados na lista apresentada.
Mãos a obra - Testando algumas funções do SIM800L
Componentes necessários
- 1x - SIM800L
- 1x - Fonte externa de 3,4 a 4.4V de 2A.
- 1x - Arduino Mega
- Fios Jumpers
- Protoboard
Montando o projeto
Atenção: esse módulo pode utilizar muita corrente de sua fonte em picos de transmissão (até 2A), então não alimente-o diretamente pelo Arduino.
Recomenda-seutilizar uma fonte externa de 3,4V a 4,3V de no mínimo 2A. Caso não tenha uma fonte com tanta corrente, você pode adicionar alguns capacitores de alto valor capacitivo para ajudar nos picos de transmissão. Se a fonte não for suficiente para alimentá-lo, ele irá reiniciar aleatoriamente durante as transmissões.
Projeto 1 - Enviando e recebendo SMS
Programando o Arduino
void setup() { Serial2.begin(115200); pinMode(13, OUTPUT);//LED pinMode(8, OUTPUT);//Pino de reset do GSM //reinicia o GSM digitalWrite(8, 0); delay(2000); digitalWrite(8, 1); delay(7000); if (gsmWrite("AT", "OK") == "FAIL") { return;//Se o GSM nao responder, retorna a funcao (trava o mcu) } delay(5000);//Espera o termino da inicializacao do GSM SMSsnd("014998202683", "Arduino ON, lendo mensagens...");//Envia a mensagem pro numero. Atencao: precisa do DDD! } void loop() { SMSrd();//Verifica se há novas mensagens para serem lidas a cada 10seg delay(10000); } String gsmWrite(String snd, String rcv)//Funcao que envia dados pro GSM e espera a resposta de ate 30seg { Serial2.println(snd); if (rcv.indexOf("+CMGS") > -1) { delay(150); Serial2.write(0x1A); } for (uint16_t i = 0; i < 1200; i++) { delay(25); if (Serial2.available()) { delay(50); String a = Serial2.readString(); if (a.indexOf(rcv) > -1 || rcv.length() == 0) { return a; } } } return "FAIL"; } void SMSsnd(String nm, String msg)//Funcao que envia o SMS { String snd = "AT+CMGS=\""; snd += nm; snd += "\""; gsmWrite("AT+CMGF=1", "OK"); gsmWrite("AT+CSMP=17,255,0,0", "OK"); gsmWrite(snd, ">"); gsmWrite(msg, "+CMGS:"); } void SMSrd()//Funcao que le se ha SMS nao lido { String c = ""; gsmWrite("AT+CMGF=1", "OK"); c = gsmWrite("AT+CMGL=\"REC UNREAD\"", ""); if (c.indexOf("+CMGL:") > -1) { if (c.indexOf("ON") > -1)//ON { digitalWrite(13, 1);//se o SMS conter o texto ON, liga o LED } else if (c.indexOf("OFF") > -1)//OFF { digitalWrite(13, 0);//se o SMS conter o texto OFF, desliga o LED } gsmWrite("AT+CMGD=1,1", "OK");//apaga todas mensagens (SIM card ha pouca memoria) } }
Colocando para funcionar
Depois de ligar nosso projeto na alimentação, vamos logo receber uma mensagem indicando que o sistema está ativo, mostrando que o envio de SMS funcionou perfeitamente. Também foi adicionada a leitura de SMS, de modo que, quando um SMS é enviado com a mensagem "ON" ou "OFF", o LED no pino 13 seja ligado ou desligado.
Projeto 2 - Obtendo horário através da rede
Programando o Arduino
void setup() { Serial.begin(115200); Serial2.begin(115200);//Inicia a Serial do GSM pinMode(8, OUTPUT);//Pino de reset do GSM //Reinicia o GSM digitalWrite(8, 0); delay(2000); digitalWrite(8, 1); delay(7000); String rcv = gsmWrite("AT", "*PSUTTZ:");//Espera o GSM obter o horario da rede if (rcv.indexOf("FAIL") > -1) { gsmWrite("AT+CLTS=1;&W", "OK");//Se nao responder, pode ser configuracao do seu GSM, entao vamos ativar a obtencao automatica de horario pela rede setup();//retorna ao inicio } delay(5000); } void loop() { Serial.println(gsmTIME());//Mostra a data e horario no Serial Monitor delay(5000); } String gsmWrite(String snd, String rcv)//Funcao que envia dados ao GSM e espera a resposta { Serial2.println(snd); if (rcv.indexOf("+CMGS") > -1) { delay(150); Serial2.write(0x1A); } for (uint16_t i = 0; i < 1200; i++) { delay(25); if (Serial2.available()) { delay(50); String a = Serial2.readString(); if (a.indexOf(rcv) > -1 || rcv.length() == 0) { return a; } } } return "FAIL"; } String gsmTIME()//Funcao que retorna a data e horario { String c = gsmWrite("AT+CCLK?", "+CCLK:"); int16_t a = c.indexOf("\"") + 1; int16_t b = c.indexOf("\"", a); return c.substring(a, b); }
Colocando para funcionar
Abrindo o Serial Monitor, podemos observar a data e o horário retornado pelo módulo GSM, lembrando que a data está no padrão (ano/mês/dia). O ultimo valor do horário corresponde ao fuso horário*4, logo, para obter nosso fuso horário, basta dividir "-12" por 4 e chegamos em -3 (fuso horário de brasília).
Projeto 3 - Obtendo localização através da rede
Programando o Arduino
void setup() { Serial.begin(115200); Serial2.begin(115200); pinMode(8, OUTPUT);//Pino de reset do GSM //Reseta o GSM digitalWrite(8, 0); delay(2000); digitalWrite(8, 1); delay(7000); if (gsmWrite("AT", "OK") == "FAIL") { return; } delay(5000); if (gsmWrite("AT+SAPBR=1,1", "OK") == "FAIL")//Ativa a rede pra localizacao { return; } else { String rcv = gsmWrite("AT+CIPGSMLOC=1,1", "+CIPGSMLOC:");//Pergunta a localizacao ao GSM int a = rcv.indexOf(":") + 2; int b = rcv.indexOf(",", a); if (rcv.substring(a, b) == "0") { a = rcv.indexOf(",", b) + 1; b = rcv.indexOf(",", a) + 1; b = rcv.indexOf(",", b); Serial.println(rcv.substring(a, b));//Mostra a localizacao no Serial monitor } } } void loop() { } String gsmWrite(String snd, String rcv)//Funcao que envia dados ao GSM e espera a resposta { Serial2.println(snd); if (rcv.indexOf("+CMGS") > -1) { delay(150); Serial2.write(0x1A); } for (uint16_t i = 0; i < 1200; i++) { delay(25); if (Serial2.available()) { delay(50); String a = Serial2.readString(); if (a.indexOf(rcv) > -1 || rcv.length() == 0) { return a; } } } return "FAIL"; }
Colocando para funcionar
As coordenadas que o módulo GSM retorna é longitude e latitude respectivamente.
Entendendo a fundo
Software
Para utilização do módulo GSM foram usados os comandos "AT" do Datasheet, este pode ser encontrado logo abaixo em nossa seção de referências. Existem incontáveis comandos para as mais diversas aplicações e se você pretende utilizar o módulo GSM, aconselhamos que estude o Datasheet e conheça os comandos necessários para seu projeto.
A comunicação entre o Microcontrolador e o módulo GSM é feita através da porta Serial (UART) à 115200b/s neste caso, mas pode ser alterada. A cada comando enviado, normalmente, retorna-se uma resposta, então sempre que enviamos um comando, precisamos esperar a resposta para saber se os dados enviados foram realmente enviados. Para isso, foi criada uma função básica cuja função é escrever o dado no módulo GSM e esperar o retorno da resposta em um tempo limite de 30 segundos. Tome cuidado que alguns comandos podem demorar até 85 segundos para retornar resposta e caso isso aconteça, o código irá falhar por timeout. Para arrumar isso, aumente o timeout da função de leitura.
-Função gsmWrite(String snd, String rcv)
gsmWrite("AT", "OK");
A função criada para envio de dados do módulo GSM é uma boa maneira de utilizar o mesmo em diversos tipos de códigos, entretanto, como normalmente após a escrita de algum comando nós esperamos uma resposta, isto pode deixar nosso código lento e travando, já que alguns comandos demoram até 85 segundos!
Essa função basicamente escreve o comando (primeiro argumento da função, "snd") AT na porta Serial e posteriormente espera a resposta do mesmo (segundo argumento da função, "rcv"). Caso o módulo GSM não retorne a reposta esperada em 30 segundos que definimos no loop FOR() da função, retorna-se a mensagem "FAIL".
-Comandos AT
O módulo GSM SIM800L funciona com os comandos AT e a maioria deles retorna alguma mensagem de confirmação ou erro, vamos ver como alguns deles funcionam!
AT+CCLK
Quando requisitado "AT+CCLK?" do SIM800L, retorna-se "+CCLK: <time>" e ao fim, "OK". Também pode-se retornar erros como mostrado na imagem.
AT+CMGL
A leitura de SMS do nosso projeto foi dedicada apenas às mensagens não lidas, por isso utilizamos "AT+CMGL="REC UNREAD"", mas você pode trocar para qualquer uma das opções acima que se encaixar melhor ao seu projeto.
Conclusões finais
As utilidades para o módulo GSM são inúmeras e isto nos permite ter uma gama de aplicações muito grande em um mesmo projeto, já que conta com diversas features, desde SMS até conexões TCP e etc. Apesar de alguns comandos demorarem bastante por causa da latência da rede telefônica, ainda podemos usufruir bem deste incrível módulo. O SIM800L faz muito mais do que mostrado aqui, entretanto estamos mostrando apenas o básico para norteá-los.
Referencias
Display OLED 0.96" I2C com Arduino
Utilizando o Display OLED 0.96" I2C com Arduino
Neste tutorial, aprenderemos a utilizar o Display OLED 0.96" em conjunto com o Arduino Micro, mas você pode fazer com qualquer Arduino, bastando apenas a troca dos pinos da comunicação I2C que o Display utiliza. Também é possível usar com Raspberry PI, PIC e até ESP8266 e ESP32!
[toc]
Display OLED
OLED (organic light-emitting diode, diodo emissor de luz orgânico) é um Diodo emissor de luz (LED) em que a camada de emissão eletro-luminescente são filmes orgânicos que emitem luz em resposta a uma corrente elétrica que flui entre anodo e catodo. Esta camada de semicondutor orgânico fica situada entre dois eletrodos. Os OLEDs podem ter duas ou três camadas de material orgânico.
As telas OLED também são as melhores telas disponíveis atualmente no mercado e por conta disso, o preço é bem elevado em relação aos outros tipos.
O Display OLED possuem varias vantagens frente a outros tipos de telas:
- Consome muito menos energia;
- Mais leve;
- Fino;
- Ângulos de visão maiores;
- Melhor brilho e contraste;
- Reproduzir cores mais naturais.
Mas nem tudo são flores, devido ao fato de ele usar material orgânico, o Display OLED possui uma vida útil menor que outras telas. Outras desvantagem é a baixa resistência à água. Ainda assim, esse display tem vantagens surpreendentes que compensam suas desvantagens.
Display OLED 0.96" I2C
Este Display OLED 0.96" é perfeito para prototipação e produtos, uma vez que utiliza apenas 2 pinos do MCU com a comunicação Serial I2C. Além disso, é pequeno e tem uma ótima aparência pelo fato de ser OLED.
Especificações do display
- Tamanho: 128x64 pixels;
- Tensão: 3-5V;
- Comunicação: SPI ou I2C.
Mãos a obra - Escrevendo no Display
Componentes necessários
Você pode utilizar outras placas, tais como Arduino UNO e Arduino Mega, você apenas deverá se atentar para os pinos I2C da sua placa de desenvolvimento
Montando o projeto
Cuidado: alguns display tem o Vcc e GND invertido.
- Vcc: 3.3V ou 5V.
- GND: GND.
- SCL: 3.
- SDA: 2.
Caso você venha a utilizar em outro microcontrolador, precisará verificar os pinos de I2C dele e fazer a ligação corretamente.
Bibliotecas utilizadas
Baixe ambas bibliotecas e instale no diretório padrão de suas bibliotecas. Normalmente esse diretório se encontra dentro da pasta "Arduino", localizada em "Meus documentos".
Antes de começar
Precisamos alterar uma linha na biblioteca do display (SSD1306), onde é definido o tamanho em pixels do display. Nosso display é 128x64, você deve verificar isso do site onde comprou o display. Por padrão, a biblioteca vem com 128x32 definido, entretanto, nosso display é 128x64.
Se seu display já é 128x32, pode pular esta parte, caso contrario, efetue a troca mostrada abaixo
1-) Abra o arquivo "Adafruit_SSD1306.h", que se encontra dentro da pasta da biblioteca baixada.
2-) Procure pela definição do tamanho do display, que está próximo a linha 70.
3-) Comente a linha do display que esta definida por padrão
4-) Remova o comentário da linha respectiva ao seu display, veja como ficou o nosso:
Código do projeto
#include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> Adafruit_SSD1306 dsp(-1);//cria o objeto do display para i2c void setup() { dsp.begin(SSD1306_SWITCHCAPVCC, 0x3C);//inicia o display com endereco padrao dsp.clearDisplay();//limpa a tela dsp.setTextColor(WHITE);//define o texto para branco (no display ficara azul) dsp.setTextSize(1);//define o tamanho do texto dsp.println("Vida de silicio");//escreve na tela a mensagem dsp.setTextSize(3); dsp.println("2018"); dsp.display();//mostra as alteracoes no display, sem isso nao ira mostrar nada!! delay(2000); dsp.clearDisplay(); } void loop() { for (int8_t i = 0; i < 64; i++) { dsp.drawLine(0, 0, 128, i, WHITE);//desenha uma linha dsp.display();//mostra na tela delay(1); } for (int8_t i = 63; i > -1; i--) { dsp.drawLine(0, 0, 128, i, BLACK); dsp.display(); delay(1); } }
Colocando para funcionar
Entendendo a fundo
Software
-Objeto SSD1306
Adafruit_SSD1306 dsp(-1);
Nosso display é I2C, entretanto, há outros com comunicação SPI e estes devem ter os pinos definidos junto ao objeto. No caso do I2C, é preciso colocar -1.
-Função .begin()
dsp.begin(SSD1306_SWITCHCAPVCC, 0x3C);
Inicia o display no endereço 0x3C do I2C e configura o Vcc interno.
-Função .clearDisplay()
dsp.clearDisplay();
Apaga tudo o que estiver escrito ou desenhado na tela.
-Função .display()
dsp.display();
Depois de escrever ou desenhar algo na tela, não será mostrado enquanto você não usar esta função, que faz o display "atualizar" os dados e mostrar as alterações
Conclusões finais
Este pequeno e incrível display permite a criação de uma interface IHM (Interface Homem máquina) perfeita para pequenos projetos e até produtos. Também podemos usufruir do I2C que utiliza apenas 2 pinos e caso seu projeto já esteja usando algum componente I2C, não será necessário a adição de novos fios.
Recomendamos ler o seguintes tutoriais para saber mais sobre IHM e sobre I2C:
- Display LCD 16x2 com Arduino
- Display LCD 20×4 e LCD 16×2 com Adaptador I2C – Utilizando o display com Arduino
Como utilizar o LED RGB com Arduino
Como utilizar o LED RGB
Neste tutorial, você aprenderá como utilizar o LED RGB integrado a uma placa Arduino Uno, utilizando as saídas PWM para demonstrar as cores emitidas do componente. Por meio do monitor serial, o Arduino lerá o nome da cor escrita pelo usuário e, por meio do LED RGB, a cor digitada será reproduzida.
Caso ainda não tenha conhecimento básico sobre como usar o monitor serial da Arduino IDE, sugerimos que você leia o tutorial Comunicação Serial Arduino, para compreender melhor o projeto a ser desenvolvido, principalmente na parte de software.
[toc]
O que é um LED? O que significa o termo "LED"?
LED é uma sigla para Light Emitting Diode que em português significa Diodo Emissor de Luz. O LED é um componente eletrônico que, quando ocorre passagem de corrente elétrica, emite luz. Possui dois terminais, chamados de anodo (positivo) e catodo (negativo).
Por que utilizar um LED?
É sempre bom termos um auxílio visual nos nossos projetos, seja como sinalizador ou alarme, indicando que algo está ligado ou não, como os encontrados em televisores, aparelhos de DVD, computadores, dentre outros, ou por opções de design de produto, como podemos ver logo abaixo.
Ou seja, um LED é uma forma visual simples de um projeto conversar conosco. Outra forma visual de um projeto interagir é através de displays LCDs.
Falamos um pouco mais sobre a importância das interfaces homem maquina (IHM) no tutorial Display lcd 16x2 com Arduino.
O que é um LED RGB?
Assim como os LEDs tradicionais, o LED RGB emite luz por meio da passagem de corrente elétrica, mas ele apresenta a peculiaridade de ser composto por três LEDs de cores diferentes, sendo elas: vermelho (Red), verde (Green) e azul (Blue), surgindo daí o nome "RGB".
Cada LED pode ser controlado de maneira individual, conectando apenas os seus terminais em alguma fonte de energia, deixando os outros desconectados, mas o seu grande diferencial está em justamente utilizar os três ao mesmo tempo, no qual utilizando pulsos PWM (recomendamos que veja o tutorial Arduino - Grandezas digitais, analógicas e PWM) para realizar o controle de intensidade de cada cor individualmente, de modo que, a cor resultante será a mistura das cores emitidas por cada LED.
Tipos de LED RGB
Por se tratar da associação de três LEDs distintos em um único LED, eles podem ser denominados de: catodo comum ou anodo comum, sendo o catodo comum o mais utilizado.
O tipo catodo comum possui uma interligação entre os catodos dos três LEDs, fazendo com que se torne apenas um. Já o tipo anodo comum apresenta uma interligação entre os anodos dos três LEDs, tornando-o apenas um, como é possível visualizar na figura abaixo.
Para identificar o terminal que equivale ao comum, basta ver qual terminal é o maior, ou ver qual está conectado a maior "placa" presente no interior do LED, como é possível ver na ilustração abaixo.
Mãos à obra - Comandando a cor a ser mostrada no LED RGB pelo Monitor Serial
O projeto deste tutorial visa integrar o monitor serial com o LED RGB, no qual o usuário enviará o nome de uma cor e o Arduino reproduzirá essa cor por meio do LED. Para este fim, serão necessários:
- 1 x Placa Arduino Uno ou outro Arduino
- 1 x LED RGB Catodo Comum
- 3 x resistores de 330Ω
- Fios Jumpers
- Protoboard
Montando o hardware
Com os componentes em mãos, montaremos o circuito abaixo.
Programando
Após montar o circuito na protoboard, damos início a parte de programação do arduino. Escreva em sua IDE o código apresentado abaixo. Não se preocupe, a explicação detalhada de cada linha será abordado logo abaixo.
const int azul = 9; const int verde = 10; const int vermelho = 11; String cor; void setup() { Serial.begin(9600); pinMode(azul, OUTPUT); pinMode(verde, OUTPUT); pinMode(vermelho, OUTPUT); } //Funções responsáveis por executar o brilho selecionado void vermelhoFuncao(){ digitalWrite(azul, LOW); digitalWrite(verde, LOW); digitalWrite(vermelho, HIGH); } void azulFuncao(){ digitalWrite(azul, HIGH); digitalWrite(verde, LOW); digitalWrite(vermelho, LOW); } void verdeFuncao(){ digitalWrite(azul, LOW); digitalWrite(verde, HIGH); digitalWrite(vermelho, LOW); } void amareloFuncao(){ analogWrite(azul, 0); analogWrite(verde, 50); analogWrite(vermelho, 255); } void roxoFuncao(){ analogWrite(azul, 207); analogWrite(verde, 0); analogWrite(vermelho, 255); } void brancoFuncao(){ digitalWrite(azul, HIGH); digitalWrite(verde, HIGH); digitalWrite(vermelho, HIGH); } void loop() { if(Serial.available()){ cor = Serial.readString(); Serial.println(cor); } if(cor == "Vermelho"){ vermelhoFuncao(); } if(cor == "Azul"){ azulFuncao(); } if(cor == "Verde"){ verdeFuncao(); } if(cor == "Amarelo"){ amareloFuncao(); } if(cor == "Roxo"){ roxoFuncao(); } if(cor == "Branco"){ brancoFuncao(); } }
Depois de passar o código acima para a sua IDE, verifique se a porta no qual o arduino está conectado está selecionada. Com tudo pronto, basta carregar o código para o arduino.
Colocando para funcionar
Agora vamos conferir o resultado deste projeto!
Entendendo a fundo
Hardware
- Como funciona
Quanto ao funcionamento específico do LED, recomendamentos que veja o artigo Como funcionam os LEDs, do Instituto Newton Braga, no qual ele explica o funcionamento dos LEDs de maneira geral comparando-o com a lâmpada incandescente.
- Montagem na protoboard
Relacionado a montagem, é composto apenas por resistores e um LED RGB, no qual os resistores estão presentes apenas para limitar o valor da corrente que circulará pelo circuito, pois sem ele a corrente poderia danificar o LED, ocasionando falha no funcionamento. Logo abaixo está o esquema eletrônico do projeto desenvolvido no tutorial de hoje.
Software
Neste tópico abordaremos cada instrução realizada pelo nosso código citado acima.
- Declarando as variáveis
São criadas quatro variáveis no código, três do tipo inteiro e uma do tipo string. O termo "const" utilizado antes do termo "int" foi empregado para dizer ao programa que a variável não sofrerá modificação em seu valor, ou seja, ela permanecerá com o mesmo valor no programa. Isso foi utilizado para declarar os pinos responsáveis pelas saídas que comandarão os terminais do LED RGB.
A String cor foi criada com o objetivo de ser armazenado nela a palavra que for escrita no monitor serial.
const int azul = 9; const int verde = 10; const int vermelho = 11; String cor;
Caso queira utilizar outros pinos para comandar seu LED RGB, lembre-se de utilizar somente os que possuem saída PWM.
- Configurações no void setup()
É iniciada a comunicação serial de 9600 bps (relembrando, caso você tenha dúvidas sobre como utilizar a comunicação serial, veja o tutorial Comunicação Serial Arduino). São declarados os pinos 'azul', 'verde' e 'vermelho' (no qual anteriormente foi atribuído a eles o valor que corresponde ao pino) como OUTPUT, ou seja, como saída.
void setup() { Serial.begin(9600); pinMode(azul, OUTPUT); pinMode(verde, OUTPUT); pinMode(vermelho, OUTPUT); }
- Criando funções para comandar o LED RGB
Nesta parte do código são criadas funções que tem por função comandar os terminais do LED RGB. Todas são iniciadas com void pois não retornarão nenhum valor para a função principal.
void vermelhoFuncao(){ digitalWrite(azul, LOW); digitalWrite(verde, LOW); digitalWrite(vermelho, HIGH); } void azulFuncao(){ digitalWrite(azul, HIGH); digitalWrite(verde, LOW); digitalWrite(vermelho, LOW); } void verdeFuncao(){ digitalWrite(azul, LOW); digitalWrite(verde, HIGH); digitalWrite(vermelho, LOW); } void amareloFuncao(){ analogWrite(azul, 0); analogWrite(verde, 50); analogWrite(vermelho, 255); } void roxoFuncao(){ analogWrite(azul, 207); analogWrite(verde, 0); analogWrite(vermelho, 255); } void brancoFuncao(){ digitalWrite(azul, HIGH); digitalWrite(verde, HIGH); digitalWrite(vermelho, HIGH); }
- Recebendo e armazenando a string de entrada
É verificado se há algum termo a ser lido do monitor serial. Caso haja, o termo é armazenado na variável cor. Logo após o armazenamento, é realizado um print no monitor serial do que foi recebido.
if(Serial.available()){ cor = Serial.readString(); Serial.println(cor); }
- Verificação do termo recebido
É realizada uma série de comparações para verificar o que foi recebido do monitor serial. As cores disponíveis para serem mostradas pelo LED RGB são: Vermelho, Azul, Verde, Amarelo, Roxo e Branco. Caso haja a confirmação que o que foi escrito corresponde a uma das opções, é chamada uma função específica para a realização do comando do LED RGB.
if(cor == "Vermelho"){ vermelhoFuncao(); } if(cor == "Azul"){ azulFuncao(); } if(cor == "Verde"){ verdeFuncao(); } if(cor == "Amarelo"){ amareloFuncao(); } if(cor == "Roxo"){ roxoFuncao(); } if(cor == "Branco"){ brancoFuncao(); }
Considerações finais
Esperamos que este tutorial tenha lhe esclarecido sobre a utilização deste componente eletrônico tão utilizado na área de desenvolvimento eletrônico.
Obrigado pela atenção e continue buscando conhecimento no portal do Vida de Silício.
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.
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]
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ô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).
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.
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.
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.
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.
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:
- 1 x Arduino UNO
- 2 x Sensores de obstaculo infravermelho (ou módulo TCRT5000)
- 1 x Chassi Robô móvel 2WD ( Ou 2 x Motores DC 5 v com roda + um suporte para o carrinho)
- 1 x Ponte H L298N
- 1 x Bateria 9 V + conector (ou fonte semelhante)
- Protoboard e Jumpers
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 !
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.
Conheça o que é o LilyPad e dê vida às suas roupas
Conheça o que é o LilyPad e dê vida às suas roupas
Uma das áreas relacionadas ao mundo maker que tem ganhado força é a wearable, área destinada ao estudo e aplicação das "tecnologias vestidas", onde componentes e circuitos eletrônicos são integrados à peças de roupas e acessórios para criar sistemas automáticos e interativos. No que se refere à essas soluções vestíveis, a placa de desenvolvimento LilyPad tem sido muito usada. Ela funciona como uma placa Arduino, só que foi projetada visando o uso em roupas e acessórios.
[toc]
Dando vida às roupas
A placa LilyPad é uma derivada das placas Arduino que visa atender projetos portáteis. Ela funciona conectada a baterias recarregáveis e pode ser integrada a projetos wearable. Ela foi desenhada e desenvolvida pela engenheira e designer Leah Buechley em conjunto com a SparkFun.
A placa em questão foi desenvolvida de maneira que fosse de fácil instalação em tecidos, nos quais é possível montar circuitos utilizando-a integrada a outros módulos, costurando-os com uma linha condutora, como podemos ver abaixo.
O hardware da placa pode ser visualizado logo abaixo. Por utilizar o mesmo microcontrolador que o Arduino Uno, a pinagem acaba sendo semelhante.
Exitem cerca de quatro modelos diferentes da família, que são:
- LilyPad Arduino Simple;
- LilyPad Arduino Main Board;
- LilyPad Arduino USB;
- LilyPad Arduino Simple Snap.
Vamos agora conhecer mais sobre cada uma, vendo suas características e vantagens.
LilyPad Arduino Simple
Possui ao todo 9 pinos que podem ser utilizados como INPUT / OUTPUT digitais, onde 5 deles podem ser utilizados para PWM e 4 podem ser utilizados como entrada analógica. Seu microcontrolador é o ATmega328p e sua tensão de operação é de 2,7 até 5,5V. Ela apresenta também um conector JST, no qual podem ser conectadas baterias de lítio de 3,7V. Para ser programado pela IDE do arduino, a placa em questão precisa ser conectado a um adaptador FTDI para com isso, ser conectado ao computador.
LilyPad Arduino Main Board
É a que apresenta o maior número de pinos em relação as outras, totalizando 14 pinos, no qual 6 podem ser utilizados para PWM e 6 podem ser utilizados como entrada analógica. Algumas versões possuem o ATmega168 como microcontrolador, enquanto outras possuem o ATmega328p. Sua tensão de operação está na faixa de 2,7 até 5,5V. Assim como o modelo anterior, necessita de um conversor FTDI.
LilyPad Arduino USB
Assim como a LilyPad Simple, essa também apresenta 9 pinos, onde 4 podem ser PWM e quatro podem servir como entrada analógica. Sua principal diferença para o modelo Simple, é que este possui um conector micro USB, onde ele poderá ser conectado diretamente ao computador, sem a necessidade de um adaptador FTDI. Seu microcontrolador é o ATmega32u4, e pode ser alimentado na faixa de 3,8 até 5V.
LilyPad Arduino Simple Snap
No aspecto visual, esta é a placa que mais se difere das demais, por apresentar encaixes condutores ao invés de furos. Em questão de hardware, se assemelha muito com o LilyPad Simple, apresentando assim 9 pinos ao todo, onde 4 podem ser PWM, e 4 podem ser entradas analógicas. Seu microcontrolador é o ATmega328p. Como o modelo Simple e o Main Board, o Simple Snap também necessita de um adaptador FTDI para ser conectado ao computador, para assim ser programado.
Mãos à obra - Começando com o tradicional Blink
Componentes necessário
Para este tutorial, tenha em mãos os seguintes itens:
Montando o projeto
Ensinaremos a você como passar a programação da IDE pro LilyPad por meio do Arduino Uno, sem a necessidade de se utilizar o conversor FTDI. O código que passaremos ao LilyPad será o nosso famoso e querido blink.
Primeiramente, precisamos preparar o arduino UNO para que ele seja o nosso "adaptador FTDI". O primeiro passo é remover o ATmega328p do seu arduino UNO, como pode-se ver abaixo.
AVISO: Cuidado ao remover o microcontrolador, pois há risco de se quebrar um terminal caso seja removido de maneira indevida.
Após isso, monte o circuito representado abaixo.
Pronto! Agora você poderá programar sua LilyPad sem problemas por meio da IDE do Arduino!
Programando
O código que será passado já é conhecido por todos, no qual consiste em deixar o LED presente na placa acesso por 1 segundo, e apagado por mais 1 segundo.
void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); }
Pelo fato dessa placa apresentar o microcontrolador ATmega328p, o mesmo presente no Arduino UNO, na opção de "Placa" podemos selecionar a opção "Arduino/Genuino Uno", sem a necessidade de ter que adicionar novas placas a IDE.
Colocando pra funcionar
Aqui podemos ver o resultado na prática, do blink.
Entendendo a fundo
Software
Relembrar é sempre bom, então falaremos o que irá ocorrer em cada linha do código.
Primeiramente inicia-se a programação configurando o pino 13 como saída (OUTPUT) no void setup().
pinMode(13, OUTPUT);
Após isso, é realizado os seguintes comandos no void loop():
- Define o estado lógico do pino 13 como alto, ligando o LED presente na placa;
- Ocorre uma espera de 1 segundo para a execução da próxima linha de programação;
- Define o estado lógico do pino 13 como baixo, desligando o LED presente na placa;
- Ocorre uma espera de 1 segundo para a execução da próxima linha de programação.
digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000);
Considerações finais
Esperamos que este tutorial tenha lhe esclarecido sobre como utilizar a placa LilyPad, principalmente a respeito de sua programação.
ATtiny85 - Primeiros passos
ATtiny85 - Primeiros Passos
Precisa criar projetos pequenos e com baixo consumo energético? Neste tutorial vamos apresentar o ATtiny85, um pequeno Microcontrolador (MCU) de 8 pinos, que pode ser programado pela Arduino IDE!
[toc]
O ATtiny85
Este pequeno MCU, apesar de ser inferior em relação ao desempenho quando comparado diretamente ao existente em uma placa Arduino UNO (ATmega328P). O ATtiny85 é útil em diversos projetos, entre eles, os portáteis, os de baixo consumo energético, os que utilizam poucos pinos, robôs e até em pequenos módulos separados de uma central, que por sua vez, se comunicaria com o ATtiny85 através de I2C, SPI ou UART (Serial), para controlar itens específicos, como por exemplo, uma placa de reles.
Características
- Tensão: 1,8V a 5,5V.
- Clock interno: 1MHz - 8MHz.
- Flash: 8KB.
- RAM: 512B.
- EEPROM: 512B.
- Digital Pins: 6.
- Analog Input (ADC): 4 canais de 10bit.
- PWM: 3 canais de 8bit.
- UART: 0.
- I2C: 1.
- SPI: 1.
Mapa de pinos
Em muitos projetos simples que fazemos, não usamos nem metade dos pinos do Arduino UNO por exemplo. Assim desperdiçando um imenso hardware. Quando pensamos em algo portátil, qualquer consumo desnecessário é ruim ao projeto, porém, o ATtiny85 pode nos ajudar com isso.
Para efeitos de comparação, o Arduino UNO funcionando normalmente, consome aproximadamente ~50mA. Já o ATtiny85, consome aproximadamente ~1mA! Em relação ao Arduino UNO podemos melhorar isso usando Sleeps, no entanto, devido a existência de um LED indicando que a placa esta ligada e a diversos outros itens, portanto, mesmo com Deep Sleep, o Arduino UNO consome aproximadamente ~15mA. Já o ATtiny85, por não conter nada além do MCU, no modo Deep-Sleep consome ~0,0001mA ou ~100nA! Seus projetos portáteis irão melhorar muito na questão de autonomia, pois, é possível liga-lo com uma simples bateria CR2032 que encontramos em placa-mãe de CPUs.
Um dos problemas mais comuns é a falta dos pinos físicos de UART ,logo, se você for usar o Serial Monitor para algum debug ou até a comunicação com outros MCUs via UART (Serial), será necessário o uso da Software Serial. Esta biblioteca emula a comunicação Serial (UART) em qualquer pino do MCU e visto que o ATtiny85 não há pinos físicos para UART, devemos usa-la. Entretanto, a biblioteca ocupa uma imensa quantidade de Flash e RAM.
Podemos trabalhar, satisfatoriamente, com o Clock interno, que vai de 1MHz até 8MH. No entanto, Se for preciso mais velocidade, é necessário adicionar um cristal externo de até 20MHz.
Instalando na Arduino IDE
A Arduino IDE não suporta o ATtiny85 nativamente, portanto, precisamos adicionar o Core do ATtiny85 a ela para conseguir usar o ATtiny85.
1-) Entre em https://github.com/SpenceKonde/ATTinyCore e copie o link .JSON que esta descrito dentro do arquivo "Installation" . Com este link iremos baixar os arquivos na Arduino IDE.
2-) Vá em "Preferências", adicione o link copiado em "URLs adicionais" e clique em "OK".
3-) Vá em "Ferramentas" -> "Placa" -> "Gerenciador de Placas...". Procure pelo ATtinyCore na lista e instale.
4-) Volte em "Ferramentas" -> "Placa" e veja que apareceu o ATtiny!
Mãos a obra - Piscando o primeiro LED no ATtiny85
Componentes necessários
Montando o projeto
O ATtiny85 não conta com conversor Serial e muito menos uma porta USB, portanto, devemos dar upload a ele através de um gravador que
neste caso será o Arduino UNO. A explicação estará logo abaixo em "Entendendo a fundo: Hardware".
Para gravar o "Bootloader" (definição dos Fuses) e o código em si, devemos utilizar um gravador externo. Iremos usar o Arduino UNO como ISP.
1-) Abra o exemplo "ArduinoISP" no menu de exemplos , e faça o upload deste código no seu Arduino UNO. Não esqueça de selecionar a porta COM e a placa "Arduino UNO" no menu de ferramentas, caso não esteja selecionado.
2-) Após efetuar o upload do "ArduinoISP" no Arduino UNO, ele está apto a gravar códigos em Microcontroladores ISP sem Bootloader. Podemos agora concluir as ligações necessárias para upload do código e gravação dos Fuses ("Bootloader") no ATtiny85.
Muita atenção na posição do ATtiny85! Deixamos a "bolinha indicadora" para a esquerda, se você inverter, consequentemente irá inverter os pinos de alimentação e queimar seu tiny85! Sempre confira as ligações com o Mapa de pinos.
Os pinos utilizados são os mesmos de uma comunicação SPI e alimentação.
- 5V.
- GND.
- CLOCK (13).
- MISO (12).
- MOSI (11).
- CS (10).
3-) Plugue o Arduino UNO no computador e abra um novo Sketch (projeto). Precisamos selecionar as configurações de "Bootloader" (Fuses) para depois gravar o código no tiny85. Entre no menu de ferramentas e indicamos que deixe igual o da imagem, apenas altere se souber o que esta fazendo!
Obs: Altere a porta COM para a porta que seu Arduino UNO estiver conectado.
Após arrumar todos itens, clique em "Gravar Bootloader". Isso irá apenas configurar os Fuses do ATtiny85, ainda não é o upload do nosso código. Você só precisa fazer isso para o primeiro upload ou se for alterar alguma dessas configurações futuramente.
Agora que gravamos o "Bootloader", podemos finalmente dar upload de nossos códigos. Basta manter as configurações selecionadas anteriormente, escrever o código e dar upload.
Veja como ficou nossa montagem:
Código do projeto
void setup() { pinMode(4, OUTPUT);//Define o pino 4 (PB4) como saida. } void loop() { digitalWrite(4, !digitalRead(4));//Inverte o estado do pino. delay(200);//Espera 200mS. }
Colando para funcionar
Após a gravação do "Bootloader" e do código, podemos ver essa mini-maravilha funcionando! Removemos os fios de upload e deixamos apenas a alimentação (5V e GND) juntamente com o LED no pino PB4.
Entendendo a fundo
Software
-Função pinMode
pinMode(4, OUTPUT);//Define o pino 4 (PB4) como saida.
Como podemos ver no Mapa de pinos, as opções em verde são os pinos que podemos usar normalmente. Estes estão descritos como PB0 ao PB5 e podemos usar o número para programar. Usamos o pino 4, que é referente ao PB4 (localizado ao lado do GND).
-Blink
digitalWrite(4, !digitalRead(4));//Inverte o estado do pino. delay(200);//Espera 200mS.
Efetuamos um Blink (inversão de estado) no pino 4, para que vejamos o LED piscando.
Desafio
Como citado anteriormente, podemos utilizar esse pequeno MCU para fazer sub-módulos de controle, que estará conectado em uma central (um Arduino MEGA por exemplo). Tente fazer a comunicação Serial (UART) entre o Arduino UNO com o ATtiny85 para fazer o LED piscar a partir de comandos recebidos pela Serial (UART). Também citamos que não há pinos físicos para UART no tiny85, então você precisa usar a biblioteca Software Serial.
Fechamento
Com esse minúsculo Microcontrolador, podemos fazer diversos projetos onde tamanho e consumo energético são essenciais e importantes. Entretanto, a pouca RAM e Flash comparada ao UNO, pode ser fatal se seus modos de programação não forem os melhores. Não se esqueça de "boas práticas" para programa-lo e bons estudos.
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.
- Introdução: Nessa parte você conhecerá um pouco mais o sensor SCT013
- Mãos à obra: Aqui você aprenderá a usar o Sensor de corrente SCT-013 na prática
- 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.
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.
- 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.
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.
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
- 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;
- Corrente Alternada: A corrente alternada varia ao longo do tempo gerando um campo magnético também variante ao longo do tempo;
- 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.
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).
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.
Podemos ver essa bobina com mais detalhes na foto a seguir
O circuito é bem simples:
- 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.
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:
- 1 x Placa Arduino;
- 1 x Sensor de corrente SCT-013 100A;
- 1 x Protoboard;
- 2 x Resistores de 10kΩ;
- 1 x Resistor de 330Ω;
- 1 x Capacitor eletrolítico de 100uF;
- Jumpers;
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.
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.
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.
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:
- 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:
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:
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.
Em seguida adicionamos um capacitor entre o GND e a saída de 2,5V no meio do divisor de tensão:
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.
Veja como vai fica nosso circuito:
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.
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.
[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.
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:
Sendo assim, podemos montar um circuito onde temos uma tensão que será proporcional à quantidade de gases poluentes.
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:
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.
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.
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.
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.
Mãos a Obra - Desenvolvimento do Projeto
Componentes necessários
- 1 x Sensor de gás MQ -135
- 1 x Arduino UNO ou outra placa Arduino
- 1 x Protoboard 400 furos ou outra Protoboard
- Fios Jumpers
Montando o projeto
A montagem do circuito é bem simples e direta. Basta seguir o esquemático abaixo.
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:
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:
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.
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.
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 !!!");
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.
- 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.
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?
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
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:
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 ):
A0, A1 e A2 são portas do nosso Chip:
Que em geral vem ligados a alimentação do módulo (VCC):
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.
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:
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:
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:
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.
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.
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 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.
Comunicação Wireless TCP com ESP (Parte 2)
Comunicação Wireless TCP com ESP
Daremos inicio a segunda parte do nosso material sobre comunicações Wireless. No tutorial anterior, foi abordado sobre o protocolo UDP, que não é orientado à conexão. Desta vez, vamos aprender sobre o protocolo TCP, este por sua vez, é orientado à conexão, que nos garante a entrega de mensagens, ordenação do recebimento/envio, etc. O código aqui apresentado irá funcionar tanto para ESP8266 quanto para o ESP32, já que a diferença é mínima e funciona da mesma forma.
[toc]
Protocolo TCP
TCP (Transmission Control Protocol) é um protocolo para transmissão de dados voltado à conexão, ou seja, permite que as maquinas se comuniquem e gerenciem o estado atual da conexão com seus clientes e servidores. Uma característica importante do TCP é seu gerenciamento do status da rede e os dados, com isto, podemos saber se o dado enviado foi realmente entregue ao destinatário, também garante a entrega ordenada das informações sem que haja colisões e perdas inperceptíveis. Muitas aplicações usam o TCP para efetuar suas comunicações, sendo amplamente usado em todo tipo de situação, ao contrario do UDP que por não ser orientado à conexão, pode gerar erros em nossos sistemas.
Mãos à obra
Componentes necessários
- 1x ESP8266(Usaremos NodeMCU 8266) ou 1x ESP32.
- Aplicativo TCP Client no celular.
Obs: Você pode usar qualquer aplicativo ou programa para transmitir os pacotes TCP. Nós usaremos o primeiro encontrado na Play Store para ser fácil de vocês encontrarem caso queiram usar também. Link do TCP Client na Play Store
Código do projeto
#ifdef ESP8266//Se estiver usando ESP8266, automáticamente irá adicionar as bibliotecas do ESP8266. #include <ESP8266WiFi.h> #include <WiFiServer.h> #elif defined ESP32//Se estiver usando ESP32, fara a mesma operaçao. #include <WiFi.h> #endif WiFiServer sv(555);//Cria o objeto servidor na porta 555 WiFiClient cl;//Cria o objeto cliente. void setup() { Serial.begin(115200);//Habilita a comm serial. WiFi.mode(WIFI_AP);//Define o WiFi como Acess_Point. WiFi.softAP("NodeMCU", "");//Cria a rede de Acess_Point. sv.begin();//Inicia o servidor TCP na porta declarada no começo. } void loop() { tcp();//Funçao que gerencia os pacotes e clientes TCP. } void tcp() { if (cl.connected())//Detecta se há clientes conectados no servidor. { if (cl.available() > 0)//Verifica se o cliente conectado tem dados para serem lidos. { String req = ""; while (cl.available() > 0)//Armazena cada Byte (letra/char) na String para formar a mensagem recebida. { char z = cl.read(); req += z; } //Mostra a mensagem recebida do cliente no Serial Monitor. Serial.print("\nUm cliente enviou uma mensagem"); Serial.print("\n...IP do cliente: "); Serial.print(cl.remoteIP()); Serial.print("\n...IP do servidor: "); Serial.print(WiFi.softAPIP()); Serial.print("\n...Mensagem do cliente: " + req + "\n"); //Envia uma resposta para o cliente cl.print("\nO servidor recebeu sua mensagem"); cl.print("\n...Seu IP: "); cl.print(cl.remoteIP()); cl.print("\n...IP do Servidor: "); cl.print(WiFi.softAPIP()); cl.print("\n...Sua mensagem: " + req + "\n"); } } else//Se nao houver cliente conectado, { cl = sv.available();//Disponabiliza o servidor para o cliente se conectar. delay(1); } }
Colando para funcionar
Devo lembrar que o IP padrão do ESP em modo Acess_Point é 192.168.4.1
1-) Precisamos nos conectar na rede WiFi criada pelo micro controlador.
2-) Logo, iremos adicionar o servidor com seu IP e PORTA no aplicativo. Lembre-se que você pode usar qualquer aplicativo ou programa de computador para isso.
3-) Após incluir os dados do servidor no aplicativo, podemos conectar-se e enviar os dados.
Obs: Também há dados disponíveis no Serial monitor, que o micro controlador escreveu, olhe como ficou.
Entendendo a fundo
Software
-Função WiFiClient::connected()
if (cl.connected())//Detecta se há clientes conectados no servidor. { }
Esta função retorna se há cliente conectado em nosso servidor. Também irá retornar que há clientes até que todos dados sejam lidos do buffer, se não, continuará aparecendo clientes conectados até que todos dados sejam lidos.
-Função WiFiClient::available()
if (cl.available() > 0)//Verifica se o cliente conectado tem dados para serem lidos. { }
Esta função, retorna a quantidade de bytes disponiveis para a leitura no buffer do cliente. Pode ser usada para detectar se há dados, e também para efetuar a leitura byte a byte do buffer, afim de montar a String final.
-Função WiFiClient::print()
cl.print();
Usada para enviar a String para o cliente. Há várias maneiras de mandar uma informação para o cliente, desde write(), printf() até print() e println().
-Função WiFiServer::available()
cl = sv.available();//Disponabiliza o servidor para o cliente se conectar.
Esta função, obtem um cliente que esta conectado ao servidor e tem dados disponiveis para a leitura. Pode ser entendida a grosso modo que diz ao cliente que há um servidor disponivel para enviar dados.
Desafio
O desafio desta vez, é tentar conectar multiplos clientes ao mesmo tempo em seu servidor. Este código não permite isto, então faça alterações e estude sobre as bibliotecas usadas para permitir multiplas conexões!
Fechamento
Neste tutorial, você aprendeu a efetuar uma troca simples de mensagens entre o Cliente (nosso celular) e o Servidor (ESP), pode ser usada de mesma forma para comunicação entre dois micro controladores. Na parte 3 deste material, aplicaremos as aulas passadas em um aplicativo em Android ou PC para se comunicar com nosso ESP8266/32. Não se esqueça de comentar sobre duvidas, elogios e criticas! Também aceitamos sugestões sobre a terceira parte deste material.
Touch capacitivo - ESP32
Touch capacitivo com ESP32
Nesse tutorial aprenderemos a usar sensores de touch capacitivo em nossos projetos com o ESP32, que tem suporte nativo a este recurso incrível. Em vários projetos, precisamos adicionar botões ou algum tipo de sensor para toque (pressão); o mais usado por ser barato e fácil, é o Push Button, porem, alem de dar um aspecto "velho" ao projeto, pode gerar problemas mais frequentes como por exemplo Bounce. Para contornar estes problemas, usaremos o Touch capacitivo, que é o mesmo do seu celular moderno (Smartphone), ao mínimo toque, é detectado e executado tal tarefa.
Mãos à obra - Implementando um touch capacitivo no ESP32
Componentes necessários
Montando o projeto
A montagem é simples, apenas sendo necessário ligar o jumper ao GPIO4, ficara parecido com o nosso:
Programando
long lastms;//Váriavel para guardar o ultimo toque. void setup() { Serial.begin(9600);//Inicia a comunicação Serial para visualização dos valores do Touch. pinMode(LED_BUILTIN, OUTPUT);//Define o LED OnBoard como saída touchAttachInterrupt(4, led, 20);//Atribui uma função (led) quando for detectado um valor menor de (20) ao pino (4). lastms = 0;//Inicializa a váriavel em 0. //Para chegar a este valor usado (20), é necessário apenas ver os valores que aparece no Serial monitor, //toque o fio e veja qual sera o novo valor. Ao tocar, a tendencia do valor é aproximar-se de 0. } void loop() { Serial.println(touchRead(4));//Mostra o valor do touch no monitor. delay(100); } void led()//função que foi atribuida para o evento do touch. { if (millis() - lastms > 150)//Verifica se o ultimo toque faz mais de 150mS { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Inverte o estado do led. lastms = millis();//Salva o ultimo tempo em que foi tocado. } }
Colocando para funcionar
Após o upload, podemos tocar na ponta do fio que perceberemos o LED invertendo seu estado. Se você manter tocado, verá que o LED ficará piscando, no intervalo de 150mS. Veja como ficou o nosso neste video:
Entendendo a fundo
Software
- Função de Interrupção touch - touchAttachInterrupt()
touchAttachInterrupt(4, led, 20);
Esta função, atribui uma rotina de interrupção para quando for detectado um valor abaixo do definido para o pino. Neste caso, quando o ESP32 detectar um valor abaixo de 20 no pino 4, irá chamar a função led(). A nossa função led() apenas inverte o estado do led com um intervalo de tempo para que não pisque muito rápido.
Lembre-se que a função interrupção é como uma chamada telefônica. O controlador para tudo que está fazendo para atende-la.
- Função led()
A função led() é chamada através da interrupção no pino 4.
void led()//função que foi atribuida para o evento do touch. { if (millis() - lastms > 150)//Verifica se o ultimo toque faz mais de 150mS { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Inverte o estado do led. lastms = millis();//Salva o ultimo tempo em que foi tocado. } }
Sabemos que o processamento de um microcontrolador é muito mais rápido do que podemos interagir. Quando acionamos o touch, o ESP chamará milhares de vezes a interrupção que foi atribuída a função led(). Por isso é importante implementarmos uma maneira de fazer com que a iteração do LED ocorra apenas após um determinado tempo
Uma forma de fazer isso é usar um contador de tempo com o auxilio da função millis(), uma variável auxiliar e um IF.
- A função millis() conta o tempo em milissegundos desde que o ESP32 foi ligado.
- A variável auxiliar armazena o valor do millis() da ultima vez que houve alteração do estado do LED
- A condicional IF compara o tempo atual do millis() com o tempo armazenado na variável auxiliar, se for maior que o tempo escolhido, ele entra na rotina do IF, altera o estado do LED e novamente armazena o novo tempo de millis().
Ou seja: Essa rotina subtrai o tempo atual com o anterior, e se for maior que 150mS, irá inverter o LED e salvar o novo tempo. Dessa forma, só invertemos o estado do LED depois que passou 150ms da ultima mudança de estado.
Veja que se você ficar com o dedo pressionado o tempo todo, teremos o LED ligando e desligando de 150ms em 150ms.
Você poderia usar delay() também, mas o problema é que o delay mantem o microcontrolador parado contando o tempo enquanto esse tipo de rotina implementada permite que o controlador continue com a execução das outras tarefas.
Por isso essa função condicional é bastante usada para atribuir intervalos entre as ações, uma alternativa saudável para o delay().
- Função de leitura do touch
touchRead(4)
Esta função, retorna o valor do pino (Threshold). Este valor pode váriar de acordo do lugar de ESP32. Em nossos testes, ao plugar o ESP32 na Protoboard, o valor foi de 84 para 60. Os valores quando não estamos tocando ficaram em média de 60, e ao tocar, aproximou-se de 0.
Por isso definimos 20 na função anterior, pois ao tocar, o valor aproxima-se de 0, então colocando 20, teremos certeza que foi um toque e chamamos a função para inverter o LED.
- Uma outra forma de implementar o touch
Veja que você poderia implementar a leitura no seu programa sem usar a interrupção. Usando um IF na função loop por exemplo.
void loop() { Serial.println(touchRead(4));//Mostra o valor do touch no monitor. delay(100); if(touchRead(4) < 20) //verifica se o valor lido é menor que 20 { if (millis() - lastms > 150)//Verifica se o ultimo toque faz mais de 150mS { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Inverte o estado do led. lastms = millis();//Salva o ultimo tempo em que foi tocado. } } }
O programa todo ficaria assim:
long lastms;//Váriavel para guardar o ultimo toque. void setup() { Serial.begin(9600);//Inicia a comunicação Serial para visualização dos valores do Touch. pinMode(LED_BUILTIN, OUTPUT);//Define o LED OnBoard como saída lastms = 0; } void loop() { Serial.println(touchRead(4));//Mostra o valor do touch no monitor. delay(100); if(touchRead(4) < 20) //verifica se o valor lido é menor que 20 { if (millis() - lastms > 150)//Verifica se o ultimo toque faz mais de 150mS { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Inverte o estado do led. lastms = millis();//Salva o ultimo tempo em que foi tocado. } } }
Hardware
Antes do touch capacitivo entrar em uso continuo em celulares, o touch era resistivo, sendo necessário tocar a tela com certa pressão para que fosse detectado o toque. Já o touch capacitivo, é mais sensível e permitindo um manuseio mais fácil da tela. Veja a imagem representando o touch capacitivo:
Quando você toca no fio ou tela, há uma troca de elétrons entre as partes, e com isso, permite o nosso sistema detecta-lo.
Desafio
O desafio desta vez, é que você monte um teclado matricial com o touch do ESP32 para digitar uma senha por exemplo.
Fechamento
Hoje você aprendeu a usar esta íncrivel função que ESP32 nos dá. Com ela, é possível deixar nosso projetos extremamente modernos e bonitos. Alem disto, você também pode usa-lo em conjunto com o ULP para acordar o ESP32 de Deep-Sleep, viabilizando projetos portáteis e vestíveis. Se houver alguma sugestão, dúvida ou crítica, comente abaixo que iremos te responder.
Conhecendo o ESP32
Conhecendo o ESP32
Vamos conhecer mais a respeito do incrível "irmão mais novo" do nosso querido ESP8266, o ESP32. Este novo microcontrolador da Espressif é uma melhoria do seu antecessor, com mais poder de processamento (Triple core), memória e novos recursos, incluindo Bluetooth e sensores de touch capacitivo. Veja abaixo uma lista de características do ESP32.
Características do ESP-WROOM32
- Processador principal: LX6 32-bit Dual-core, operando 2-240 MHz.
- Processador secundário: ULP (Ultra Low Power coprocessor) 8MHz e consome 150uA.
- FLASH: 4MB.
- RAM: 520kB.
- GPIO: 34, com 3.3V e 12mA.
- ADC: 18, com resolução de 12-bit.
- DAC: 2, com resolução 8-bit.
- WiFi: 2,4 GHz, 802.11 b/g/n.
- Bluetooth: Bluetooth Low Energy v4.2 (BLE).
- Acelerador via hardware para encriptações, hash e afins. (AES, RSA, SHA e ECC).
- True Random Number Generator (TRGN).
- 4 Timers de 64-bit.
- 4 Watchdogs.
- 10 Sensores de Touch Capacitivo.
- 1 Sensor de temperatura interno.
- 1 Sensor de efeito Hall.
O ULP é um processador de baixo consumo que pode ser usado até em Deep Sleep, e com isso, conseguimos acordar o micro controlador das mais diversas formas, como por exemplo dados na Serial, informação de algum sensor ou os próprios sensores de toque capacitivo. Vários erros que aconteciam com o ESP8266 foram corrigidos e/ou melhorados, por exemplo, as tarefas de background, interrupções, yield() e watchdogs. Ainda é cedo para dizer (no momento) se foram corrigidos totalmente ou apenas melhorados para que gerem menos inconvenientes.
Podemos programa-lo de diversas formas, inclusive na Arduino IDE. Porem, a inclusão das funções do ESP32 ainda está atrasada em relação a esp-IDF, há varias funções que ainda não foram portadas para o Core do Arduino, a principal até o momento, é o Bluetooth, que ainda não é possível usufruir corretamente. Se você precisa usar o Bluetooth ou alguma função que ainda não foi incluída à Arduino IDE, sugerimos que use a esp-IDF.
Chega de papo e vamos programar esta belezinha, o nosso novo brinquedo. Iremos usar a Arduino IDE por já estarmos familiarizado com os comandos e funções.
Instalando o ESP32 na Arduino IDE
Instalando o Python no seu computador
Talvez seja necessário a instalação do Python em sua maquina caso ainda não tenha instalado. Se você já programou o ESP8266, provavelmente já tem o Python instalado e não precisara instalar novamente.
- Baixando o instalador do Python
Entre em ( https://www.python.org/downloads/ ) e Baixe o Python 2.7.XX
- Instalando o Python
Abra o instalador e siga até a terceira tela. Na terceira tela ative a opção "Add Python.exe to Path" clicando em "Will be installed on local hard drive" e termine a instalação.
Instalando o Driver (Core) do ESP32 na IDE Arduino
1 - Baixe o ZIP do ESP32, disponível no site do GitHub. ( https://github.com/espressif/arduino-esp32 )
2- Extraia os arquivos dentro da pasta Arduino/hardware/espressif/esp32/ , que se encontra em seu HD. Ficara igual o nosso:
3- Vá em esp32/tools e execute o arquivo GET.exe . Irá começar o download de novos arquivos e isso pode demorar um pouco. Ao fim, a janela se fechara automaticamente.
4- Abra a Arduino IDE, e veja se as placas do ESP32 estão disponíveis para seleção.
5- Plugue seu ESP32 no computador e espere a instalação automática do driver CP2102. Alguns usuários relatam que não foi possível a instalação automática, sendo necessário a instalação manualmente do driver CP2102. Após a instalação do driver, selecione a porta COM respectiva do seu ESP32, se estiver em duvida qual seja, desconecte o ESP32 do computador e veja quais portas estão ativas, agora conecte novamente e veja a porta que apareceu.
Mãos à obra
Componentes necessários
- 1x ESP32 (Usaremos o NodeMCU32).
Programando
Iremos fazer o primeiro upload para nossa placa com o clássico Blink. O Blink é um código para piscar LEDs de forma bem simples. Na placa NodeMCU há um LED OnBoard que iremos piscar, então não é preciso usar um LED externo. Caso você queira usar um LED externo, não se esqueça de alterar os pinos no código.
Código do projeto
void setup() { pinMode(LED_BUILTIN, OUTPUT);//Habilita o LED onboard como saída. } void loop() { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Faz o LED piscar (inverte o estado). delay(250);//espera 250mS para inverter o estado do LED. }
Colocando para funcionar
Após o upload do código, nosso micro controlador começara a piscar, veja o nosso:
Entendendo a fundo
Software
- Função Setup
void setup() { pinMode(LED_BUILTIN, OUTPUT);//Habilita o LED onboard como saída. }
A função de Setup do Arduino é feita da mesma forma, ao ligar/resetar o micro controlador, esta função é executada uma unica vez, por isso o nome "setup", referenciando uma função que configure nosso micro controlador. Normalmente as configurações iniciais, como por exemplo definição de pino (Input/Output) só é necessária ser feita uma vez, logo, adicionamos ela ao setup. Diferentemente do Loop, que é aonde nosso código é executado infinitamente.
- Função pinMode
pinMode(LED_BUILTIN, OUTPUT);//Habilita o LED onboard como saída.
A função pinMode(pino, estado) é usada para definir qual o estado de um pino do micro controlador, no caso, iremos controlar um LED, então foi declarado OUTPUT, para que possamos alterar o nivel lógico do pino (LOW ou HIGH).
- Função digitalWrite
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Faz o LED piscar (inverte o estado).
A função digitalWrite(pino, estado) é usada para "escrever" um valor no pino do micro controlador. Você pode usar LOW e HIGH, para acender ou apagar um LED, ligar ou desligar motores e etc. Também foi usado a função digitalRead(pino) que faz a leitura do atual estado do pino, e após pegar este valor, nós invertemos com a exclamação " ! ", que se encontra antes da função digitalRead(). Fazendo isto, nós sempre iremos alternar o estado do LED, ou seja, se esta ligado, desligamos; e se esta desligado, ligamos.
- Função Delay
delay(250);//espera 250mS para inverter o estado do LED.
A função delay(mS) é usada para adicionar um tempo entre as tarefas. Se ela não for usada, o LED irá piscar muito rapidamente, impossibilitando a visualização. Logo, usamos 250mS para que possamos ver o LED piscando lentamente.
Fechamento
Então chegamos ao fim de mais um tutorial, aprendemos a instalar e dar o primeiro upload neste incrivel micro controlador. Nos proximos tutoriais, iremos ensinar sobre como dividir tarefas entre os 2 processadores, permitindo assim, que você rode 2 códigos ao mesmo tempo.
Você também pode optar por instalar a ESP-IDF, um ambiente completo de desenvolvimento pro ESP32 que suporta todas configurações e features do microcontrolador: https://portal.vidadesilicio.com.br/instalando-esp-idf-no-windows-esp32/
Se houver dúvidas ou sugestões, fique à vontade para comentar!
O que é Watchdog e como usar do ESP8266?
O que é Watchdog e como usar do ESP8266?
Vamos aprender o que é e como usar o Watchdog do ESP8266. O ESP conta com dois Watchdog's, um implementado via software, e outro via hardware (interno), aprenderemos uma utilidade básica para esta incrível ferramenta no mundo dos micro controladores!
Este tutorial exige um conhecimento no mínimo intermediário/avançado sobre programação e hardware!
[toc]
Sobre o Watchdog
Watchdog (traduzindo para cão de guarda) é um dispositivo interno ou externo, separado do clock e processador principal. Sendo assim, caso o micro controlador ou software venha a travar, por ser independente do resto, irá reiniciar o sistema.
O Watchdog é basicamente um "Contador" fora do sistema principal. Quando ele é ativado, é necessário reseta-lo dentro do tempo pré-estabelecido, caso contrario, o Watchdog irá reiniciar completamente o micro controlador ou software em que for implementado.
Imagine que você colocou seu prato de comida no microondas e digitou 15 Segundos para apenas aquecer a comida, e por algum motivo, o microondas trave enquanto o aquecimento esta ligado. Sua comida poderia super-aquecer ou coisa pior. Este travamento poderia ser resolvido com o uso do Watchdog, já que com o sistema travado, não ocorreria o Feed do Watchdog, e assim ocasionaria o reinicio do sistema, preservando sua comida.
Os usos desta ferramenta são gigantescos, já que todo sistema pode travar e gerar terríveis danos. Um motor ligado a um sistema travado, pode gerar perdas em fábricas ou até matar alguém. Watchdog é de suma importância em diversos projetos!
Entretanto, até o Watchdog pode falhar. Nunca confie em um único sistema de segurança, se for preciso, adicione mais formas! O tutorial é apenas uma apresentação da ferramenta, não nos responsabilizamos por nada.
O ESP8266, conta com dois Watchdog's, um via software e outro via hardware. É possível desabilitar o SW WDT (Software Watchdog), mas até o momento não há formas de desabilitar o HW WDT (Hardware Watchdog).
Software Watchdog tem duração de ~3,2 Segundos. Se não for alimentado durante este tempo, irá reiniciar o software do ESP e manterá os estados dos pinos.
Hardware Watchdog tem duração de ~8 Segundos. Se não for alimentado durante este tempo, irá reiniciar completamente o ESP, inclusive mudando os estados dos pinos para o padrão do boot.
Mais sobre Watchdog's do ESP8266, clique AQUI.
Mãos à obra
Componentes utilizados
- 1 - ESP8266 (Usaremos dois NodeMCU).
- LED OnBoard
Montando o projeto
Para este exemplo, acenderemos o LED_BUILTIN do NodeMCU, este LED OnBoard, está conectado ao pino D4 do NodeMCU.
Código do projeto
O código e explicação serão separada por partes, mostrando ambos Watchdog's resetando o ESP, e também como corrigir este problema.
Será duas partes por Watchdog, uma que faz o Watchdog reiniciar o MCU, e outro que faz a alimentação correta e não reiniciando o MCU.
Para entender o que foi repassado com os código, leia a explicação do software logo abaixo!
Software Watchdog (Parte 1, sem alimentar):
void setup() { pinMode(D4, OUTPUT);//Define o LED Onboard como saida. digitalWrite(D4, 1);//Apaga o LED. delay(2000);//Espera 2 segundos para visualizarmos que o ESP foi iniciado. for (long x = 0; x < 20; x++)//Ira piscar o LED 10x com intervalo de 250mS. { digitalWrite(D4, !digitalRead(D4));//Inverte o estado do LED. delayMicroseconds(250000);//Espera 250mS } //Após piscar 10x sem erros, irá entrar no loop e o LED começara a piscar // rapidamente indicando que não ocorreu erros. //Este código não efetua o FEED do SW WDT dentro do FOR, e ocasionara no // reset do ESP, então nunca irá piscar rapidamente, desde que não irá para o loop. } void loop() { digitalWrite(D4, !digitalRead(D4)); delay(50); }
Software Watchdog (Parte 2, alimentando corretamente):
void setup() { pinMode(D4, OUTPUT);//Define o LED Onboard como saida. digitalWrite(D4, 1);//Apaga o LED. delay(2000);//Espera 2 segundos para visualizarmos que o ESP foi iniciado. for (long x = 0; x < 20; x++)//Irá piscar o LED 10x com intervalo de 250mS { digitalWrite(D4, !digitalRead(D4));//Inverte o estado do LED. delayMicroseconds(250000);//Espera 250mS yield();//Efetua o feed do SW WDT. } //Após piscar 10x sem erros, irá entrar no loop e o LED começara a piscar // rapidamente indicando que não ocorreu erros. //Este código efetua o feed do SW WDT, então logo após as 10 piscadas, // começara a piscar rapidamente pois entrou no loop. } void loop() { digitalWrite(D4, !digitalRead(D4)); delay(50); }
Hardware Watchdog (parte 1, sem alimentar):
void setup() { pinMode(D4, OUTPUT);//Define o LED Onboard como saida. digitalWrite(D4, 1);//Apaga o LED. delay(2000);//Espera 2 segundos para visualizarmos que o ESP foi iniciado. ESP.wdtDisable();//Desabilita o SW WDT. for (long x = 0; x < 20; x++)//Irá piscar o LED 10x com intervalo de 1 Segundo { digitalWrite(D4, !digitalRead(D4));//Inverte o estado do LED. delay(1000);//Espera 1 Segundo. yield(); } //Após piscar 10x sem erros, irá entrar no loop e o LED começara a piscar // rapidamente indicando que não ocorreu erros. //Este código não efetua o FEED do HW WDT dentro do FOR, e ocasionara no // reset do ESP, então nunca irá piscar rapidamente, desde que não irá para o loop. } void loop() { digitalWrite(D4, !digitalRead(D4)); delay(50); ESP.wdtFeed();//Alimenta o HW WDT. }
Hardware Watchdog (parte 2, alimentando corretamente):
void setup() { pinMode(D4, OUTPUT);//Define o LED Onboard como saida. digitalWrite(D4, 1);//Apaga o LED. delay(2000);//Espera 2 segundos para visualizarmos que o ESP foi iniciado. ESP.wdtDisable();//Desabilita o SW WDT. for (long x = 0; x < 20; x++)//Irá piscar o LED 10x com intervalo de 1 Segundo { digitalWrite(D4, !digitalRead(D4));//Inverte o estado do LED. delay(1000);//Espera 1 Segundo. yield(); ESP.wdtFeed();//Alimenta o Watchdog. } //Após piscar 10x sem erros, irá entrar no loop e o LED começara a piscar // rapidamente indicando que não ocorreu erros. //Este código efetua o feed do HW WDT, então logo após as 10 piscadas, // começara a piscar rapidamente pois entrou no loop. } void loop() { digitalWrite(D4, !digitalRead(D4)); delay(50); ESP.wdtFeed();//Alimenta o Watchdog. }
Entendendo a fundo
Software
O Feed do Software Watchdog no ESP, é feito em diversas formas, e normalmente não é necessário preciso implementar as funções de Feed. Os 4 principais métodos para efetuar o feed do Software Watchdog no ESP são:
delay();
Usando o clássico delay(), automaticamente é feito o Feed do SW WDT, então não é preciso se preocupar. Lembre-se que a função delayMicroseconds() não efetua o feed do SW WDT. Também é possível usar delay(0) para efetuar o feed do SW WDT.
yield();
Esta função faz diversos processamentos de background no ESP, inclusive o Feed do SW WDT. Esta função é praticamente o coração do ESP.
ESP.wdtFeed();
Esta outra função também alimenta o SW WDT.
Término do Loop principal.
Ao termino do loop principal, é feito automaticamente a chamada do yield(), que ocasiona no gerenciamento das tarefas de background do ESP.
A ideia do código usado para mostrar no funcionamento do SW WDT, é que pisque o LED lentamente 10x no inicio do código para mostrar que o ESP foi ligado/reiniciado. Logo em seguida após passar pelo setup(), já dentro do loop(), é feito com que o LED pisque mais rapidamente, para permitir a visualização de que o código prosseguiu sem resetar.
Pensado nisto, ao testarmos o código do Software Watchdog (parte 1), percebemos que isto não ocorre, pois como foi dito anteriormente, o SW WDT, tem um tempo de ~3,2 Segundos, e dentro do laço FOR foi usado o delayMicroseconds(250000) que não faz o feed do SW WDT. Logo percebemos que o LED irá piscar 6x totalizando ~3 Segundos, e não 10. Isto ocorre pois não efetuamos o feed do SW WDT antes de acabar o tempo estabelecido, ocasionando o Reset do ESP. Podemos confirmar isto olhando o Serial Monitor, que mostra o Reset do ESP.
Agora avançando ao Software Watchdog (parte 2), você perceberá que o ESP não é reiniciado, isto pois dentro do laço FOR, colocamos um dos métodos para efetuar o feed do SW WDT, neste caso, o yield(). É possível ver que após o ESP piscar lentamente 10x, ele entra no loop() e começa a piscar rapidamente, mostrando que o código continua fluindo.
Resumo: Até aqui foi mostrado como é feito o feed do software Watchdog. É possível desabilita-lo caso seja necessário, chamando a função ESP.wdtDisable(). Agora vamos ao Hardware Watchdog!
Hardware Watchdog
Este HW WDT, não pode ser desabilitado, e tem o tempo de ~8 Segundos para efetuar o Reset ao micro controlador. O feed do HW WDT, é feito unicamente pela função ESP.wdtFeed(). Os outros métodos citados acima não fazem o feed o HW WDT!
A ideia deste código, é a mesma que a anterior. Adicionar um laço FOR para o LED piscar 10x, e após acabar, irá entrar no loop() piscando rapidamente o LED, indicando que não houve Reset.
Testando o código Hardware Watchdog (parte 1), percebe-se que o LED piscou ~4x e após isto, o ESP é resetado por causa que não efetuamos o feed corretamente com a função necessária. Veja que mesmo utilizando dois métodos do SW WDT, (delay e yield), o ESP irá reiniciar. Já que o ESP reseta, não é possível ver o LED piscar rapidamente após entrar no loop().
Já com o código do Hardware Watchdog (parte 2), podemos ver que o LED pisca 10x lentamente e após isto, começa a piscar rapidamente, indicando que o código não travou no laço FOR. Você deve efetuar o feed do HW WDT pela função própria, não se esqueça!
Colocando para funcionar
Mostraremos o funcionamento na prática do SW WDT ligado à um solenoide pequeno. Não é necessário o código, apenas entender que:
Botão da esquerda: Liga ou Desliga o solenoide.
Botão da direita: Gera um travamento no sistema por um loop infinito (While).
Ao inicio do código, o solenoide é ativado 2x, indicando o inicio do programa. Podemos perceber que o controle do solenoide funciona perfeitamente, invertendo seu estado atual. Mas após gerar um evento que trava o ESP, o botão de controle do solenoide para de funcionar, isto acontece pois o ESP travou!
Mas logo após ~3 Segundos, o ESP é reiniciado automaticamente pelo Software Watchdog e os controle voltam a funcionar.
Fechamento
Aprender a utilizar esta ferramenta de extrema importância em projetos é quase indispensável se você pretende "seguir carreira" nesse mundo. Um sistema travado por gerar danos grandes nas mais diversas áreas e situações, sempre tome cuidado com a garantia de funcionamento do seu projeto! Dúvidas? Sugestões? Críticas? Comente abaixo!
Protocolo de tempo NTP com ESP
Protocolo de tempo NTP com ESP
É comum que em projetos de automação e robótica seja necessário saber a hora correta, para marcar a hora em que uma ação ocorreu ou até para ativar sensores em certo horário. Vamos aprender a adicionar um RTC (Real Time Clock - Relógio de tempo Real) ao ESP sem precisar de um hardware externo, como por exemplo um DS1307 ou do DS3231. Para isso, usaremos o NTP que só precisa de uma conexão com a internet o que é facilmente resolvido quando o assunto é projetos com ESP e IoT.
Sobre o NTP
Do Wikipédia:
O NTP é um protocolo para sincronização dos relógios dos computadores baseado no protocolo UDP sob a porta 123, para sincronização do relógio de um conjunto de computadores em redes de dados com latência variável. O NTP permite manter o relógio de um computador com a hora sempre certa e com grande exatidão.
O NTP serve tanto para atualizar e também manter os horários e datas sincronizadas entre dispositivos. Não há muitas explicações sobre isto, porém caso queira aprender mais sobre o NTP, clique AQUI ou AQUI.
Digamos que você tem uma rede de sensores, e precisa que eles liguem as 20h da noite, as melhores alternativas para isto, são um RTC externo/interno ou até o NTP caso haja conexão com a internet. Para o exemplo deste tutorial, acenderemos o LED Onboard de acordo com o horário que iremos definir. Com o NTP, também é possível arrumar a data e hora de um RTC externo que esteja errado!
Neste GIF, é mostrado o funcionamento do exemplo deste tutorial, no qual o LED foi acionado as 19:23:30.
Mãos à obra
Componentes necessários
Montando o projeto
Nesse projeto usaremos apenas a placa NodeMCU. Usaremos o LED que já vem na placa ligado ao Pino D4 para fazer nossa experiência. Também funciona com ESP32.
Código do projeto
Não se esqueça de alterar as credenciais do WiFi e usar o fuso horário correto. Também altere para o horário que desejar, como o tutorial foi feito as 19:23, usamos este valor.
#include <NTPClient.h>//Biblioteca do NTP. #include <WiFiUDP.h>//Biblioteca do UDP. #include <ESP8266WiFi.h>//Biblioteca do WiFi. WiFiUDP udp;//Cria um objeto "UDP". NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);//Cria um objeto "NTP" com as configurações. #define led D4//Define o LED ao pino D4. String hora;//Váriavel que armazenara o horario do NTP. void setup() { Serial.begin(9600);//Inicia a comunicação serial. pinMode(led, OUTPUT);//Define o pino como saida. digitalWrite(led, 1);//Apaga o LED. WiFi.mode(WIFI_STA); WiFi.begin("SUA REDE", "SUA SENHA");//Conecta ao WiFi. delay(2000);//Espera a conexão. ntp.begin();//Inicia o NTP. ntp.forceUpdate();//Força o Update. } void loop() { hora = ntp.getFormattedTime();//Armazena na váriavel HORA, o horario atual. Serial.println(hora);//Printa a hora já formatada no monitor. if (hora == "19:23:30")//Se a hora atual for igual à que definimos, irá acender o led. { digitalWrite(led, 0);//Acende } delay(1000);//Espera 1 segundo. }
Entendendo a fundo
Software
-Declarando o objeto
NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);//Cria um objeto "NTP" com as configurações.
Aqui é criado o objeto NTP com os seguintes parâmetros:
- Objeto UDP.
- Servidor do NTP, Acesse ESTE link para ver os servidores brasileiros disponíveis.
- Fuso horário multiplicado por segundos, apenas altere o fuso horário se for necessário.
- intervalo de updates para atualização da hora, é necessário para manter a hora correta. O padrão é 1 Minuto.
-Função NTPClient::begin() e forceUpdate()
ntp.begin();//Inicia o NTP. ntp.forceUpdate();//Força o Update.
Iniciamos o NTP e também forçamos o update para certificar de que a hora esteja certa.
-Salvando a hora atual
hora = ntp.getFormattedTime();//Armazena na váriavel HORA, o horario atual.
Esta função ntp.getFormattedTime() retorna uma string com a hora atual, contendo HH:MM:SS. Salvamos isto na nossa String hora
Também é possível pegar os dados separados ou até o dia. Veja as funções da biblioteca!
-Acionando o LED com a hora
if (hora == "19:23:30")//Se a hora atual for igual à que definimos, irá acender o led. { digitalWrite(led, 0);//Acende }
Caso a variável que contem a hora atual seja igual à definida, neste caso é 19:23:30, acenderá o LED.
Desafio
O desafio desta vez, é manter o LED aceso entre intervalos de tempo, por exemplo das 13h até as 16h. Para isto, pode-se usar a boa e velha lógica booleana ou a função constrain() do arduino. Boa sorte!
Considerações finais
A implementação deste simples protocolo pode ser de grande ajuda e utilidade em seus projetos que tenham conexão com a Internet. Dúvidas? Sugestões? Críticas? Comente abaixo!
Sleep Modes - Economizando energia- ESP8266
Economizando energia
Atire a primeira pedra quem nunca pensou em fazer algo portátil com o ESP8266. Vamos aprender sobre os diversos modos de Sleep presente no ESP8266, desde o Modem Sleep até o Deep Sleep.
Por que Sleep em micro controladores?
Deixar o MCU ligado durante algum tempo ocioso, consome muita bateria desnecessariamente e torna inviável projetos portáteis, já que precisaríamos trocar constantemente a bateria ou pilha. Para isto, existem os Sleep modes, que adormecem certas funções do MCU, permitindo o uso em projetos portáteis.
Modem Sleep
Somente o rádio WiFi/Wireless do MCU é desligado, todo o resto do sistema continua ligado normalmente. É útil quando o envio de informações se faz em intervalos de tempos e que é preciso o funcionamento do sistema em geral, como por exemplo acender LEDs, fazer comunicações e etc. O rádio não fica completamente desligado, de acordo com os datasheet's, o ESP faz um gerenciamento entre os Beacons (DTIM) do seu roteador e desliga entre os intervalos definidos.
Consumo: ~15mA.
LightSleep
Rádio WiFi/Wireless e Clock interno são desligados. CPU fica pendente. Com este modo, é possível acordar o CPU com um sinal enviado (HIGH/LOW) para um pino definido no software, continuando seu código normalmente. Como o anterior, este modo também possui o "Automatic sleep", que faz o MCU dormir entre os intervalos do DTIM.
Consumo: ~400 μA.
Deep Sleep
Rádio WiFi/Wireless, CPU e CLOCK ficam desligados, Apenas o RTC continua ON. Este modo é o melhor na questão de consumo já que praticamente todo o MCU fica desligado. É útil quando precisamos por exemplo enviar dados de um sensor a cada 5 minutos para um banco de dados ou gravar na EEPROM para futuramente ser enviado caso não haja conexão com a internet.
Consumo: ~20μA.
Como o foco deste material será a autonomia, será ensinado como é o funcionamento do Deep Sleep, já que tem o menor consumo e é facilmente configurado através do código. Caso você ainda não tenha conhecimento sobre os BOT's do Telegram, veja ESTE tutorial.
Faremos um sensor de luminosidade portátil, que irá detectar o nível de luz no local e enviar por um BOT no Telegram a mensagem para o nosso chat a cada 1 minuto. Entre os intervalos, entrará em Deep Sleep para poupar a bateria.
Este projeto poderá ser feito por qualquer ESP8266, porém é necessário que o GPIO16 (D0) esteja conectado ao RESET. O ESP8266 01 não conta com este pino fisicamente, entretanto, é possível liga-lo ao RESET da seguinte forma:
Mãos à obra
Componentes necessários
Para este projeto, usaremos novamente o NodeMCU, e também mostraremos o consumo dele durante o Deep-sleep.
- 1 - ESP8266 (Usaremos o NodeMCU).
- 1 - LDR.
- 1 - Resistor de 470 Ω.
- X - Jumper's.
Montando o projeto
Faça as ligações necessárias para se ler um LDR, conectado ao pino A0. Para o Deep Sleep acordar o MCU após o tempo definido, precisamos ligar o pino D0 ao RST.
Código do projeto
Não se esqueça de colocar as informações sobre seu WiFi, ID e TOKEN do Telegram. Ensinamos como pegar o ID no tutorial do Telegram, de uma olhada!
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> #define BOTtoken "1659677:AberDacEJadpENQS_mUTIvLfGQ5f6dQe"//Define o token do BOT. WiFiClientSecure client; UniversalTelegramBot bot(BOTtoken, client); String ldr; void setup() { WiFi.mode(WIFI_STA);//Define o ESP como Station. WiFi.begin("SUA REDE", "SUA SENHA");//Conecta na rede. while (WiFi.status() != WL_CONNECTED)//Espera a conexão se estabelecer. { delay(1); } ldr += analogRead(A0);//Le o LDR. bot.sendSimpleMessage("SEU ID", ldr, "");//Envia o valor do LDR para o chat. ESP.deepSleep(1 * 60000000);//Dorme por 1 Minuto (Deep-Sleep em Micro segundos). } void loop() { }
Entendendo a fundo
Hardware
Para o Deep sleep funcionar corretamente, é preciso fazer a ligação do pino D0 (GPIO16) ao pino de RESET. Quando o RTC estoura o tempo (Overflow), é gerado um pulso LOW ao pino do RESET, fazendo com que o mesmo seja resetado e recomece o código do começo! Por este motivo, o código foi escrito no setup(), já que não foi necessário nenhuma ação dentro do loop(), mas isto não impede de escrever dentro do loop().
Sempre que o o ESP for resetado, ele iniciara o código do começo!
Software
-Função ESP.deepSleep()
ESP.deepSleep(1 * 60000000);//Dorme por 1 Minuto (Deep-Sleep em Micro segundos).
Este comando coloca o MCU em Deep-sleep por 1 Minuto. O valor à ser colocado na função é em Micro Segundos!
Após você usar este comando, o MCU irá dormir até que o tempo se acabe. Quando o tempo definido estourar (Acabar), o RTC irá gerar um pulso LOW ao pino RST, fazendo com que o MCU seja reiniciado completamente. Após o reset, o código irá se iniciar do começo normalmente e só entrara em Sleep novamente, quando chegar a respectiva linha do comando para dormir.
Fechamento
Faremos alguns cálculos de autonomia com Sleep.
Após testar este projeto, você pode medir o consumo da corrente no MCU utilizando um multímetro ou algo similar. Usarei um Osciloscópio para medir a tensão em cima de um resistor de 1 Ω, isso significa que os valores lidos da tensão pelo osciloscópio, serão a mesma que a corrente.
Para entender o gráfico do osciloscópio de uma maneira simples, primeiro veja que a escala vertical esta com 20mV por divisão, isto significa que a cada divisão vertical, corresponde a 20mV!
Fig 1 - Escala vertical em 20mV.
Fig 2 - Explicação do gráfico.
Fig 3 - Corrente em modo STA.
Como podemos ver, a corrente (FIG 3), está aproximadamente em 80mA quando o ESP8266 esta com o RF ligado. Usando Modem Sleep para desligar o RF, este consumo já iria para ~15mA!
Para medir a corrente quando o ESP8266 entra em Deep Sleep, foi necessário a redução da escala vertical, indo para 5mV (FIG 4) por divisão!, a leitura do gráfico é a mesma que o anterior (FIG 5).
Fig 4 - Escala vertical em 5mV.
Fig 5 - Corrente em Deep sleep.
Agora você deve estar se perguntando porque o consumo esta tão alto comparado ao datasheet (20μA). Isto se deve ao fato de que esta placa NodeMCU conta com diversos componentes, como por exemplo regulador de tensão e o conversor FTDI. Estes componentes "roubam" uma preciosa energia quando é ativado o Deep Sleep. Por este motivo, você não deve usar o NodeMCU para projetos portáteis, já que o consumo é muito maior. Para isto, use o ESP8266 01, 12, ou qualquer outro que não venha em uma placa (Kit de Desenvolvimento). Ainda sim, usando o ESP 01, há o LED vermelho que indica se o MCU esta ligado, o consumo não será 20μA enquanto não remover este LED!
Usamos ESTA ferramenta para fazer os cálculos, você também pode fazer o calculo de autonomia do seu projeto com ela!
- Bateria 18650: 3,7V e 4000mAh.
- NodeMCU: Duração do código = 2 Segundos por 80mA.
- NodeMCU: Tempo de Sleep = 1 Minuto por 3mA.
Chegamos a conclusão que sem Sleep, o NodeMCU ficaria 40 horas ligado até que a bateria se acabe. Já com o Deep sleep, isso é aumentado para 583 horas (24 dias)!!!
Para comparar o Deep Sleep do teste com o "verdadeiro" Deep sleep de um ESP8266 (20μA), também foi feito o cálculo e chegamos a incríveis 1230 horas, o equivalente a 51 dias!
Dúvidas? Sugestões? Críticas? Comente abaixo!
Comunicação Wireless UDP com ESP (Parte 1)
Comunicação Wireless UDP com ESP
Neste material, iremos aprender a fazer uma comunicação Wireless UDP entre dois ESP8266 para transmissão de informações. O grande diferencial do ESP é sua comunicação Wireless com suporte a WiFi, então nada mais justo que aprender a usar isto. Lembrando que este código também funciona para o ESP32.
[toc]
Protocolo UDP
O protocolo UDP, da camada de transporte, nos permite de forma rápida e descomplicada, o envio de informações através da rede. A simplicidade de usar o UDP é compensada ao fato de não ser uma comunicação orientada à conexão, como por exemplo o TCP, logo, não há garantia que os pacotes sejam recebidos de forma ordenada ou se quer sejam recebidos. Usa-lo para aplicações simples é recomendado, já que não são dados críticos; a perda de pacotes (improvável, porém possa acontecer) não é tão prejudicial ao sistema. Iremos transmitir de um Cliente para um Host.
Esta comunicação simples pode ser feita para transmitir dados até um banco de dados em um computador ou informações para outros Micro controladores. As aplicações são as mais diversas e variadas possíveis, novamente, o limite é sua imaginação.
Lembre-se, serão dois ESP8266, um cliente e outro host. Os dois códigos estarão logo abaixo!
Veja como é rápido o processo de envio e recebimento dos dados. O cliente pisca quando envia o pacote e o host pisca após receber o pacote, é tão rápido que os dois parecem piscar juntos:
Mãos à obra
Componentes necessários
- 2 - ESP8266 (Usaremos dois NodeMCU).
- LEDs Onboard.
Hardware
Acenderemos o LED_BUILTIN do NodeMCU para indicar a transmissão de dados. Este LED OnBoard, está conectado ao pino D4 do NodeMCU.
Código do projeto
Cliente
#include <ESP8266WiFi.h>//Biblioteca do WiFi. #include <WiFiUdp.h>//Biblioteca do UDP. WiFiUDP udp;//Cria um objeto da classe UDP. long x;//Variavel para ser enviada. void setup() { pinMode(D4, OUTPUT);//Habilita o LED onboard como saida. digitalWrite(D4, 1);//Desliga o LED. WiFi.mode(WIFI_STA);//Define o ESP8266 como Station. } void loop() { connect();//Sub-rotina para conectar-se ao host. send();//Sub-rotina para enviar os dados ao host. delay(500);//Aguarda meio segundo. } void connect()//Sub-rotina para verificar a conexao com o host. { if (WiFi.status() != WL_CONNECTED)//Caso nao esteja conectado ao host, ira se conectar. { WiFi.begin("NodeMCU", "");//Conecta à rede do host. delay(2000);//Espera ate que a conexao seja feita. } } void send()//Sub-rotina para enviar dados ao host. { if (WiFi.status() == WL_CONNECTED)//Só ira enviar dados se estiver conectado. { x = random(0, 1000);//Gera um numero aleatorio entre 0 e 1000. udp.beginPacket("192.168.4.1", 555);//Inicializa o pacote de transmissao ao IP e PORTA. udp.println(x);//Adiciona-se o valor ao pacote. udp.endPacket();//Finaliza o pacote e envia. digitalWrite(D4, 0);//- delay(5);//- digitalWrite(D4, 1);//Pisca o led rapidamente apos enviar. } else//Caso nao esteja com uma conexao estabelicida ao host, piscara lentamente. { digitalWrite(D4, 0); delay(250); digitalWrite(D4, 1); } }
Host
#include <ESP8266WiFi.h>//Biblioteca do WiFi. #include <WiFiUdp.h>//Biblioteca do UDP. WiFiUDP udp;//Cria um objeto da classe UDP. String req;//String que armazena os dados recebidos pela rede. void setup() { pinMode(D4, OUTPUT);//Habilita o LED onboard como saida. digitalWrite(D4, 1);//Desliga o LED. Serial.begin(115200);//Habilita a comunicaçao serial para a string recebida ser lida no Serial monitor. WiFi.mode(WIFI_AP);//Define o ESP8266 como Acess Point. WiFi.softAP("NodeMCU", "");//Cria um WiFi de nome "NodeMCU" e sem senha. delay(2000);//Aguarda 2 segundos para completar a criaçao do wifi. udp.begin(555);//Inicializa a recepçao de dados UDP na porta 555 } void loop() { listen();//Sub-rotina para verificar a existencia de pacotes UDP. } void listen()//Sub-rotina que verifica se há pacotes UDP's para serem lidos. { if (udp.parsePacket() > 0)//Se houver pacotes para serem lidos { req = "";//Reseta a string para receber uma nova informaçao while (udp.available() > 0)//Enquanto houver dados para serem lidos { char z = udp.read();//Adiciona o byte lido em uma char req += z;//Adiciona o char à string } //Após todos os dados serem lidos, a String estara pronta. Serial.println(req);//Printa a string recebida no Serial monitor. digitalWrite(D4, 0);//- delay(5);//- digitalWrite(D4, 1);//Pisca o LED rapidamente apos receber a string. } }
Entendendo a fundo
Software
Recomendamos que vocês a leiam esta referência sobre WiFi, praticamente todos comandos disponíveis estão explicados AQUI.
Cliente
-Enviando dados para o destino
udp.beginPacket("192.168.4.1", 555);//Inicializa o pacote de transmissao ao IP e PORTA. udp.println(x);//Adiciona-se o valor ao pacote. udp.endPacket();//Finaliza o pacote e envia.
Nesta parte, usamos 3 funções do UDP, entre elas estão:
-Função WiFiUDP::beginPacket()
udp.beginPacket("192.168.4.1", 555);
Estamos enviando o pacote para o IP "192.168.4.1" que é o IP padrão do host no ESP8266, na porta 555.
-Função WiFiUDP::println()
udp.println(x);
Adicionamos o valor da variável X ao pacote.
-Função WiFiUDP::endPacket()
udp.endPacket();
Por ultimo, fechamos o pacote para finalmente ser enviado ao destino.
Para melhor entendimento, veja esta figura:
- Vermelho = beginPacket();
- Verde = print();
- Azul = endPacket();
Host
-Função WiFiUDP::parsePacket()
udp.parsePacket();
Esta função faz a verificação de novos dados no buffer. Se houver dados novos para serem lidos, a função irá retornar um numero maior que zero.
Desafio
O desafio agora é você fazer uma mensagem de retorno para quem enviou uma mensagem ao host, por exemplo, quando o cliente 1 enviar dados ao host, o host responda "OK". Também faça um Print do IP de quem foi recebido o dado. Na referencia do WiFi (citado acima), há os comandos necessários!
Finalizando
Com a possibilidade de comunicação entre dispositivos pelo WiFi ou Wireless Ponto-a-Ponto, podemos fazer projetos muito legais e redes de dispositivos para se comunicarem. Não se esqueça de ver a parte 2 do material, sobre TCP! Dúvidas? Sugestões? Críticas? Comente abaixo!
Memória não Volátil EEPROM do ESP8266 - NodeMCU
Memória não Volátil EEPROM do ESP8266
EEPROM é um tipo de memória não volátil presente na maioria dos sistemas e micro controladores, já que quase sempre é preciso guardar dados para que sejam lidos mesmo após a uma queda de energia por exemplo. Nesse tutorial você aprenderá a usar essa memória não volátil do ESP8266 usando o NodeMCU
O principal propósito da EEPROM, é guardar as informações (em Bytes) para que possamos ler a qualquer momento, e caso o sistema venha a reiniciar ou algo do tipo, as informações se manterão intactas
[toc]
Sobre a EEPROM
EEPROM, é uma memória não volátil, mas tem um limite relativamente pequeno de gravações (no ESP8266). Isto faz com que devemos tomar cuidado para por exemplo, não colocar as funções de gravação em loop's. Normalmente é utilizada para armazenar dados sobre a inicialização do sistema ou algo relacionado que não seja necessário ser alterado com muita frequência.
O ESP8266 não tem EEPROM dedicada, porém, há uma emulação em um segmento da FLASH de 4B até 4096KB. Cada Byte da EEPROM no ESP8266, tem um limite de 10mil gravações e "infinitas" leituras. Sabendo disto, tome cuidado para não extrapolar nas gravações; a leitura é permitida quantas vezes forem necessárias.
Alguns exemplos práticos para a EEPROM:
- Manter a maior temperatura alcançada de um sensor.
- Guardar variáveis que o usuário inserir após o inicio padrão do sistema também é comumente usado, por exemplo, alocar as novas credenciais do WiFi após o cliente comprar o produto novo.
- Salvar o último dia em que um motor parou de funcionar para gerar relatórios.
As aplicações da EEPROM são as mais diversas e variadas. Pode estar presente na maioria dos projetos já que é facilmente manipulável.
Mãos à obra - Utilizando a EEPROM do NodeMCU
Componentes utilizados
Software
#include <EEPROM.h> void setup() { Serial.begin(9600);//Inicia a comunicação Serial. Serial.println();//- Serial.println();//-Apenas para "limpar" a tela. EEPROM.begin(4);//Inicia a EEPROM com tamanho de 4 Bytes (minimo). Serial.println(EEPROM.read(0));//Mostra no Monitor oque há antes de efetuar a gravação if (EEPROM.read(0) != 18)//Se não existir o numero escolhido (18), irá gravar. Isto é necessário para evitar regravações desnecessárias. { EEPROM.write(0, 18);//Escreve no endereço "0", o valor "18". EEPROM.commit();//Salva o dado na EEPROM. Serial.println(EEPROM.read(0));//Mostra o valor no endereço 0 novamente. } else//Se já existir o valor, irá avisar. { Serial.println("Dado ja cadastrado"); } EEPROM.end();//Fecha a EEPROM. } void loop() { }
Entendendo a fundo
Software
-Função EEPROM::begin()
EEPROM.begin(4);
Necessária sempre que for ler ou escrever na EEPROM. O parâmetro é o tamanho de inicialização, que precisa estar entre 4 até 4096. Neste caso, foi iniciado o mínimo possível, 4 Bytes.
-Função EEPROM::read()
EEPROM.read(0);
Faz a leitura do endereço desejado, retornando um valor UINT8 (0 até 255). No caso do exemplo do tutorial, usamos o primeiro endereço da EEPROM, que é "0". Você pode escolher qualquer endereço desde que esteja entre o parâmetro usado no begin().
-Função EEPROM::write()
EEPROM.write(0, 18);
Escreve no endereço X, o valor Y. No caso do exemplo, escrevemos no endereço "0", um número qualquer, "18". Esta escrita deve ser feita em UINT8 (0 até 255), caso seja necessário valores maiores, precisara usar mais Bytes da EEPROM.
-Função EEPROM:commit()
EEPROM.commit();
Esta função salva o que escrevemos anteriormente, sem isto, não irá salvar! Também pode ser feito pelo comando EEPROM.end(), que também efetua o commit().
-Função EEPROM::end()
EEPROM.end();
Fecha a EEPROM. Lembre-se que após usar esta função, não é possível escrever ou ler valores da EEPROM!
Curiosidades
Ao efetuar um teste que mostra o valor de cada Byte da EEPROM, os 4 primeiros Bytes do meu ESP8266 já estavam com valores modificados. Penso que tenha sido alguma biblioteca externa ou ?.... Teste você mesmo e diga nos comentários se também havia algo alterado!
Código para efetuar a leitura completa da EEPROM:
#include <EEPROM.h> void setup() { Serial.begin(9600); Serial.println(); Serial.println(); EEPROM.begin(4096);//Inicia toda a EEPROM. for (int i = 0; i < 4097; i++)//Loop que irá mostrar no Serial monitor cada valor da EEPROM. { Serial.print(EEPROM.read(i)); Serial.print(" "); } EEPROM.end();//Fecha a EEPROM. } void loop() { }
Desafio
O desafio desta vez, é maximizar a eficiência da EEPROM, salvando dados de um sensor apenas quando for maior que o anterior. Assim, estendendo a vida útil dela.
Fechamento
Você aprendeu a usar a EEPROM de micro controladores de um jeito muito fácil. Agora, podemos salvar dados e mante-los mesmo caso a alimentação seja cortada, ou o MCU seja reiniciado. Dúvidas? Sugestões? Críticas? Comente abaixo!
Servidor WEB com ESP - NodeMCU
Servidor WEB com NodeMcu - ESP
Vamos aprender à criar um Servidor WEB usando HTML e TCP/IP em nosso pequeno ESP8266 ou ESP32. Para essa experiência usaremos o NodeMcu, mas daremos as instruções para você fazer o mesmo projeto com o ESP32. Um servidor web é, como o nome sugere, um servidor de informações que serão fornecidas pelo MCU através da internet ou até LAN. Podemos acessar estes dados em computadores, celulares ou outros MCU's, e também enviar informações e instruções para o MCU.
Aplicação prática
Acionar LEDs, motores, luzes, ventiladores, etc. Você terá uma interface HMI (Interface Homem-Máquina) e com isso, conseguirá manipular seu sistema das mais diversas formas. Ver status de funcionamento de sensores ou atuadores, as possibilidades são muitas, depende de você. Mostraremos apenas o básico, o controle de um LED por botão, porém, após você entender o funcionamento deste sistema, conseguira fazer muitas coisas!
Para este projeto, você verá o básico necessário para implementar com sucesso um acionamento (transmissão de dados SITE->MCU).
TCP
O protocolo TCP/IP (Transmission Control Protocol) é um protocolo para transmissão orientado à conexão, ou seja, permite que as maquinas se comuniquem e gerenciem o estado atual da transmissão.
Uma característica muito importante sobre o TCP é seu gerenciamento do status da rede e os dados, com isto, podemos saber se o dado enviado foi realmente entregue ao destinatário, também garante a entrega ordenada das informações sem que haja colisões e perdas imperceptíveis.
De um jeito mais fácil, TCP será nosso “Caminhão”, que irá levar as informações até o navegador de quem acessar nosso IP.
HTML
HTML é uma linguagem de marcação utilizada em sites da WEB e são interpretadas pelos navegadores (http request). Quando o usuário se conectar ao IP do ESP pelo navegador, o mesmo irá enviar os dados no formato do HTML via TCP e com isso, após o navegador receber os dados, irá mostrar a página web!
Clique aqui para ver mais Informações sobre HTML
Mãos à obra
Componentes necessários
- 1 - ESP8266 (Usaremos o NodeMCU).
- LED OnBoard
Hardware
Vamos acender o LED_BUILTIN do NodeMCU, este LED OnBoard, está conectado ao pino D4 do NodeMCU.
Código do projeto
Não se esqueça de colocar suas credenciais do WiFi na linha 14 para o funcionamento do código!
#include <ESP8266WiFi.h>//Biblioteca que gerencia o WiFi. #include <WiFiServer.h>//Biblioteca que gerencia o uso do TCP. WiFiServer servidor(80);//Cria um objeto "servidor" na porta 80 (http). WiFiClient cliente;//Cria um objeto "cliente". String html;//String que armazena o corpo do site. void setup() { Serial.begin(9600);//Inicia comunicaçao Serial. WiFi.mode(WIFI_STA);//Habilita o modo STATION. WiFi.begin("SUA REDE", "SUA SENHA");//Conecta no WiFi (COLOQUE O NOME E SENHA DA SUA REDE!). Serial.println(WiFi.localIP());//Printa o IP que foi consebido ao ESP8266 (este ip que voce ira acessar). servidor.begin();//Inicia o Servidor. pinMode(D4, OUTPUT);//Define o LED_BUILTIN como Saida. } void loop() { http();//Sub rotina para verificaçao de clientes conectados. } void http()//Sub rotina que verifica novos clientes e se sim, envia o HTML. { cliente = servidor.available();//Diz ao cliente que há um servidor disponivel. if (cliente == true)//Se houver clientes conectados, ira enviar o HTML. { String req = cliente.readStringUntil('\r');//Faz a leitura do Cliente. Serial.println(req);//Printa o pedido no Serial monitor. if (req.indexOf("/LED") > -1)//Caso o pedido houver led, inverter o seu estado. { digitalWrite(D4, !digitalRead(D4));//Inverte o estado do led. } html = "";//Reseta a string. html += "HTTP/1.1 Content-Type: text/html\n\n";//Identificaçao do HTML. html += "<!DOCTYPE html><html><head><title>ESP8266 WEB</title>";//Identificaçao e Titulo. html += "<meta name='viewport' content='user-scalable=no'>";//Desabilita o Zoom. html += "<style>h1{font-size:2vw;color:black;}</style></head>";//Cria uma nova fonte de tamanho e cor X. html += "<body bgcolor='ffffff'><center><h1>";//Cor do Background //Estas linhas acima sao parte essencial do codigo, só altere se souber o que esta fazendo! html += "<form action='/LED' method='get'>";//Cria um botao GET para o link /LED html += "<input type='submit' value='LED' id='frm1_submit'/></form>"; html += "</h1></center></body></html>";//Termino e fechamento de TAG`s do HTML. Nao altere nada sem saber! cliente.print(html);//Finalmente, enviamos o HTML para o cliente. cliente.stop();//Encerra a conexao. } }
Entendendo a fundo
Software
-Função WiFiServer::available()
cliente = servidor.available();
Aqui, estamos dizendo ao cliente que há um servidor disponível para conexão.
-Detectando clientes conectados
if (cliente == true){}
Com esta condicional, é verificado a existência de clientes conectados no ESP, e se sim, enviará o HTML para o cliente.
-Enviando a estrutura do HTML
cliente.print(html);
Após a criação da estrutura do HTML, precisamos enviar para o cliente. É feito com um simples print().
-Fechando conexão
cliente.stop();
Após o envio do HTML, encerramos a conexão pois não é necessário se manter conectado.
Foi usado um botão do tipo SUBMIT para fazer uma requisição GET ao Host, para entender melhor como funcionam os botoes no HTML, veja ESTE tutorial.
Fechamento
Com a possibilidade de receber e enviar dados pela internet, nossos horizontes ficam bem amplos. Podemos tanto controlar o MCU para por exemplo acionar o portão da garagem, ou descobrir se esta chovendo com sensores e etc. Dúvidas? Sugestões? Críticas? Comente abaixo!