O que é Raspberry Pi?
Raspberry Pi - O que é e como funciona?
O Raspberry Pi é uma placa revolucionária! Em uma placa, do tamanho de um cartão de credito, você tem um computador poderoso e de baixo custo. Mesmo sendo pequeno, este microcomputador é capaz de fazer a maior parte das coisas que o seu computador faz, como folhas de cálculo, processamento de texto e jogos. Também é capaz de reproduzir vídeo em alta definição. Além disso, pode funcionar com várias distribuições de Linux e está sendo utilizado para ensinar crianças de todo o mundo a programar.
[toc]
Um pouco de história
A ideia do Raspberry PI surgiu, com professores buscando uma forma de ensinar programação a jovens.
Em meados de 2005, esses professores notaram que o domínio sobre computadores dos novos alunos do curso de ciência da computação na universidade de Cambridge, na Inglaterra, tinha mudado muito em relação as turmas da década de 1990.
Os alunos, que antes chegavam com bom domínio de diversas linguagens de programação e com bastante conhecimento de hardware, agora chegavam com pouca bagagem.
Dessa forma, Eben Upton teve a ideia de desenvolver um computador que fosse uma plataforma educacional. Além disso ele seria de baixo custo e de fácil manuseio. Com isso, a universidade poderia dar uma placa para cada aluno ingressante para que adquirissem os conhecimentos fundamentais para o curso. (Quem me dera se fosse assim na minha faculdade!! hehehe)
Raspberry PI Foundation
Foi então que Upton e seus colegas perceberam que o projeto do Raspberry Pi tinha um potencial. Visto que ele poderia ser difundido por todo mundo. E assim, surgiu a Raspberry Pi Foundation, sediada no Reino Unido.
Essa fundação, criada por Eben Upton e alguns professores, se tornou desenvolvedora e detentora da tecnologia do Raspberry PI. Essa fundação é responsável por desenvolver os projetos das placas de Raspberry.
A fabricação das placas fica por conta de empresas parceiras que seguem os padrões instituídos pela Fundação. Tal como o preço e qualidade do hardware.
A Raspberry Pi Foundation transformou o pequeno computador de uma ferramenta usada apenas em sua universidade natal, para ser uma incrível plataforma educacional de baixo custo usada em todo o mundo.
Seu objetivo é disponibilizar para qualquer pessoa no mundo a possibilidade de aprender a programar e validar protótipos, tanto para uso comercial quanto educacional.
Aplicações do Raspberry PI
Portanto, o Raspberry pode ser considerado um minicomputador. Essa placa possui uma capacidade de processamento maior que do Arduino - o Raspberry utiliza arquitetura CISC ( Complex Instruction Set Computer ou Computador com um Conjunto Complexo de Instruções ).
Com um tamanho semelhante a de um cartão de crédito, esta placa pode ser utilizada tanto para aplicações simples (como acender lâmpadas remotamente) quanto para reconhecimento facial ou de objetos.
Principais Modelos Raspberry Pi lançados
Desde o lançamento da primeira placa, a instituição vem atualizando o hardware. Abaixo, apresento os modelos de placas já lançadas:
2012 | Raspberry Pi 1 Model B |
2014 | Raspberry Pi 1 Model A+ |
2015 | Raspberry Pi 2 Model B |
2015 | Raspberry Pi Zero |
2016 | Raspberry Pi 3 Model B |
2017 | Raspberry Pi Zero W |
2018 | Raspberry Pi 3 Model B+ |
2019 | Raspberry Pi 4 Model B |
Funcionalidades da Raspberry Pi 4 B
A mais recente e popular delas é o Raspberry Pi 4 B. Ela é surpreendente. Vemos abaixo as funcionalidades:
- Processador ( Broadcom BCM2711, Quad Core Cortex-A72 (ARM v8) SoC de 64 bits a 1,5 GHz )
- Memória ram de 1GB, 2GB ou 4GB (dependendo do modelo)
- Porta Gigabit Ethernet
- Wifi de 2,4GHz e 5GHz
- Bluetooth 5.0 BLE
- 2 portas USB de 2.0
- 2 portas USB de 3.0
- GPIO 40 pinos (input/output)
- 2 portas micro HDMI (suporta resolução 4Kp60 )
- Porta de exibição MIPI DSI de 2 pistas
- Porta da câmera MIPI CSI de 2 pistas
- Porta de áudio estéreo de 4 pólos e vídeo composto
- H.265 (decodificação 4kp60), H264 (decodificação 1080p60, codificação 1080p30)
- Gráficos do OpenGL ES 3.0
- Slot para cartão Micro-SD para carregar sistema operacional e armazenamento de dados
- 5V DC via conector USB-C (mínimo 3A)
- 5V DC via conector GPIO (mínimo 3A)
- Power over Ethernet (PoE) ativado (requer PoE HAT separado)
- Temperatura de operação: 0 - 50 graus C ambiente.
Então o Raspberry Pi precisa de um sistema operacional?
Sim. Como essa placa é semelhante a um computador, precisamos então de um sistema operacional. O mais utilizado é o Raspbian (baseado no Debian). Também pode-se utilizar o Windows 10 IoT. Lembrando que deve-se utilizar um cartão de memória para a instalação da ISO, já que o Raspberry não possui HD físico instalado em sua placa.
Todos os S.Os. estão disponíveis para a instalação no site oficial do Raspberry ( https://www.raspberrypi.org/downloads/ ).
Projetos com Raspberry Pi:
- Doorjam ( https://ideas.redpepper.land/doorjam-47f1a5bce2fd )
- Espelho mágico ( https://michaelteeuw.nl/post/84026273526/and-there-it-is-the-end-result-of-the-magic )
- Porta automática com reconhecimento facial ( https://www.hackster.io/windows-iot/windows-iot-facial-recognition-door-e087ce )
Resumo
Bom, então podemos concluir que o Raspberry Pi é uma placa eletrônica com capacidade semelhante à de um computador.
Suas funcionalidades permitem a criação de protótipos simples (como um controle de iluminação) quanto de aplicações mais sofisticadas (reconhecimento facial e de objetos).
E aí, gostou do artigo? Qual é a sua opinião sobre a placa Raspberry?
Banco de dados com Google planilhas com ESP32 / ESP8266
Banco de dados com Google planilhas - ESP
O Google planilhas é um "Excel online", que te permite criar tabelas e coisas do tipo, online, sem a necessidade de instalar no seu computador. Podemos compartilhar essa tabela para outras pessoas visualizarem ou edita-las. Nesse tutorial aprenderemos como usar o Google Planilhas para criar um banco de dados online, gratuito e simples, visto que não precisamos ter um servidor dedicado à hospedar o serviço. Esta primeira parte será ensinado apenas a enviar os dados usando um ESP.
[toc]
Banco de dados
Banco de dados é um conjunto de dados, normalmente relacionados entre si, como por exemplo: dados de clientes, LOG de temperaturas e coisas similares. Normalmente são dados organizados por colunas e linhas (matriz/tabela) para fácil entendimento por nós.
Poderíamos usar MySQL ou Firebase, que nos permite criar banco de dados de forma eficiente e confiável, entretanto, é preciso ter um servidor apenas para hospedar seu banco de dados sempre disponível.
Você pode ler mais sobre Banco de dados e o uso do MySQL no tutorial: Arduino e MySQL – Registrando temperatura em um banco de dados usando o Shield Ethernet W5100
O Google planilhas oferece uma solução simples e gratuita para o armazenamento dos dados coletados. Podemos criar essas tabelas em conjunto do Google Forms, para enviar os dados dos nossos sensores, clientes e etc., sem a necessidade de um computador ou servidor pago hospedando o banco de dados, já que a Google se encarrega totalmente do serviço.
Obtendo os recursos necessários
Para usar esse incrível recurso precisaremos de uma conta no Google, e com ela criaremos dois arquivos, um de Planilha e outro Form.
Iremos através do formulário, enviar dados para a planilha (os dados do formulário irão para a planilha).
Passo 1-) Vá ao seu Google Drive e crie uma Planilha.
Passo 2-) Altere o nome da sua planilha para ser de fácil identificação nos próximos passos.
Passo 3-) Volte no Drive e crie um formulário.
Passo 4-) Altere o titulo do seu formulário para o desejado, e configure as perguntas.
Na planilha, os títulos das perguntas serão as colunas, e as respostas serão as linhas. Usaremos a opção "Resposta curta", que permite adicionar números e textos pequenos.
Passo 5-) Vá em "Respostas", vamos atribuir o formulário à planilha criada anteriormente. Clique nas "três bolinhas", e "Selecionar destino da resposta".
Passo 6-) Selecione a planilha desejada e estará pronto para receber nossos dados.
Agora, nosso formulário esta pronto para receber os dados e automaticamente transmitir para a planilha.
Para testar o formulário, clique no "Olho" ao canto superior direito, para abrir o link do formulário.
Após digitar o numero e clicar em "Enviar", será mostrado o aviso que a resposta foi registrada.
Agora, volte à sua Planilha, e veja que os resultados já estão aparecendo!
A coluna "Carimbo de data/hora" é preenchida automaticamente pelo sistema do Google, poupando imenso trabalho e requisitos do nosso sistema, dispensando até mesmo RTCs. A outra coluna "Numero" é o titulo da nossa pergunta, e a linha é a resposta que inseri.
Agora que aprendemos a utilizar o formulário em conjunto com a planilha, precisamos apenas integrar no Microcontrolador.
Mãos à obra
Componentes necessários
- 1x ESP8266 ou ESP32 (Usaremos o NodeMCU 8266).
Conheça um pouco mais sobre ESP:
Código do projeto
Atenção: Não copie e cole o código inteiro, precisamos fazer algumas alterações no link utilizado. Será explicado logo abaixo em "Entendendo a fundo".
Caso esteja usando o ESP32, altere as bibliotecas removendo a ESP8266WiFi.h e incluindo as bibliotecas WiFi.h e WiFiClientSecure.h
Alguns usuário relatam erro com as versões mais novas do core esp8266 (quando você instala pelo menu (ferramentas > placa > gerenciar placas). A solução é instalar e usar a versão 2.4.0
// Código Banco de dados com Google planilhas com ESP - Vida de Silício #include <ESP8266WiFi.h> // Alterar a linha anterior por #include <WiFi.h> se estiver usando ESP32 // #include <WiFiClientSecure.h> // Incluir esta biblioteca se estiver usando ESP32 WiFiClientSecure client;//Cria um cliente seguro (para ter acesso ao HTTPS) String textFix = "GET /forms/d/e/1FAIpQLSdm6M_0mTVx_LKHLB1J3u_hjaag_hBtMfDHQlTIKe0EoatfsQ/formResponse?ifq&entry.717212213="; //Essa String sera uma auxiliar contendo o link utilizado pelo GET, para nao precisar ficar re-escrevendo toda hora void setup() { Serial.begin(115200);//Inicia a comunicacao serial WiFi.mode(WIFI_STA);//Habilita o modo estaçao WiFi.begin("SUA REDE", "SUA SENHA");//Conecta na rede delay(2000);//Espera um tempo para se conectar no WiFi } void loop() { if (client.connect("docs.google.com", 443) == 1)//Tenta se conectar ao servidor do Google docs na porta 443 (HTTPS) { String toSend = textFix;//Atribuimos a String auxiliar na nova String que sera enviada toSend += random(0, 501);//Adicionamos um valor aleatorio toSend += "&submit=Submit HTTP/1.1";//Completamos o metodo GET para nosso formulario. client.println(toSend);//Enviamos o GET ao servidor- client.println("Host: docs.google.com");//- client.println();//- client.stop();//Encerramos a conexao com o servidor Serial.println("Dados enviados.");//Mostra no monitor que foi enviado } else { Serial.println("Erro ao se conectar");//Se nao for possivel conectar no servidor, ira avisar no monitor. } delay(5000); }
Colocando para funcionar
Após a editar o código com as suas informações, tudo irá funcionar corretamente. Veja como ficou o nosso, enviando valores aleatórios para nossa planilha a cada ~5 Segundos.
Entendendo a fundo
Precisamos fazer algumas alterações para o funcionamento do sistema com sua planilha. Sem isso, você irá enviar dados para nossa planilha de teste! (hehe)
Passo 1-) Abra seu formulário (Figura 7).
Passo 2-) Copie todo o link entre "docs.google.com" e "/viewform". Salve isso em algum lugar, já iremos utilizar.
O nosso ficou "/forms/d/e/1FAIpQLSdm6M_0mTVx_LKHLB1J3u_hjaag_hBtMfDHQlTIKe0EoatfsQ".
Passo 3-) Clique com o direito no "Input Text Box" e "inspecionar elemento".
Passo 4-) Agora, iremos pegar o nome desse Input Text Box.
O nosso é "entry.717212213".
Agora, devemos alterar esses dois valores no código, pois são os valores da sua planilha, e no código demonstrado de exemplo, foi utilizado nossos dados.
Obs: Altere apenas as partes destacadas, o restante é necessário para o correto funcionamento.
Atualização por contribuição do leitor Anselmo:
Caso tenha dificuldade em encontrar os entry, bastar seguir os seguintes passos:
-
- Clique no formulário com o botão direito do mouse e selecione "Exibir código fonte da pagina" (Ctrl+U);
- Agora pesquise pelo nome do campo inserido no formulário usando a ferramenta de pesquisa do navegador (Ctrl+F);
- No final do código vai encontra algo parecido com: FB_PUBLIC_LOAD_DATA_ = [null,[null,[[490158642,"nome do campo",null,0,[[12345678,null,0,null,[[1,9,[""];
- O entry vai ser o numero após o colchete “12345678”,
- Inclua "entry." antes do número, fincando “entry.12345678”;
- Se você tiver outros campos, os outros entry do formulário vão estar na sequencia.
Exemplo: Campo do formulário: Teste var 1
-
- Procure por “Teste var” (Ctrl+F);
- No final do código vai encontra algo parecido com: "teste var 1",null,0,[[278629525,null,0,null,[[1,9,[""]
- Copie o número após o colchete “278629525”
- basta agora incluir "entry." antes do número , ficando “entry.278629525”
Passo 5-) Vá no começo do código e altere esta parte destacada, pelo que você copiou no item 2.
Esta parte é o "ID/KEY" do seu formulário, cada formulário tem o seu.
Passo 6-) Nessa mesma parte do código, altere essa outra parte destacada, pelo valor copiado no item 4.
Se você tiver mais de uma entrada para dados, a String ficaria por exemplo:
"GET /forms/d/e/1FAIpQLSdm6M_0mTVx_LKHLB1J3u_hjaag_hBtMfDHQlTIKe0EoatfsQ/formResponse?ifq&entry.717212213=123&entry.312212717=1234"
Os dados em negrito são os dados que você adicionaria, sendo de sensores, temperatura e etc.
Se você quiser testar com nossa planilha, sinta-se livre. Entretanto, é permitido apenas a visualização. Link da nossa planilha.
Software
- String auxiliar
String textFix = "GET /forms/d/e/1FAIpQLSdm6M_0mTVx_LKHLB1J3u_hjaag_hBtMfDHQlTIKe0EoatfsQ/formResponse?ifq&entry.717212213=";
Essa String textFix é uma auxiliar para nao precisar ficar reescrevendo toda hora, desde que essa parte é FIXA. O único valor que iremos alterar é após o igual "=", que será o valor enviado à planilha.
- Função WiFiClient::connect()
if (client.connect("docs.google.com", 443) == 1)
Precisamos antes de enviar o método GET, se conectar no servidor. Essa função se conecta à URL (IP), na porta desejada.
- Corpo restante do GET
String toSend = textFix;//Atribuimos a String auxiliar na nova String que sera enviada toSend += random(0, 501);//Adicionamos um valor aleatorio toSend += "&submit=Submit HTTP/1.1";//Completamos o metodo GET para nosso formulario. client.println(toSend);//Enviamos o GET ao servidor- client.println("Host: docs.google.com");//- client.println();//- client.stop();//Encerramos a conexao com o servidor Serial.println("Dados enviados.");//Mostra no monitor que foi enviado
Após a conexão com o servidor, adicionamos um valor aleatório na String final à ser enviada, e também terminamos o restante do necessário a ser enviado.
Desafio
Foi demonstrado apenas o envio de uma variável para a planilha, entretanto em qualquer projeto pode ser necessário o envio de diversas. Faça as alterações necessárias, adicionando os novos "Input Text Box" e tente enviar varias variáveis para sua planilha!
Fechamento
Em diversos projetos precisamos enviar dados ou guarda-los para analise, e um banco de dados como SQL pode ser desnecessário, uma vez que precisamos de um servidor para hospedar o banco de dados; com este método é possível facilmente criar seu banco de dados online, compartilhar com amigos e etc.
Na parte 1 foi mostrado apenas o procedimento para envio dos dados, entretanto, podemos precisar pegar valores da tabela para uso. Já a parte 2, você aprenderá como ler os valores da planilha para manipulação de dados ou até criar comandos de controle para o MCU: Lendo dados do Google planilhas com ESP – Banco de dados
Referências
- https://developers.google.com/sheets/api/guides/values
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!
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!
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!
Software Timer - ESP8266
Software Timer
Em várias situações, é necessário de certa forma, a manipulação do tempo em micro controladores. O jeito mais fácil é pelas funções básicas (delay e derivados), porém, normalmente, estas funções travam o micro controlador, e com isto, você é incapaz de ler botões ou algo do tipo enquanto o delay não acabar. Isto além de gerar terríveis problemas nos mais variados projetos, não é uma pratica saudável. Neste tutorial, vamos aprender sobre o OS_TIMER do ESP8266, este timer é baseado no software do ESP8266 e o limite inferior é 1mS e máximo de ~2 horas. Este software timer não é aconselhado para projetos em que o tempo é crítico. Apesar de nossos testes darem certa confiança, por ele ser baseado em software, alguns fatores podem atrasa-lo em alguns mS, tome cuidado.
Demonstrando a diferença
Neste exemplo apenas para comparação do Software Timer, usaremos um exemplo que acende 3 LEDs a cada 1 segundo e enquanto isso, ficaremos enviando dados na Serial para mostrar o funcionamento do código. Antes de ir para o software timer, testem este código abaixo no ESP8266 e veja no Serial Monitor como é o recebimento de informações.
Neste código, estamos usando Delay para fazer o acionamento simples dos LEDs. Você perceberá que só irá aparecer mensagens a cada 4 Segundos.
long x;//Variavel para mostrar o desenvolvimento do codigo no Serial Monitor. void setup() { pinMode(D1, OUTPUT);//Define D1 como Saida. pinMode(D2, OUTPUT);//Define D2 como Saida. pinMode(D3, OUTPUT);//Define D3 como Saida. Serial.begin(9600);//Inicia a comunicaçao Serial para provar que o codigo nao trava. } void loop() { led();//Sub rotina para acender os LED`s. Serial.println(x++);//Mostra no serial monitor o desenvolvimento do codigo. } void led()//Sub rotina para acender os LED`s. { digitalWrite(D1, 1);//Acende o led 1. delay(1000);//Aguarda 1 segundo. digitalWrite(D2, 1);//Acende o led 2. delay(1000);//Aguarda 1 segundo. digitalWrite(D3, 1);//Acende o led 3. delay(1000);//Aguarda 1 segundo. digitalWrite(D1, 0);//- digitalWrite(D2, 0);//- digitalWrite(D3, 0);//-Apaga os 3 leds. delay(1000);//Aguarda 1 segundo. }
Após ver que o ESP só pula para a linha debaixo da função led() a cada 4 segundos, percebe-se que o ESP fica travado durante 4 segundos apenas para acender os LEDs, inutilizando totalmente o seu uso para outras coisas.
Agora chega de papo e vamos ao Software Timer.
Normalmente, na maioria dos casos, as funções de delay travam o código até que o delay se acabe. Ao usar delay(60000), o micro controlador ficará travado por 1 Minuto nesta linha até que o tempo acabe e não fara mais nada. Se desejarmos acender um LED a cada 30 segundos, isto irá gerar muitos problemas usando delay, então, usaremos os Timer’s. O Timer gera uma interrupção no sistema a cada intervalo de tempo e voltara a fazer a sua rotina padrão após terminar suas instruções.
Lembre-se, A rotina de um timer (Interrupção) não pode conter comandos de Delay, Serial e vários outros. A rotina do ISR deve ser a mais breve possível e normalmente usamos flag’s armazenadas na RAM para agilizar o processo e evitar erros internos.
Mãos à obra
Componentes necessários
- 1 – ESP8266 (Usaremos o NodeMCU).
- 3 – LED's.
- 3 - Resistores de 220 Ω.
- Fios Jumpers.
Montando o projeto
Veja como ficou nossa montagem:
Código do projeto
#include <user_interface.h>;//Biblioteca necessaria para acessar os Timer`s. os_timer_t tmr0;//Cria o Timer. Maximo de 7 Timer's. volatile byte status;//Variavel armazenada na RAM para Status do LED. long x;//Variavel para mostrar o funcionamento do Codigo. void setup() { os_timer_setfn(&tmr0, led, NULL); //Indica ao Timer qual sera sua Sub rotina. os_timer_arm(&tmr0, 1000, true); //Inidica ao Timer seu Tempo em mS e se sera repetido ou apenas uma vez (loop = true) //Neste caso, queremos que o processo seja repetido, entao usaremos TRUE. pinMode(D1, OUTPUT);//Define D1 como Saida. pinMode(D2, OUTPUT);//Define D2 como Saida. pinMode(D3, OUTPUT);//Define D3 como Saida. Serial.begin(9600);//Inicia a comunicaçao Serial. } void loop() { leitura();//Sub rotina para processar os LED`s. //O codigo irá funcionar normalmente sem que haja delays e acendendo os LED`s no intervalo definido. //Para demonstraçao, abra o Serial monitor e voce vera que o codigo continua normalmente. Serial.println(x++);//Print para provar que o codigo nao trava. Abra o Serial monitor e veja //que o codigo continua rodando enquanto os LED`s piscam a cada 1 Segundo. } void leitura()//Sub rotina para processar os LED`s. { switch (status) { case(1)://Caso status seja 1, acenda o led 1. digitalWrite(D1, 1); break; case(2)://Caso status seja 2, acenda o led 2. digitalWrite(D2, 1); break; case(3)://Caso status seja 3, acenda o led 3. digitalWrite(D3, 1); break; case(4)://Caso status seja 4, Apague os 3 LED`s. digitalWrite(D1, 0); digitalWrite(D2, 0); digitalWrite(D3, 0); break; } } void led(void*z)//Sub rotina ISR do Timer sera acessada a cada 1 Segundo e mudara o status do LED. { if (status == 4)//Verifica se o maximo foi alcançado para resetar a contagem. { status = 0; } status++; }
Entendendo a fundo
Hardware
As ligações são simples, apenas sendo necessário ligar o pino de cada LED em sua correspondente porta, não esquecendo o uso de resistores para limitar a corrente/tensão e também não queimar o LED. O outro pino do LED no GND. Este é o básico para um LED funcionar.
Software
-Função os_timer_setfn()
os_timer_setfn(&tmr0, led, NULL);
Esta função atribui uma função sua à rotina do Timer. Neste caso, definimos a nossa função led() ao timer tmr0, que criamos anteriormente.
-Função os_timer_arm()
os_timer_arm(&tmr0, 1000, true);
Com esta outra, é definido o tempo do timer e também se irá se repetir (loop). Neste caso, definimos ao timer tmr0, que entre na função anteriormente atribuída, a cada 1000mS. Se você não precisa que isso seja repetido, troque true por false, desativando o loop.
Finalizando
Comparando os dois códigos, podemos perceber claramente a diferença entre fazer tarefas com um Timer ou Delay. Enquanto o primeiro código só mostra a mensagem a cada 4 Segundos, o segundo mostra a mensagem diversas vezes ao mesmo tempo que gerencia os LEDs. Você pode usar isso em vários projetos em que é preciso fazer tarefas em tempos definidos, sem travar o resto do sistema com Delay. Dúvidas? Sugestões? Críticas? Comente abaixo!
Segurança de dados com AES
Segurança de dados
A segurança é algo essêncial em muitos projetos, principalmente nos conectados à Internet. Desde esconder senhas ou mensagens para que ninguém além do destino possa ler, a segurança faz parte do nosso cotidiano e iremos aprender a implementa-la nos Microcontroladores. Aprenderemos usar a criptografia AES (Advanced Encryption Standard) com foco em apenas sobre sigilo do dado, o download dela estará ao fim do tutorial. Esta biblioteca para criptografia com AES, funciona tanto para Arduino, quanto para ESP8266 ou ESP32.
Um pouco sobre segurança
Antes de entrar em detalhes sobre o AES, um resumo sobre a segurança de dados.
-Codificação
A codificação é possivelmente o método mais simples e antigo, trata-se da troca de uma linguagem, para outro padrão. É necessário conhecer os caracteres codificados para poder decodificar. O objetivo da codificação não é tornar a mensagem secreta. Exemplo: Morse(Fig 1), que converte os caracteres para pulsos elétricos, sons, luzes, etc.
-Criptografia simétrica
A criptografia simétrica faz o uso de uma chave privada que deve ser mantida em segredo, já que é usada tanto para encriptação, quanto para desencriptação. Esta é mais simples e leve que a criptografia assimétrica. Exemplo: AES, DES.
-Criptografia assimétrica
A criptografia assimétrica faz o uso de duas chaves, uma pública e outra privada. A pública pode ser usada para encriptação e a privada para desencriptação. Esta é mais pesada e lenta. Exemplo: RSA.
O uso delas é bem diferente e logo, a comparação direta não faz sentido. Por exemplo, a assimétrica permite autenticidade dos dados e pode garantir que o dado recebido é de uma pessoa autorizada e não de alguém re-enviando o dado.
-Hash
Hash é um algoritmo de uma via, ou seja, é irreversível. É muito usado com senhas da seguinte forma: Primeiramente é gerado um Hash da senha e este, será apenas comparado ao Hash armazenado no destino. Caso os Hash's sejam iguais, logo a senha é igual. Exemplo: MD5, SHA-1.
Clique AQUI para mais informações sobre Hash.
-AES
AES (Advanced Encryption Standard), é uma criptografia de blocos com chave simétrica (cifra de bloco) e será usado AES-128 no exemplo deste tutorial. AES trabalha com o sistema de blocos de 16 Bytes. É possível utilizar valores de entrada menores sem problemas, mas maiores será necessário dividir em blocos de 16B.
Imagine que você use dois micro controladores para transmissão de mensagens (Exemplo: Whatsapp, Facebook...), muito provavelmente você deseja que ninguém consiga ler as mensagens, isto pode ser feito com a encriptação, que irá cifrar (embaralhar) a mensagem e deixa-la ilegível para qualquer pessoa sem a chave, garantindo que apenas as pessoas com a chave, consigam ler.
Também pode ser usada para protocolos de comunicação entre dispositivos Wireless ou Wired, para preservar a integridade do mesmo e evitar "curiosos de plantão".
Mãos à obra
Código do projeto
#include <AES.h>//Biblioteca do AES. AES aes;//Cria a classe aes. byte key[16], out[16], inp[32];//Cria arrays (vetores) para a chave, input e output de dados. const char pass[] = "abc";//Define a chave usada, neste exemplo usamos AES128, então precisa ser <= 16 Bytes. void setup() { Serial.begin(115200);//Habilita a serial. Serial.println();//Limpa o monitor. enc128("vida de silicio", 1);//Faz a função de encriptação e retorna o HEX encriptado. } void loop() { } void enc128(const char txt[], bool db)//Argumentos: (texto e debug) { if (strlen(pass) > 16)//Verifica se a chave tem o tamanho limite de 16 caracteres. { if (db == true) { Serial.println("Chave para AES128 <= 16 Bytes"); } return;//Se a chave for maior, irá sair da função. } if (strlen(txt) > 16)//Verifica se o texto tem o tamanho limite de 16 caracteres. { if (db == true) { Serial.println("Frase/numero para AES <= 16 Bytes / bloco"); } return;//Se o texto for maior, irá sair da função. } for (byte i = 0; i < strlen(pass); i++)//Adiciona a chave(pass) na array key. { key[i] = pass[i]; } for (byte i = 0; i < strlen(txt); i++)//Adiciona o texto na array input. { inp[i] = txt[i]; } //Adiciona a chave ao algoritimo. if (aes.set_key(key, 16) != 0)//Verifica se a chave esta correta, caso nao, sairá da função. { if (db == true) { Serial.println("Erro ao configurar chave"); } return;//Sai da função } //Faz a encriptação da array INPUT e retorna o HEXA na array OUTPUT. if (aes.encrypt(inp, out) != 0)//Verifica se a encriptação esta correta, se não, sairá da função. { if (db == true) { Serial.println("Erro ao encriptar"); } return;//Sai da função } if (db == true)//Se o debug estiver on (1), irá mostrar o HEXA no serial monitor. { for (byte i = 0; i < 16; i++) { Serial.print(out[i], HEX); Serial.print(" "); } Serial.println(); } aes.clean();//Limpa a chave e residuos sensiveis da encriptação. }
Entendendo a fundo
Software
A função que desenvolvemos enc128() torna o uso muito simples, mas você deve estudar mais sobre o AES e a biblioteca usada para entender melhor o funcionamento. Aqui será mostrado apenas a encriptação, mas também é possível fazer a desencriptação da mesma forma, este será o desafio de vocês para aprendizado.
-Variaveis usadas
byte key[16], out[16], inp[32];
Criamos os vetores (Arrays) para alocar a CHAVE e mensagens de INPUT e OUTPUT do buffer AES.
-Definindo a chave
char pass[] = "abc";
Definimos a Key (chave) da nossa criptografia. Deve ter no mínimo 1 caractere, e no máximo 16 (AES 128). 0 < Key <= 16. Aqui usamos "abc", mas é aconselhado o uso de letras e números aleatórios.
Você deve usar chaves grandes e aleatórias. Sem isso, seu sistema estará em grandes riscos. Usamos uma chave simples para fácil entendimento.
-Função enc128()
enc128("vida de silicio", 1);
enc128(texto, debug);
A função criada para encriptação dos dados torna o processo bem fácil. Os parâmetros necessários para ela é o texto que deseja encriptar, e em seguida, o debug, que mostra no serial monitor possíveis erros e por fim, o HEX da encriptação.
O texto para encriptação deve estar entre aspas e ser menor que 17 caracteres (bytes). 0 < texto <= 16.
O debug é ativado com 1 e desativado com 0, aconselhamos a sempre usar 1 para caso aconteça erros.
-Função AES::set_key()
aes.set_key(key, 16);
Com esta função, é adicionado a nossa chave ao sistema de criptografia interno.
Obs: A chave para AES é 128/192/256b, porém, para ser didático, foi usado apenas 3 caracteres. Tome cuidado ao usar chaves de outros tamanhos, alguns lugares não aceitam!
-Função AES::encrypt()
aes.encrypt(inp, out);
Esta função, faz a encriptação dos dados que estão dentro do vetor INP, e retorna os valores dentro do vetor OUT.
Colocando para funcionar
Ao testar o código que foi mostrado aqui, será gerado exatamente este código em hexadecimal "4A 38 3A 94 FC FB C4 C6 E1 4F D2 5D 34 7B B5 80", este código hexadecimal é a nossa mensagem encriptada. Encontrei um site bem legal que faz a encriptação e desencriptação dos dados AES, usarei ele.
Coloquei a nossa chave "abc" e o código hexadecimal gerado pelo micro controlador. Após clicar para desencriptar, é mostrado a mensagem original, e como podemos ver, funcionou.
o AES permite vários métodos de encriptação, a mais simples é a ECB, a biblioteca usada no tutorial também permite a CBC que é mais segura, porém mais complicada.
Clique AQUI para ir ao site.
Desafio
O desafio para vocês é que façam a desencriptação de um código hex, estudem sobre o assunto e veja as funções da biblioteca! Vocês podem desencriptar o próprio hex gerado da sua encriptação, ou usar o site indicado anteriormente para obter um hex e ver se a desencriptação funciona. Lembrando que esta biblioteca funciona para Arduino, ESP8266 e ESP32.
Download da biblioteca: https://github.com/spaniakos/AES
Fechamento
A segurança é extremamente importante em IoT e nao deve ser esquecida. Sempre adicione caso seja necessário em seu projeto, e principalmente em produtos comerciais. Tem dúvidas? sugestões? críticas? Comente abaixo!
Controlando seu projeto usando Telegram - ESP
Controlando seu projeto com Telegram
Imagine uma automação ou projeto que permite você “conversar” com seu Microcontrolador (MCU) e também receber comandos, parece difícil, mas é bem simples. Aprenderemos a usar o Telegram para criar automações e projetos das mais diversas possibilidades e utilidades que estabelece uma comunicação amigável com o MCU. Para essa experiência usaremos o NodeMCU 8266, mas você pode fazer com outros ESPs, tal como os da linha ESP8266 e o ESP32.
[toc]
O Telegram
Podemos fazer desde simples controles de LEDs, ou até uma automação residencial controlada pelo Telegram, já que os BOTs permitem controle total de informações.
Usaremos o Telegram pois nos permite criar “BOTs”. Estes BOT's, são como robôs virtuais e com eles, conseguimos criar uma interface IHM (Interface Homem-Máquina). Este método, permite o fluxo de informações de ambos sentidos (Input e Output), então conseguimos controlar o sistema e também ser notificado pelo sistema.
Criando seu Bot no Telegram
1-) Pesquise pelo "BotFather" no menu de pesquisa do Telegram, entre nele e clique em "Começar ou Reiniciar".
2-) Pelo BotFater podemos criar novos Bots, configura-los e muito mais. Para criar, faça:
- Digite "/newbot".
- Digite o nome do seu novo Bot.
- Digite o usuário do Bot com a terminação "bot".
3-) Logo após a criação, o BotFater enviará uma mensagem com o link do Bot e logo abaixo o Token do Bot. Você pode clicar neste link para abrir a conversa com seu Bot ou pode pesquisa-lo futuramente.
Você precisa desse Token para inserir no código!
Mãos a obra
Componentes necessários
Para este projeto, usaremos o ESP8266 (versão NodeMCU). Entretanto, pode ser feito igualmente com o ESP32, sendo necessário alguns pequenos ajustes.
- 1x – ESP8266. (Usaremos o NodeMCU).
- 1x – Telegram no Celular.
- 1x - LED. (Usaremos o LED OnBoard da placa).
- Biblioteca utilizada
Clique AQUI para ir a pagina de download da biblioteca "UniversalTelegramBot" utilizada.
Alguns usuários relatam erro com a biblioteca "ArduinoJson". Caso aconteça com você, será necessário instalar a biblioteca na Arduino IDE.
Para isso vá em "Gerenciador de bibliotecas", procure pela biblioteca "ArduinoJson", instale-a e reinicie a Arduino IDE.
- Código do projeto
Não se esqueça de alterar as credenciais do WiFi e também o Token do seu Bot. Sem isso não irá funcionar.
Vários usuários relatam erro com a versão 2.5 do esp8266 (core) instalado na Arduino IDE, que é resolvido instalando a 2.4.0.
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> #define BOTtoken "135924:AAErDKEJaQpEnqs_xj35asdGQ5kK6dQet4"//Define o Token do *seu* BOT WiFiClientSecure client; UniversalTelegramBot bot(BOTtoken, client); String id, text;//Váriaveis para armazenamento do ID e TEXTO gerado pelo Usuario unsigned long tempo; void setup() { pinMode(D4, OUTPUT);//LED conectado à saida WiFi.mode(WIFI_STA);//Define o WiFi como Estaçao connect();//Funçao para Conectar ao WiFi } void loop() { if (millis() - tempo > 2000)//Faz a verificaçao das funçoes a cada 2 Segundos { connect();//Funçao para verificar se ainda há conexao readTel();//Funçao para ler o telegram tempo = millis();//Reseta o tempo } } void connect()//Funçao para Conectar ao wifi e verificar à conexao. { if (WiFi.status() != WL_CONNECTED)//Caso nao esteja conectado ao WiFi, Ira conectarse { WiFi.begin("SUA REDE", "SUA SENHA");//Insira suas informaçoes da rede delay(2000); } } void readTel()//Funçao que faz a leitura do Telegram. { int newmsg = bot.getUpdates(bot.last_message_received + 1); for (int i = 0; i < newmsg; i++)//Caso haja X mensagens novas, fara este loop X Vezes. { id = bot.messages[i].chat_id;//Armazenara o ID do Usuario à Váriavel. text = bot.messages[i].text;//Armazenara o TEXTO do Usuario à Váriavel. text.toUpperCase();//Converte a STRING_TEXT inteiramente em Maiuscúla. if (text.indexOf("ON") > -1)//Caso o texto recebido contenha "ON" { digitalWrite(D4, 0);//Liga o LED bot.sendMessage(id, "LED ON", "");//Envia uma Mensagem para a pessoa que enviou o Comando. } else if (text.indexOf("OFF") > -1)//Caso o texto recebido contenha "OFF" { digitalWrite(D4, 1);//Desliga o LED bot.sendMessage(id, "LED OFF", "");//Envia uma Mensagem para a pessoa que enviou o Comando. } else if (text.indexOf("START") > -1)//Caso o texto recebido contenha "START" { bot.sendSimpleMessage(id, id, "");//Envia uma mensagem com seu ID. } else//Caso o texto recebido nao for nenhum dos acima, Envia uma mensagem de erro. { bot.sendSimpleMessage(id, "Comando Invalido", ""); } } }
Colocando para funcionar
Após a criação do BOT e upload do código, podemos ver funcionando. Veja o BOT respondeu como o esperado aos comandos:
Entendendo a fundo
Software
-Função UniversalTelegramBot::sendMessage()
bot.sendMessage(id, "LED OFF", "");
Com esta função, é feito o envio da mensagem para o determinado ID (referente ao ID de quem enviou a mensagem ao Bot). Logo ao iniciar seu BOT, automaticamente é enviado uma mensagem "/START", e nosso sistema irá responder com o seu ID do Telegram; você pode usar isso para aceitar apenas comandos de seu ID.
-Variável id
id = bot.messages[i].chat_id;
Toda vez que o Bot receber um novo update (mensagem), irá armazenar o ID da pessoa que enviou a mensagem na variável id.
-Variável text
text = bot.messages[i].text;
Toda vez que o Bot receber um novo update (mensagem), irá armazenar o texto na variável text.
A biblioteca do Telegram permite mais opções interessantes, como por exemplo obter o horário em que a mensagem foi enviada ao Bot! Dê uma olhada na referência da biblioteca.
-Função UniversalTelegramBot::getUpdates()
int newmsg = bot.getUpdates(bot.last_message_received + 1);
Esta função faz a verificação de novas mensagens, sempre será lido da última (mais recente), para a primeira (mais antiga) mensagem no buffer do Bot. Isto será feito até que se tenha lido todas as mensagens disponíveis então tome cuidado para não travar ou atrasar o resto do seu código!
Desafio
Qualquer pessoa que adicionar seu Bot (basta pesquisar), pode enviar comandos e controla-lo. Você terá que criar algum tipo de “cadeado” para aceitar apenas comandos de pessoas autorizadas. Cada usuário no Telegram tem um ID, então você pode usar isso à seu favor e fazer o sistema aceitar apenas comandos de algumas pessoas.
Fechamento
Podemos facilmente incluir este controle com o Telegram em diversos projetos, permitindo que o mesmo seja controlado à distancia e até mesmo que você seja notificado, como por exemplo um alarme para sua casa que mande mensagem para seu celular ao detectar movimento. As aplicações são imensas, dependendo apenas da sua criatividade. Dúvidas? Sugestões? Críticas? Comente!
O que é ESP8266 - A Família ESP e o NodeMCU
O que é ESP8266 - A Família ESP e o NodeMCU
Que tal conectar seu projeto à imensidão da internet de forma simples e barata? Essa é a proposta do ESP8266 que têm sido cada vez mais usado em projetos de automação e robótica para conectar as mais diversas ideais à internet. Neste tutorial você irá conhecer a família de microcontroladores ESP8266 que é tendência no mundo dos Makers e nos mais diversos exemplos de Internet das Coisas (IoT), e também aprenderá como funciona a sua programação e dar o primeiro upload. Entre eles: ESP-01 A, ESP-7, ESP-12E e NodeMcu
[toc]
O que é ESP8266?
É possível que você já tenha ouvido falar sobre o ESP8266, ele tem se tornado cada vez mais popular entre projetos de Internet das Coisas!
Os ESP8266's são microcontroladores que já possuem tudo que é necessário para se conectar a Internet. Ou seja, eles são como um Arduino com integração Wi-Fi.
Outro ponto importante é que eles são pequenos e isso viabiliza projetos pequenos.
Um exemplo é o ESP8266-01, esta minúscula placa, também chamado de "Módulo" por alguns, tem um potencial muito maior do que o aparenta, veja algumas especificações:
- CPU: 32bit RISC Tensilica Xtensa LX106 rodando à 80/160 MHz.
- RAM: 64 kB.
- FLASH: QSPI Externo - de 512 kB até 4 MB.
- WiFi: IEEE 802.11 - b/g/n.
Comparando diretamente com o Arduino, o ESP8266 tem um poder de processamento maior, porem há poucas GPIO's para usar nesta versão. Esta versão, conta apenas com 4 GPIO's para uso, sendo que dois são para comunicação Serial.
Para resolver esse problema de pinos insuficientes, existem versões mais robustas do ESP8266, como por exemplo, este ESP8266-12:
Este, é exatamente o mesmo que o anterior, mas conta com mais GPIO's disponíveis para uso geral.
APLICAÇÕES DO ESP8266
O uso para esse Micro controlador beira ao "Infinito", já que conta com poder de processamento e WiFi embutido. Com ele, também é possível ser usado como um "Módulo" com outros Micro controladores, isto pode ser feito através de comandos AT. Além disso, as versões menores, como o 01 ou 09, são muito usados como uma "Ponte Serial-WiFi", já que contam com poucos pinos; sendo assim, é possível receber dados por um aplicativo/WEB e enviar estes dados para um Arduino e acender uma lampada por exemplo! O oposto também é possível, enviar dados do Arduino para um aplicativo ou página WEB.
Algumas aplicações interessantes:
- Automação residencial.
- Rede de sensores.
- Robótica.
- Comunicação Wireless entre MCU's (Micro controller Unit).
- Aplicativos e Paginas WEB para controle geral.
- Monitoramento de Informações remotamente.
- E muito mais.
A Família ESP8266
Apresentaremos as principais características dos dois principais mais vendidos, que são: ESP8266-01 e o ESP8266-12 na versão NodeMCU.
ESP-01
Este pequeno ESP8266-01, conta com poucos pinos para uso geral, porém é muito usado por conta do seu tamanho como a "Ponte Serial-WiFi", segue a explicação dos pinos:
GND: Terra-GND.
Vcc: Alimentação de 3,3V.
RESET: Reset ativo quando em LOW.
CH_PD: Chip enable, deve estar em HIGH para funcionamento do MCU.
RXD: Receive data, usado para receber dados da comunicação de outros MCU's.
TXD: Tansmit data, usado para transmitir dados a outros MCU's.
GPIO0: GPIO (General Purpose Input/Output), este pino é para uso geral, tanto como Entrada/Saída e até Digital/PWM. Deve estar conectado ao GND para novos Upload's (Veja na Fig 4, Boot Modes).
GPIO2: GPIO para uso geral.
Para dar um novo upload à este carinha, você precisa de um conversor Serial (FTDI) para transmitir os dados até ele. As ligações são estas:
Lembrando que a alimentação deve ser feita com 3,3V, inclusive o Rx. Com isto, voce já sera capaz de dar upload de seus códigos.
NodeMCU
Esta versão do ESP8266-12 vem numa placa de desenvolvimento, chama-se de NodeMCU. Esta belezinha conta com conversor Serial e regulador de tensão próprio, não sendo necessário ambos como nas outras versões fora da placa. Também há pinos próprios para I2C, SPI, Analógico e outros.
GPIO's ESP8266:
Esta imagem, mostra todas definições de GPIO's do ESP8266, inclusive durante o boot, em que alguns pinos são mantidos em certos estados.
Mãos à obra
Este projeto é o "Hello world" no mundo de Microcontroladores. Você irá ensinar a dar o primeiro upload para piscar o LED_BUILTIN (LED OnBoard) do ESP8266-01 usando um FTDI externo. Pegue a pipoca e vamos la!
Componentes necessários
- 1 - ESP8266-01 ( ESP-01 A ).
- 1 - Módulo FTDI FT232RL - Conversor USB Serial.
- X - Jumper's.
As ligações ficarão parecidas com esta:
Estas são ligaçoes básicas, porém, para cada novo upload, é necessário colocar o GPIO0 em GND, como foi mostrado no esquema, GPIO0 já esta em GND. Não se esqueça dele sempre que for fazer um novo Upload!
Preparando a IDE Arduino
Usaremos a Arduino IDE, mas você pode programa-lo com LUA, ou até a propria SDK.
1-) Vá em Arquivos>Preferencias, e adicione este link em "URLs Adicionais...": http://arduino.esp8266.com/stable/package_esp8266com_index.json
2-) Vá em Ferramentas>Placa>Gerenciador de placas.
3-) Procure pelo ESP8266 e instale-o.
4-) Após instalar as placas do ESP8266, selecione-a em Ferramentas>Placa>Generic ESP8266 Module. (Estou usando o ESP8266-01, caso voce use por exemplo o NodeMCU, selecione NodeMCU...).
5-) Agora, é só configurar a placa, aconselho a usarem igual ao da foto. Testem primeiramente com o upload a 115200@bps, caso nao funcione, teste com outras velocidades! Não se esqueça de selecionar a porta que estiver seu FTDI.
Sua IDE esta pronta para funcionar com o ESP8266! Vamos ao código!
Código do projeto
void setup() { pinMode(LED_BUILTIN, OUTPUT);//Habilita o LED interno como Saida. } void loop() { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Inverte o estado do LED de acordo com a leitura. delay(250); }
Entendendo a fundo
Software
-Função pinMode()
pinMode(LED_BUILTIN, OUTPUT);//Habilita o LED interno como Saida.
Esta função define um pino, como saída ou entrada. Neste caso, definimos o pino do LED_BUILTIN como saída.
-Função digitalWrite() e digitalRead()
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Inverte o estado do LED de acordo com a leitura.
Aqui, estamos escrevendo um sinal lógico ao LED_BUILTIN. Neste caso, usamos a função digitalRead() que retorna o valor atual de um pino (1 para HIGH e 0 para LOW).
Usamos tambem um Inversor (NOT) "!" para inverter o estado de leitura, ou seja, caso o LED esteja ligado (1), invertemos para (0) e escrevemos isso à porta, assim, desligando-a.
-Função delay()
delay(250);
A função delay(), gera um atraso no código, fazendo com que o micro controlador trave naquela linha e fique até acabar o tempo. O tempo deve ser em mS, sendo que 1 Segundo = 1000mS.
De upload do codigo, e veja que o LED OnBoard (Azul) irá piscar a cada 250mS. Não se esqueça que para dar um novo upload, é necessário que o ESP8266 seja reiniciado com o GPIO0 em GND novamente.
Fechamento
Você aprendeu o que é este incrível microcontrolador e também como dar o primeiro upload à ele. Sinta-se à vontade para dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.
Você vai gostar de Conhecer o ESP32