AULA 7 _ Usando o Módulo GY-521 (MPU-6050) com o ESP32

Módulo GY-521 (MPU-6050) com o ESP32 | GIROSCÓPIO

Módulo GY-521 (MPU-6050) com o ESP32 | ACELERÔMETRO E GIROSCÓPIO

Olá, entusiastas da eletrônica e inovação! Neste tutorial, iremos explorar o módulo GY-521: suas aplicações, conexões e projetos práticos. Além disso, aprofundaremos nosso conhecimento sobre acelerômetro, giroscópios e também o protocolo I2C, essencial para a interação com este sensor.

kit robotica educacional com Arduino ESP ou Microbit

https://youtu.be/VEU_fLbrySo

Conhecendo o Módulo GY-521 (MPU-6050) | ACELERÔMETRO E GIROSCÓPIO

O módulo GY-521 é um módulo que utiliza o chip MPU-6050, é uma verdadeira maravilha da tecnologia que pode adicionar detecção de movimento e orientação aos seus projetos, unindo giroscópio e acelerometro de alta precisão em um único módulo tornando-o uma excelente opção.

Versatilidade de Aplicações: O módulo GY-521 é reconhecido por sua versatilidade, sendo aplicável em diversos projetos eletrônicos, como drones, robôs e dispositivos de realidade virtual.

Combinação de Sensores: Equipado com o chip MPU-6050, integra giroscópio e acelerômetro em um único dispositivo, permitindo medições precisas de movimentos e orientações.

Protocolo de Comunicação I2C: Utiliza o eficiente protocolo I2C, essencial para conexão com outros dispositivos no mesmo barramento.

Alta Precisão de Medição: Apresenta alta precisão nas medições de taxas de rotação, graças ao giroscópio, e fornece dados precisos sobre aceleração linear por meio do acelerômetro.

Acelerômetros e Giroscópios

Mas antes de entrarmos nos projetos, vamos ent: Para que serve o acelerômetro e o que exatamente é um giroscópio? Há alguma diferença importante entre eles?

Acelerômetro: Um acelerômetro é como um "detector de movimento" que ajuda a saber se algo está se movendo para frente, para trás, para cima ou para baixo. É o que permite que o seu telefone saiba quando você o está inclinando ou agitando.

Giroscópio: Um giroscópio é como um "sensor de rotação" que ajuda a entender se algo está girando ou virando. É útil para manter as coisas estáveis, como a câmera do seu telefone ao tirar uma foto, ou para ajudar um drone a permanecer equilibrado no ar.

Diferença: A principal diferença é que o acelerômetro ajuda a entender o movimento linear (para frente, para trás, para cima, para baixo), enquanto o giroscópio ajuda a entender a rotação ou movimento angular (giro, virada). Juntos, eles fornecem informações detalhadas sobre como um dispositivo está se movendo.

 

Mergulhando na Prática

Vamos agora colocar a mão na massa! Então pegue o seu kit, pois estamos prestes a mostrar como utilizar o GY-521.

Componentes necessários

BIBLIOTECAS

Para utilizar esse módulo com o ESP32 é necessário a instalação de algumas bibliotecas. Basta seguir esse passo-a-passo.

Abra a IDE da Arduino

• Rascunho > Incluir Biblioteca > Gerenciar Bibliotecas...  

• Procure por "Adafruit MPU6050". Em seguida instale. 

• Agora clique em INSTALAR TODAS, com isso você irá instalar todas as bibliotecas necessárias incluindo (Adafruit Unified Sensor e Adafruit BusIO).

• Pronto, já podemos utilizar nosso GY-521.

PROJETO 1

No nosso projeto inicial, vamos efetuar a leitura do sensor GY-521 e exibir os movimentos nos diferentes eixos no monitor serial.

montagem ESP32 com o Módulo GY-521 MPU-6050
montagem ESP32 com o Módulo GY-521 MPU-6050
//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 7 
//                      PROGRAMA 1 : PROJETO LEITURA DOS EIXOS

//inclusão das bibliotecas
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;

//Variaveis para receber os valores de aceleração dos eixos
int valoranteriorX = 0 ;
int valoranteriorY = 0 ;
int valoranteriorZ = 0 ;

//Define os leds
#define ledvermelho = 4;
#define ledamarelo = 5;
#define ledverde = 18;



void setup(void) {
  Serial.begin(115200); // iniciar o monitor serial 

 //Verifica se o módulo GY-521 (MPU6050) está conectado 
  if (!mpu.begin()) {
    Serial.println("Falha ao conectar o módulo");// caso não encontre
    while (1) {
      delay(10);
    }
  }
  Serial.println("Módulo conectado"); // caso encontre
// Definição da variação do chip.
  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Variação do aceleremetro para: ");
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    Serial.println("+-2G");
    break;
  case MPU6050_RANGE_4_G:
    Serial.println("+-4G");
    break;
  case MPU6050_RANGE_8_G:
    Serial.println("+-8G");
    break;
  case MPU6050_RANGE_16_G:
    Serial.println("+-16G");
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Variação do Giroscópio para: ");
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    Serial.println("+- 250 deg/s");
    break;
  case MPU6050_RANGE_500_DEG:
    Serial.println("+- 500 deg/s");
    break;
  case MPU6050_RANGE_1000_DEG:
    Serial.println("+- 1000 deg/s");
    break;
  case MPU6050_RANGE_2000_DEG:
    Serial.println("+- 2000 deg/s");
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filtro: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }

  Serial.println("");
  delay(100);

  //Inicia os pinos dos leds como saida
  pinMode(ledvermelho,OUTPUT);
  pinMode(ledamarelo,OUTPUT);
  pinMode(ledverde,OUTPUT);

  //Garante que iniciem desligados
  digitalWrite(ledvermelho,LOW);
  digitalWrite(ledamarelo,LOW);
  digitalWrite(ledverde,LOW);

}

void loop() {

  //Variáveis para leitura do Acelerometro, Giroscopio e Tempratura.
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  //Imprime os valores do acelerometro no monitor serial
  Serial.print("Aceleração X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");
//Imprime os valores do giroscopio no monitor serial
  Serial.print("Rotação X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");
//Imprime os valores do termometro no monitor serial
  Serial.print("Temperatura: ");
  Serial.print(temp.temperature);
  Serial.println(" °C");

  Serial.println("");
  delay(2000); // Atraso definido em milisegundos entre as leituras ** EDITAVEL**
}

 

PROJETO 2

Logo em seguida, vamos inserir três LEDs na montagem, utilizando-os como indicadores para alertar sempre que o sensor detectar movimento em qualquer um dos três eixos (x, y e z).

montagem ESP32 com o Módulo GY-521 MPU-6050 com leds

 

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 7 
//                      PROGRAMA 1 : PROJETO LEITURA DOS EIXOS

//inclusão das bibliotecas
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;

//Variaveis para receber os valores de aceleração dos eixos
int valoranteriorX = 0 ;
int valoranteriorY = 0 ;
int valoranteriorZ = 0 ;

//Define os leds
const int ledvermelho = 4;
const int ledamarelo = 5;
const int ledverde = 18;



void setup(void) {
  Serial.begin(115200); // iniciar o monitor serial 

 //Verifica se o módulo GY-521 (MPU6050) está conectado 
  if (!mpu.begin()) {
    Serial.println("Falha ao conectar o módulo");// caso não encontre
    while (1) {
      delay(10);
    }
  }
  Serial.println("Módulo conectado"); // caso encontre
// Definição da variação do chip.
  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Variação do aceleremetro para: ");
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    Serial.println("+-2G");
    break;
  case MPU6050_RANGE_4_G:
    Serial.println("+-4G");
    break;
  case MPU6050_RANGE_8_G:
    Serial.println("+-8G");
    break;
  case MPU6050_RANGE_16_G:
    Serial.println("+-16G");
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Variação do Giroscópio para: ");
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    Serial.println("+- 250 deg/s");
    break;
  case MPU6050_RANGE_500_DEG:
    Serial.println("+- 500 deg/s");
    break;
  case MPU6050_RANGE_1000_DEG:
    Serial.println("+- 1000 deg/s");
    break;
  case MPU6050_RANGE_2000_DEG:
    Serial.println("+- 2000 deg/s");
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filtro: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }

  Serial.println("");
  delay(100);

  //Inicia os pinos dos leds como saida
  pinMode(ledvermelho,OUTPUT);
  pinMode(ledamarelo,OUTPUT);
  pinMode(ledverde,OUTPUT);

  //Garante que iniciem desligados
  digitalWrite(ledvermelho,LOW);
  digitalWrite(ledamarelo,LOW);
  digitalWrite(ledverde,LOW);

}

void loop() {

  //Variáveis para leitura do Acelerometro, Giroscopio e Tempratura.
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  //Imprime os valores do acelerometro no monitor serial
  Serial.print("Aceleração X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");
//Imprime os valores do giroscopio no monitor serial
  Serial.print("Rotação X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");
//Imprime os valores do termometro no monitor serial
  Serial.print("Temperatura: ");
  Serial.print(temp.temperature);
  Serial.println(" °C");

  Serial.println("");

  //Condições de movimento para que os leds sejam acesos
  //eixo X
   int valoratualX = a.acceleration.x;

  if (valoratualX != valoranteriorX) {
    digitalWrite(ledvermelho, HIGH); // Acende o LED se houver alteração
  } else {
    digitalWrite(ledvermelho, LOW); // Mantém o LED apagado se não houver alteração
  }
valoranteriorX = valoratualX; // Atualiza o valor anterior para a próxima comparação

  //Eixo Y
      int valoratualY = a.acceleration.y;
    
    if (valoratualY != valoranteriorY) {
    digitalWrite(ledamarelo, HIGH); // Acende o LED se houver alteração
  } else {
    digitalWrite(ledamarelo, LOW); // Mantém o LED apagado se não houver alteração
  }

  valoranteriorY = valoratualY; // Atualiza o valor anterior para a próxima comparação

  //Eixo Z
   int valoratualZ = a.acceleration.z;

  if (valoratualZ != valoranteriorZ) {
    digitalWrite(ledverde, HIGH); // Acende o LED se houver alteração
  } else {
    digitalWrite(ledverde, LOW); // Mantém o LED apagado se não houver alteração
  }
valoranteriorZ = valoratualZ; // Atualiza o valor anterior para a próxima comparação
  
  delay(500); // Atraso definido em milisegundos entre as leituras ** EDITAVEL**
}

 

Entendendo a fundo

Arquitetura

O módulo GY-521 possui diversos pinos de conexão, cada um com funções específicas que podem variar de acordo com as necessidades do projeto. A seguir, detalharemos a função de cada um deles.

VCC: Pino de alimentação, geralmente conectado a uma fonte de 3.3V.

GND: Pino de terra, conectado ao terra do sistema.

SCL (Serial Clock): Pino de relógio para a comunicação I2C.

SDA (Serial Data): Pino de dados bidirecional para a comunicação I2C. 
XDA e XCL: Pinos auxiliares para expansões futuras, normalmente não são usados.
AD0: Pino de endereço usado para definir o último bit do endereço I2C. Pode ser conectado a VCC ou GND para definir o endereço.

INT: Pino de interrupção, usado para indicar que há dados prontos paraserem lidos.

 

Funcionamento

O módulo GY-521, também conhecido como MPU-6050 que é o chip utilizado nesse módulo, é uma unidade que integra funcionalidades de um acelerômetro e um giroscópio, permitindo a medição precisa de movimentos e orientação em um espaço tridimensional. O acelerômetro é responsável por mensurar a aceleração linear ao longo dos três eixos cartesianos (X, Y, Z), fornecendo informações sobre o quão rápido um objeto está se movendo em uma determinada direção. Por outro lado, o giroscópio avalia a taxa de rotação em torno dos mesmos eixos, indicando as mudanças na orientação do objeto.

Dessa forma, o GY-521 fornece dados abrangentes sobre o comportamento dinâmico de um objeto, capturando tanto as acelerações lineares quanto as rotações, sendo particularmente útil em aplicações que exigem um entendimento detalhado dos movimentos em três dimensões. Essa combinação de sensores permite que o módulo seja aplicado em uma variedade de projetos, desde controle de movimento até estabilização de dispositivos, contribuindo para uma ampla gama de aplicações em eletrônica e automação.

PROTOCÓLO I2C
 O protocolo I2C (Inter-Integrated Circuit) é um método de comunicação serial que permite a troca de dados entre dispositivos eletrônicos. Ele utiliza apenas dois fios, um para a transmissão de dados (SDA - Serial Data) e outro para o sinal de relógio
(SCL - Serial Clock). Esse protocolo é amplamente utilizado em dispositivos como sensores, módulos e chips para transmitir informações de maneira eficiente e simples.

 Uma das vantagens notáveis do protocolo I2C é sua capacidade de reduzir a quantidade de pinos necessários para conectar vários componentes eletrônicos em um sistema. Isso é especialmente útil em projetos que requerem a comunicação
entre múltiplos dispositivos, já que os pinos disponíveis em um microcontrolador muitas vezes são limitados.

 No contexto da nossa aula sobre o sensor GY-521 (MPU-6050), o protocolo I2C desempenha um papel crucial. Ele é utilizado para a comunicação entre o GY-521 e o microcontrolador, permitindo que os dados medidos pelo acelerômetro e giroscópio sejam transmitidos de maneira eficiente. Através dos pinos SDA e SCL do GY-521, podemos acessar informações sobre movimento e orientação em tempo real.

Conclusão

 

Convidamos você a participar ativamente desta comunidade. Deixe seu like, inscreva-se no canal e compartilhe suas dúvidas, conquistas e ideias nos comentários. Sua interação é o que dá vida a este canal. Estamos aqui para aprender juntos e moldar o futuro da tecnologia DIY e IoT. Até a próxima aula!


Controlando Módulo Relé via Bluetooth com ESP32 - Curso ESP32

Módulo Relé com ESP32 - Curso ESP32 básico

Olá, entusiastas da eletrônica e inovação! Nessa aula, vamos explorar uma função presente no ESP32, o Bluetooth, que possibilita o controle do relé para automação de lâmpadas e tomadas. Com isso, você poderá aprender a criar projetos de automação residencial que oferecem facilidade e praticidade no controle de dispositivos elétricos através do seu smartphone ou outro dispositivo compatível com Bluetooth.

Lembre-se que esse tutorial faz parte do Curso Esp32 que compõe nosso Kit IoT ESP32 – para Professores e Makers iniciantes

 

kit robotica educacional com Arduino ESP ou Microbit

Conhecendo o Módulo Relé

O módulo relé é um componente crucial em projetos de automação e controle elétrico. Este módulo atua como um interruptor controlado eletronicamente, permitindo o acionamento de dispositivos de alta potência através de sinais de baixa potência, como os provenientes de microcontroladores.

  • Tensão de Alimentação: Opera em uma faixa de tensão especificada, garantindo compatibilidade com diferentes fontes de alimentação.
  • Sinal de Controle: Possui um pino dedicado para o sinal de controle, permitindo a integração fácil com microcontroladores e sistemas de controle eletrônico.
  • Bornes de Conexão: Apresenta bornes para conexão ao circuito de alta potência, incluindo os terminais NC (Normalmente Fechado), COM (Comum) e NO (Normalmente Aberto).
  • Capacidade de Comutação: Oferece capacidade de comutação, permitindo a abertura ou fechamento do circuito de alta potência em resposta ao sinal de controle.
  • Proteção Eletromagnética: Incorpora mecanismos de proteção eletromagnética para evitar interferências indesejadas no circuito de controle.

Temos o tutorial módulo relé com arduino que explica um pouco mais sobre como módulos relés funcionam. Confere lá!

Mergulhando na Prática

Vamos agora colocar a mão na massa! Então pegue o seu kit, pois estamos prestes a mostrar como utilizar módulo relé.

Componentes necessários
• ESP32
• Protoboard
Módulo Relé 1 Canal
• LED (qualquer cor)
• Resistor de 100 Ω
• Jumper MXM

ITEM EXTRA *
• Fio paralelo
• Soquete de lâmpada
• Lâmpada

Com a mesma montagem, vamos criar dois projetos distintos, variando apenas o programa carregado no ESP32 em cada um deles.

*ATENÇÃO*

Antes de iniciarmos vale ressaltar que iremos trabalhar com rede elétrica, então certifique-se de desligar a rede antes de trabalhar com a conexão e muita atenção em todo o processo.

PROJETO 1

No nosso primeiro projeto, vamos empregar um temporizador com a função "delay"para que a lâmpada seja ligada e permaneça acesa por 5 segundos. Em seguida, ela será desligada e ficará apagada por mais 5 segundos.

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 10 
//                            PROGRAMA 1 : RELÉ COM TEMPORIZADOR


const int PINO_RELE = 18; // Pino D18 conectado ao relé

void setup() {
  pinMode(PINO_RELE, OUTPUT); // Configura o pino do relé como saída
}

void loop() {
  digitalWrite(PINO_RELE, HIGH); // Liga o relé
  delay(5000); // Aguarda 5 segundos

  digitalWrite(PINO_RELE, LOW); // Desliga o relé
  delay(5000); // Aguarda mais 5 segundos
}

 

PROJETO 2

Em seguida, vamos empregar uma funcionalidade disponível no ESP32, que é o Bluetooth, para controlar a lâmpada pelo celular. Certifique-se de configurar o aplicativo corretamente para uso. 

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 10 
//                            PROGRAMA 2 : RELÉ CONTROLADO POR BLUETOOTH


#include <BluetoothSerial.h>

BluetoothSerial SerialBT;

const int PINO_RELE = 18; // Pino D18 conectado ao relé
char comando;

void setup() {
  pinMode(PINO_RELE, OUTPUT); // Configura o pino do relé como saída

  SerialBT.begin("ESP32_VDS"); // Inicia o Bluetooth com o nome "ESP32_VDS", podendo ser alterado para qualquer nome de sua preferência
}

void loop() {
  if (SerialBT.available()) {
    comando = SerialBT.read(); // Lê o comando enviado via Bluetooth

    if (comando == 'a') //É possivel alterar a letra de comando ligar que no caso é "a" para sua prefêrencia
    {
      digitalWrite(PINO_RELE, HIGH); // Liga o relé
      SerialBT.println("Relé Ligado");//escreve no monitor 
    } else if (comando == 'b') //É possivel alterar a letra de comando desligar que no caso é "b" para sua prefêrencia
    {
      digitalWrite(PINO_RELE, LOW); // Desliga o relé
      SerialBT.println("Relé Desligado");
    }
  }
}

PROGRAMA DE CONTROLE VIA BLUETHOOTH
Ápos transferir o novo código para o ESP32 vamos precisar instalar um aplicativo em nosso celular para controlar o relé.

Passo 1: Instalação do Aplicativo Arduino Bluetooth Control

1. Vá até a loja de aplicativos do seu dispositivo (Google Play Store ou App
Store).

2. Pesquise por " Arduino Bluetooth Control " e selecione o aplicativo oficial.

3. Clique em "Instalar" para baixar o aplicativo em seu dispositivo.

Passo 2: Conexão Bluetooth
1. Ative o Bluetooth do seu dispositivo.

2. Abra o aplicativo "Arduino Bluetooth Control".

3. Vá para a seção de configurações do aplicativo e emparelhe seu dispositivo
com o módulo Bluetooth do ESP32 com nome definido no programa, no caso
do nosso está registrado como “ESP32_VDS

Passo 3: Escolha do modo
1. Após selecionar o Bluetooth irá abrir uma aba para escolha para o tipo de
automação.

2. Escolha a primeira opção “LED/Lamp Control.

Passo 4: Configurando o botão
1. Selecione a aba de configurações na parte superior direita

2. Agora, simplesmente selecione a opção ON e insira o comando
definido no programa para ligar. No nosso caso, será a letra "a".
Depois, na opção OFF, insira a letra "b" para desligar.
Passo 5: Utilização
1. Com o botão configurado agora vamos testar.

2. Clique no botão e veja a lâmpada acender e se tornar a clicar ele irá
desligar.
Agora você está pronto para aproveitar a funcionalidade Bluetooth do seu ESP32 para controlar outros dispositivos. Recomendo continuar explorando o plicativo e suas diversas funções, pois as possibilidades são praticamente ilimitadas.

Entendendo a fundo

Arquitetura

O módulo relé é constituído por três pinos essenciais, cada um com uma função específica, e três bornes para conexão ao circuito de alta potência.

Alimentação:

  • VCC (Tensão de Alimentação): Este pino é dedicado à entrada de energia, fornecendo a voltagem necessária para o funcionamento do relé.
  • GND (Terra): O pino GND está associado à referência de terra e deve ser conectado ao terminal de terra para estabelecer o circuito elétrico.

Controle:

  • Sinal de Controle: Responsável por receber o sinal de controle que aciona a mudança no estado do relé, conectando ou desconectando os bornes do circuito de alta potência.

Conexão ao Circuito de Alta Potência:

  • NC (Normalmente Fechado): Este borne está normalmente fechado quando o relé não é acionado, permitindo a condução de corrente quando ativado.
  • COM (Comum): Conectado ao circuito de alta potência, serve como o ponto central para a condução da corrente elétrica.
  • NO (Normalmente Aberto): Este borne fica normalmente aberto quando o relé não é acionado, interrompendo a condução de corrente quando ativado.

Essa estrutura fornece ao módulo relé a capacidade de controlar circuitos de alta potência por meio de um sinal de controle, facilitando sua aplicação em uma variedade de projetos, como automação residencial e controle de dispositivos elétricos.

Funcionamento

O módulo relé é um dispositivo fundamental em eletrônica que opera como um interruptor controlado eletronicamente. Seu funcionamento técnico envolve a presença de uma bobina que, ao ser energizada, cria um campo magnético em seu entorno. Esse campo magnético, por sua vez, atrai um contato móvel, alterando sua posição. Dependendo do tipo de relé (normalmente aberto ou normalmente fechado), essa mudança no posicionamento do contato móvel pode resultar na abertura ou fechamento do circuito de alta potência.

Uma característica crucial do módulo relé é o isolamento galvânico que proporciona entre o circuito de controle (baixa potência) e o circuito de carga (alta potência). Esse isolamento evita danos ao circuito de controle quando o circuito de carga está operando. Quando a corrente na bobina é interrompida, desenergizando-a, o campo magnético é desfeito, e o contato móvel retorna à sua posição inicial.

Alguns relés, como os de estado sólido, apresentam configurações específicas que utilizam componentes sem partes móveis, proporcionando maior durabilidade e confiabilidade. Essa capacidade de comutação remota torna o módulo relé crucial em sistemas de automação, controle de dispositivos elétricos e em diversos projetos eletrônicos, onde a separação eficaz entre circuitos de baixa e alta potência é necessária.

Conclusão

Nesta aula, desvendamos o funcionamento técnico do módulo relé, compreendendo sua essencialidade como interruptor eletrônico controlado por uma bobina eletromagnética. Exploramos como a ativação da bobina influencia o contato móvel, possibilitando a abertura ou fechamento do circuito de alta potência. Destacamos a importância do isolamento galvânico para a segurança elétrica e discutimos variações, como relés de estado sólido. Com este conhecimento, estamos prontos para aplicar o módulo relé em projetos práticos, explorando suas capacidades de controle remoto e automação em diversas aplicações eletrônicas.

Convidamos você a participar ativamente desta comunidade. Deixe seu like, inscreva-se no canal e compartilhe suas dúvidas, conquistas e ideias nos comentários. Sua interação é o que dá vida a este canal. Estamos aqui para aprender juntos e moldar o futuro da tecnologia DIY e IoT. Até a próxima aula!

 


Sensor de som módulo KY-037 com ESP32 - Curso ESP32

Sensor de som - módulo KY-037 com ESP32 - Curso ESP32 básico

Este sensor de som, também chamado de módulo microfone ou módulo ky-037, é uma ferramenta versátil para projetos de detecção de som como por exemplo os famosos projetos clapper, que são projetos onde você acende e apaga as luzes batendo palmas. Já viu? Então, vamos explorar suas características, aprender a conectá-lo ao ESP32 (Conhecendo o ESP32)  e descobrir como integrá-lo em projetos. Pronto para explorar as possibilidades do módulo microfone KY-037?

kit robotica educacional com Arduino ESP ou Microbit

Conhecendo o Sensor de som - módulo ky-037

https://youtu.be/r51-9N0TLzo

O módulo KY-037 se destaca como um sensor de vibração, apresentando um potenciômetro ajustável que possibilita a configuração da sensibilidade conforme necessidades específicas, tornando-o uma ferramenta versátil para aplicações eletrônicas diversas.

  • Princípio de Funcionamento: O KY-037 opera detectando vibrações e convertendo-as em sinais elétricos.
  • Sensibilidade Ajustável: Destaca-se pela capacidade de ajustar a sensibilidade conforme a necessidade do projeto.
  • Ampla Faixa de Detecção: Possui uma ampla faixa de detecção, sendo eficaz para vibrações leves e intensas.
  • Fácil Integração: Sua interface simples facilita a integração em projetos, sendo amigável para iniciantes.
  • Versatilidade em Projetos DIY: Popular em projetos de bricolagem devido à sua versatilidade em diversas aplicações práticas.
  • Baixo Consumo de Energia: Eficiente em termos de consumo, ideal para projetos alimentados por baterias.
  • Ampliação de Recursos: Combinação versátil com outros componentes, ampliando as possibilidades criativas em projetos eletrônicos.

Mergulhando na Prática - usando o módulo microfone KY-037

Agora, vamos colocar a mão na massa! Então pegue o seu kit, pois estamos prestes a mostrar como utilizar o KY-037.

Componentes necessários

Ajuste do sensor de som - módulo ky-037

Conforme mencionado, este módulo inclui um potenciômetro destinado a ajustar a sensibilidade em relação ao que é interpretado como ruído.

sensor de som - módulo ky-037
sensor de som - módulo ky-037
  • Utilize uma chave de fenda pequena ou a ferramenta apropriada para girar o potenciômetro, assegurando-se de que seja compatível com o formato do componente.
  • Faça o ajuste de forma gradual, girando o potenciômetro em sentido horário ou anti-horário, enquanto o KY-037 está energizado.
  • Observe atentamente as mudanças na sensibilidade do sensor em relação às vibrações. Aumentar a sensibilidade pode resultar na detecção de movimentos mais sutis, enquanto diminuir a sensibilidade o tornará menos suscetível a vibrações leves.
  • Realize testes práticos expondo o KY-037 a diferentes intensidades de vibrações para determinar o ajuste ideal do potenciômetro, adaptando-o ao ambiente específico do projeto.
  • Lembrando que quando o "LED 2" acende ele está detectando ruído.

PROJETO 1 - ligando um LED com módulo microfone KY-037

Neste primeiro projeto, iremos empregar a detecção de ruído para acionar um LED. E guarde bem esse conhecimento, pois utilizando apenas mais um componente presente no KIT, é possível acionar até mesmo a lâmpada de sua casa.

Dica: caso ainda seja iniciante no uso do protoboard, confira nosso tutorial como usar um protoboard.

sensor de som - módulo ky-037
sensor de som - módulo ky-037

Após concluído a primeira montagem, peço que verifiquem se ele está regulado para o nível de ruído presente no seu ambiente, é possível realizar esse ajuste manualmente como mostrado no tópico de ajuste.

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 6 
//                            PROGRAMA 1 : PROJETO DETECTANDO RUIDO  

const int sensor = 4; // Pino D4 conectado ao sensor KY-037
const int led = 19; //Pino D19   conectado ao LED
bool estado = 0; // Variavel que armazena se teve ruido ou não (INICIA COMO 0 OU SEJA NÃO TEM RUIDO)

void setup(){
  pinMode(sensor, INPUT); //Define o pino 4 (sensor) como entrada
  pinMode(led, OUTPUT); //Define o pino 19 (LED) como saida
  digitalWrite(led,LOW);//Garante que o led irá iniciar desligado
}

void loop(){
  if (digitalRead(sensor) == HIGH)//Se o sensor detectar o ruído seu nivel lógico será 1, ou seja, HIGH. Então ele fará a ação.
  { 
      estado = digitalRead(led); //Verifica o estado do sensor e armazena 
      digitalWrite(led, !estado); //Altera o estado do LED (caso esteja ligado ele desliga e caso esteja desligado ele liga)
      delay(500); //Intervalo de 0,5 segundos entre as leituras
  }
}

 

 

PROJETO 2 - Usando sensor de som - módulo ky-037 - para acionar um buzzer

Na próxima etapa, trocaremos o LED pelo buzzer para construir um sistema de segurança. Ao identificar qualquer ruído, o buzzer emitirá um alerta sonoro que durará alguns segundos.

montagem sensor de som - módulo ky-037 - com esp32 e buzzer
montagem sensor de som - módulo ky-037 - com esp32 e buzzer
//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 6 
//                            PROGRAMA 2 : PROJETO ALARME

const int sensor = 4; // Pino D4 conectado ao sensor KY-037
const int buzzer = 19; //Pino D19   conectado ao BUZZER
bool estado = 0; // Variavel que armazena se teve ruido ou não (INICIA COMO 0 OU SEJA NÃO TEM RUIDO)

void setup(){
  pinMode(sensor, INPUT); //Define o pino 4 (sensor) como entrada
  pinMode(buzzer, OUTPUT); //Define o pino 19 (LED) como saida
  digitalWrite(buzzer,LOW);//Garante que o BUZZER irá iniciar desligado
}

void loop(){
  if (digitalRead(sensor) == HIGH)//Se o sensor detectar o ruído seu nivel lógico será 1, ou seja, HIGH. Então ele fará a ação.
  { 
      estado = digitalRead(buzzer); //Verifica o estado do sensor e armazena 
      digitalWrite(buzzer, !estado); //Altera o estado do BUZZER que inicia como desligado sempre que entra no loop, logo ele ligará o buzzer nessa linha.
      delay(5000); //Mantem o BUZZER ligado por 5 segundo.
      digitalWrite(buzzer, estado);//Retorna ao estado inicial do BUZZER que é desligado.
      delay(1000);//Intervalo de 1 segundo entre as leituras para evitar que o próprio BUZZER ative o alerta.
  }
}

ENTENDENDO A FUNDO O SENSOR DE SOM

Arquitetura do sensor de som - módulo ky-037 

O módulo KY-037 possui uma arquitetura simples, mas eficaz, projetada para detectar vibrações e converter esses movimentos em sinais elétricos. Vamos examinar seus principais elementos:

Pinos:

  • AO (Analógico): Fornece uma saída analógica proporcional à intensidade das vibrações detectadas.
  • DO (Digital): Emite um sinal alto ou baixo, indicando se uma vibração foi detectada.

Potenciômetro (ajustável) - AJUSTANDO SENSIBILIDADE DO sensor de som - módulo ky-037 :

  • Este componente ajustável, frequentemente chamado de potenciômetro, desempenha um papel crucial na regulagem do sensor. Ele permite ajustar a sensibilidade do módulo, adaptando-o para diferentes intensidades de vibrações.

LEDs:

Os LEDs são responsáveis pelo feedback visual para as seguintes funcionalidades:

  • LED 1: Acende quando o módulo está alimentado que varia de 3.3v a 5v.
  • LED 2 : Acende quando detecta ruído 
sensor de som - módulo ky-037
sensor de som - módulo ky-037

Funcionamento

O KY-037 opera com base no princípio piezoelétrico para detectar vibrações. Internamente, o módulo inclui um sensor piezoelétrico, que é um cristal que gera uma carga elétrica quando é deformado mecanicamente. Logo, quando ocorre uma vibração, o cristal é submetido a esse estresse mecânico, gerando uma pequena corrente elétrica proporcional à intensidade da vibração.

Além disso, A saída do sensor piezoelétrico é então processada pelo circuito interno do KY-037. Ele converte a corrente gerada pelo sensor em sinais elétricos mais utilizáveis, oferecendo saídas analógicas e digitais. A saída analógica (pino AO) fornece uma voltagem que varia proporcionalmente à intensidade da vibração, enquanto a saída digital (pino DO) emite um sinal lógico alto ou baixo, indicando a detecção ou não de vibrações.

Dessa forma, O potenciômetro ajustável no KY-037 desempenha um papel crucial nesse processo, permitindo calibrar a sensibilidade do sensor. Girar o potenciômetro modifica a sensibilidade, adaptando-a para diferentes níveis de vibração no ambiente. Isso oferece uma flexibilidade significativa ao adaptar o KY-037 a condições específicas do projeto.

Portanto, de maneira mais aprofundada, o KY-037 é um sensor de vibração que se baseia na propriedade piezoelétrica para converter vibrações mecânicas em sinais elétricos, e o potenciômetro ajustável proporciona controle sobre a sensibilidade do sensor.


Conclusão

Enfim, Encerramos aqui nossa jornada nesta aula dedicada ao módulo KY-037.Exploramos suas características, compreendemos seu funcionamento e visualizamos suas potenciais aplicações em projetos práticos. Este aprendizado não apenas amplia nossos conhecimentos em eletrônica, mas também abre portas para a criatividade e inovação. À medida que avançamos em nossa jornada.

No mais, convidamos você a participar ativamente desta comunidade. Deixe seu like, inscreva-se no canal e compartilhe suas dúvidas, conquistas e ideias nos comentários. Sua interação é o que dá vida a este canal. Estamos aqui para aprender juntos e moldar o futuro da tecnologia DIY e IoT. Até a próxima aula!


HC-SR04 com ESP32 - Curso ESP32 básico

HC-SR04 com ESP32 - Curso ESP32 básico

Olá, entusiastas da eletrônica e inovação! Nesta aula, vamos conhecer o HC-SR04, um sensor ultrassônico que possibilita a detecção de distância utilizando um sonar semelhante ao utilizado por navios e morcegos. Ele verifica a distância e a comunica ao nosso microcontrolador, que, neste caso, é o ESP32. Vamos explorar seu funcionamento e aprender como utilizá-lo em projetos.

Lembre-se que esse tutorial faz parte do Curso Esp32 que compõe nosso Kit IoT ESP32 – para Professores e Makers iniciantes

Vale dizer que temos um artigo aqui no portal explicando o uso do HC-SR04 com Arduino.

Sensor Distância Ultrassônico HCSR04, HC-SR04 ou HC SR04
Sensor Distância Ultrassônico HC SR04

kit robotica educacional com Arduino ESP ou Microbit

Conhecendo o HC-SR04

O sensor utiliza princípios de ultrassom para medir distâncias. Ele emite um pulso ultrassônico, aguarda o retorno do eco e calcula a distância com base no tempo que o som levou para retornar. É uma ferramenta valiosa em projetos que envolvem detecção de obstáculos, sistemas de navegação e muito mais.

  • Sonar inspirado na natureza: O HC-SR04 utiliza a mesma tecnologia de sonar que é encontrada em navios e morcegos para medir distâncias de forma precisa e eficiente.
  • Método de medição ultrassônica: Este sensor emite pulsos ultrassônicos e mede o tempo que esses pulsos levam para retornar após atingirem um objeto. Essa técnica permite a determinação precisa da distância.
  • Ampla faixa de medição: O HC-SR04 é capaz de medir distâncias em uma faixa que vai de 2 cm a 4 metros, tornando-o versátil para uma variedade de aplicações.
  • Precisão notável: Com uma precisão de aproximadamente 3 mm, este sensor é capaz de fornecer leituras detalhadas, garantindo confiabilidade em projetos sensíveis à distância.
  • Fácil integração: Sua simplicidade de uso e interface amigável tornam o HC-SR04 acessível mesmo para iniciantes em eletrônica, sendo amplamente utilizado em projetos DIY e educacionais.
  • Ampla aplicação em automação: O HC-SR04 é uma escolha popular em projetos de automação, como robôs e sistemas de monitoramento, devido à sua capacidade de detectar objetos e obstáculos com precisão.
  • Baixo custo e alto desempenho: Além de suas características impressionantes, o HC-SR04 é conhecido por ser um sensor acessível, proporcionando um excelente custo-benefício para entusiastas e projetistas.

https://www.youtube.com/watch?v=ztLUq0ckbl8

 

Mergulhando na Prática

Vamos agora colocar a mão na massa! Então pegue o seu kit, pois estamos prestes a mostrar como utilizar o HC-SR04.

Componentes necessários
• ESP32
• Protoboard
HC-SR04
• LED (qualquer cor)
• Resistor de 100 Ω
• Jumper MXM
Buzzer Ativo

 

PROJETO 1

No nosso projeto inicial, estaremos focados na medição de distância utilizando o sensor ultrassônico. O objetivo é exibir, no monitor serial, a distância em centímetros do objeto detectado.

 

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 5 
//                            PROGRAMA 1 : PROJETO MEDINDO A DISTÂNCIA  


const int PINO_TRIG = 4; // Pino D4 conectado ao TRIG do HC-SR04
const int PINO_ECHO = 2; // Pino D2 conectado ao ECHO do HC-SR04

void setup() {
  Serial.begin(9600); // Inicializa a comunicação serial
  pinMode(PINO_TRIG, OUTPUT); // Configura o pino TRIG como saída
  pinMode(PINO_ECHO, INPUT); // Configura o pino ECHO como entrada
}

void loop() {
  digitalWrite(PINO_TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(PINO_TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(PINO_TRIG, LOW);
  
  long duracao = pulseIn(PINO_ECHO, HIGH); // Mede o tempo de resposta do ECHO  
  float distancia = (duracao * 0.0343) / 2;// Calcula a distância usando a velocidade do som (aproximadamente 343 m/s)
  Serial.print("Distância: ");
  Serial.print(distancia);
  Serial.println(" cm");
  
  delay(1000); // Aguarda 1 segundo antes de fazer a próxima leitura
}
//long -> A variável "long" é utilizada para armazenar números inteiros longos, ou seja, números inteiros maiores do que os que podem ser armazenados em uma variável "int"
//delayMicroseconds -> A função delayMicroseconds() lida com microssegundos (10 elevado a -6 segundos), enquanto a função delay() lida com milissegundos (10 elevado a -3 segundos).

 

PROJETO 2

No projeto seguinte, incorporaremos um LED à nossa configuração. A proposta é enviar um alerta visual sempre que um objeto ultrapassar o limite de distância predefinido.

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 5 
//                            PROGRAMA 2 : PROJETO ALERTA DE PROXIMIDADE


const int PINO_TRIG = 4; // Pino D4 conectado ao TRIG do HC-SR04
const int PINO_ECHO = 2; // Pino D2 conectado ao ECHO do HC-SR047
//INCLUSÃO DO LED
const int PINO_LED = 5;  // Pino D5 conectado ao LED

void setup() {
  Serial.begin(9600); // Inicializa a comunicação serial
  pinMode(PINO_TRIG, OUTPUT); // Configura o pino TRIG como saída
  pinMode(PINO_ECHO, INPUT);  // Configura o pino ECHO como entrada
  pinMode(PINO_LED, OUTPUT);  // Configura o pino LED como saída
}

void loop() {
  digitalWrite(PINO_TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(PINO_TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(PINO_TRIG, LOW);
  
  long duracao = pulseIn(PINO_ECHO, HIGH); // Mede o tempo de resposta do ECHO
  float distancia = (duracao * 0.0343) / 2;// Calcula a distância usando a velocidade do som (aproximadamente 343 m/s)
  Serial.print("Distância: ");
  Serial.print(distancia);
  Serial.println(" cm");
  
  if (distancia <= 10) // quando estiver menor ou igual a 10 cm enviará um alerta. ** Valor editável para a distância preferir.
  {
    digitalWrite(PINO_LED, HIGH); // Acende o LED se a distância for menor ou igual a 10 cm
  } else {
    digitalWrite(PINO_LED, LOW);  // Desliga o LED caso contrário
  }
  
  delay(1000); // Aguarda 1 segundo antes de fazer a próxima leitura
}

Embora tenhamos inicialmente um LED como parte de nosso circuito, podemos fazer um experimento. Substituiremos o LED por um buzzer ativo, mas é crucial observar a polaridade. Dessa forma, poderemos alternar entre alertas sonoros e visuais de maneira simples.

ENTENDENDO A FUNDO

Arquitetura

A arquitetura de pinos do sensor de ultrassom varia dependendo do modelo do sensor que você está utilizando. No entanto, a maioria dos sensores de ultrassom possui pelo menos dois pinos principais: o pino de "Trigger" (ou "TRIG") e o pino de
"Echo" (ou "ECHO"). Alem dos pinos de alimentação VCC e GND.
Pino de Trigger (Envio): Responsável por enviar os pulsos ultrassônicos para o ambiente.
Pino de Echo (Recebimento): Recebe o sinal refletido após o pulso atingir um objeto.
Esses componentes trabalham em conjunto para permitir que o sensor detecte e meça com precisão as distâncias dos objetos, tornando-o uma ferramenta valiosa
em diversas aplicações.

HC-SR04 - Sensor Ultrassom
HC-SR04 - Sensor Ultrassom

Funcionamento

O HC-SR04 opera de maneira eficiente através dos pinos Trig (Trigger) e Echo. Aqui está uma breve explicação do funcionamento de cada um:

Trigger (Trig):

  • O pino Trig é responsável por iniciar a medição de distância.
  • Para iniciar a medição, você envia um pulso de pelo menos 10 microssegundos para o pino Trig.
  • Esse pulso ativa o envio de ondas ultrassônicas em direção ao objeto que se deseja medir a distância.

Echo:

  • O pino Echo é utilizado para receber o retorno do sinal ultrassônico.
  • Quando as ondas ultrassônicas atingem um objeto e retornam, o pino Echo emite um pulso.
  • A duração desse pulso no pino Echo é proporcional à distância entre o sensor e o objeto.

Cálculo da Distância:

A distância pode ser calculada aplicando uma manipulação da fórmula de velocidade média, a qual também é familiar do nosso Ensino Médio e é a mesma utilizada em nossos código:


 

 

 

 

 

 

 

 

-ΔS é o intervalo de deslocamento (espaço)

-Δt é o intervalo de tempo (tempo final - tempo inicial) 

-A velocidade do som é geralmente considerada como 343 metros por segundo.

-Dividir por 2 é necessário porque o pulso viaja para o objeto e retorna, então a distância real é metade do caminho percorrido.


Em resumo, o Trig inicia o processo enviando pulsos ultrassônicos, e o Echo mede o tempo que leva para esses pulsos retornarem após atingirem um objeto. Essa informação de tempo é então utilizada para calcular a distância entre o sensor e o objeto em questão.

 

Conclusão

Encerramos aqui nossa aula, na qual exploramos o uso do sensor ultrassônico, aprofundando nosso entendimento da física por trás desse componente. Existem diversos projetos interessantes que podem ser realizados com o HC-SR04, como réguas, sensores de estacionamento e detecção de presença no ambiente. Que tal experimentar e conhecer ainda mais esse incrível componente?

Convidamos você a participar ativamente desta comunidade. Deixe seu like, inscreva-se no canal e compartilhe suas dúvidas, conquistas e ideias nos comentários. Sua interação é o que dá vida a este canal. Estamos aqui para aprender juntos e moldar o futuro da tecnologia DIY e IoT. Até a próxima aula!


NTC10K: Sensor de temperatura com ESP32 - Curso ESP32

NTC10K Sensor de temperatura com ESP32 - Curso ESP32 básico

Olá, entusiastas da eletrônica e inovação! Nesta aula, vamos explorar o NTC 10k, um sensor sensível à temperatura. Abordaremos suas aplicações e a criação de projetos simples com ele, explorando suas características fundamentais e compreendendo seu uso na monitorização e controle de temperatura em diversos contextos. Além disso, aprenderemos sobre as portas digitais e analógicas do ESP32. Esteja preparado para descobrir como o NTC 10k pode se tornar uma ferramenta valiosa em seus projetos. 

Lembre-se que esse tutorial faz parte do Curso Esp32 que compõe nosso Kit IoT ESP32 – para Professores e Makers iniciantes

https://www.youtube.com/watch?v=Jb_QwD0a0F0

kit robotica educacional com Arduino ESP ou Microbit

Conhecendo o NTC10K

O NTC 10k é um termistor cuja resistência varia em resposta às mudanças de temperatura. Com uma resistência nominal de 10.000 ohms a 25°C, esse componente é amplamente empregado em projetos eletrônicos para medir e monitorar variações térmicas. Sua resposta não linear à temperatura o torna eficaz na detecção precisa de mudanças térmicas em diferentes ambientes

  • Curvas de Resposta: Cada sensor NTC possui uma curva de resposta de resistência em relação à temperatura única. Isso requer que você calibre seu sensor para obter leituras precisas em sua aplicação.
  • Precisão Surpreendente: Apesar da natureza não linear dos NTCs, eles podem oferecer alta precisão em uma faixa de temperatura específica, tornando-os ideais para muitas aplicações de medição de temperatura.
  • Compensação de Temperatura: Sensores NTC também são frequentemente usados para compensação de temperatura em circuitos eletrônicos, garantindo que os componentes funcionem corretamente em diferentes condições térmicas.
  • Termômetros Digitais: Os NTCs são frequentemente encontrados em termômetros digitais, termostatos residenciais e até mesmo em sistemas de controle de climatização de veículos.

Mergulhando na Prática

Vamos agora colocar a mão na massa! Então pegue o seu kit, pois estamos prestes a mostrar como utilizar o NTC10K, além de empregarmos novamente o LED como meio de alerta.

Componentes necessários
• ESP32
• Protoboard
Termistor NTC10K
• LED (qualquer cor)
• Resistor de 100 Ω
• Resistor de 10k Ω
• Jumper MXM

PROJETO 1

Neste projeto inicial, vamos efetuar a leitura do sensor NTC 10k e exibir os resultados de temperatura em graus Celsius no monitor serial.

 

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 4 
//                            PROGRAMA 1 : LER SENSOR NTC10K 



int PinoNTC = 4; // PINO DO NTC10K
double Vs = 3.3; // TENSÃO DE SAIDA DO ESP32
double R1 = 10000; //RESISTOR UTILIZADO NO DIVISOR DE TENSÃO
double Beta = 3950; // VALOR DE BETA
double To=298.15; // VALOR EM KELVIN REFERENTE A 25° CELSIUS
double Ro=10000;
double adcMax = 4095.0;



void setup() {
  Serial.begin(9600); // INICIA O MONITOR SERIAL A UMA TAXA DE ATUALIZAÇÃO DE 9600
  pinMode(PINO_LEDVERDE, OUTPUT); // Configura o pino do LED verde
  pinMode(PINO_LEDAMARELO, OUTPUT); // Configura o pino do LED amarelo
} 
  
void loop() {
  //GARANTE QUE AS INFORMAÇÕES SERÃO RESETADAS APÓS CADA LEITURA
  double Vout, Rt = 0;
  double T, Tc, Tf, adc = 0;

  adc = analogRead(PinoNTC);// VARIÁVEL QUE RECEBE A LEITURA DO NTC10K

  //CALCULOS PARA CONVERSÃO DA LEITURA RECEBIDA PELO ESP32 EM TEMPERATURA EM °C
  Vout = adc * Vs/adcMax;
  Rt = R1 * Vout / (Vs - Vout);
  T = 1/(1/To + log(Rt/Ro)/Beta);
  Tc = T - 273.15;
  Tf = Tc * 9 / 5 + 32;
  //Imprime no monitor serial o texto e a temperatura lida pelo sensor
  Serial.print("Temperatura: ");
  Serial.print(Tc);
  Serial.println(" °C");
  }
  delay(2000); // atraso entre as leituras
}

//Serial.print: Utilizado para imprimir no monitor serial alguma informação, se estiver entre aspas será escrito o texto que estiver contido e caso não utilize as aspas é esperado alguma variavel para exibir a informação contida nela.
//Serial.println: Esse comando terminado em ln apenas define uma quebra de linha após o texto ser exibido.

 

PROJETO 2

Posteriormente, iremos incorporar dois LEDs ao projeto e estabelecer uma temperatura mínima na qual o sensor realizará a leitura, controlando os LEDs de acordo com essa temperatura.

 

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 4 
//                            PROGRAMA 2 : PROJETO NTC10K COM ALERTA DE LED  



int PinoNTC = 4; // PINO DO NTC10K
double Vs = 3.3; // TENSÃO DE SAIDA DO ESP32
double R1 = 10000; //RESISTOR UTILIZADO NO DIVISOR DE TENSÃO
double Beta = 3950; // VALOR DE BETA
double To=298.15; // VALOR EM KELVIN REFERENTE A 25° CELSIUS
double Ro=10000;
double adcMax = 4095.0;

//ACRESCENTANDO OS LEDS
const int PINO_LEDAMARELO = 22; // Pino D22 conectado ao LED amarelo
const int PINO_LEDVERDE = 23; // Pino D23 conectado ao LED verde



void setup() {
  Serial.begin(9600); // INICIA O MONITOR SERIAL A UMA TAXA DE ATUALIZAÇÃO DE 9600
  pinMode(PINO_LEDVERDE, OUTPUT); // Configura o pino do LED verde
  pinMode(PINO_LEDAMARELO, OUTPUT); // Configura o pino do LED amarelo
} 
  
void loop() {
  //GARANTE QUE AS INFORMAÇÕES SERÃO RESETADAS APÓS CADA LEITURA
  double Vout, Rt = 0;
  double T, Tc, Tf, adc = 0;

  adc = analogRead(PinoNTC);// VARIÁVEL QUE RECEBE A LEITURA DO NTC10K

  //CALCULOS PARA CONVERSÃO DA LEITURA RECEBIDA PELO ESP32 EM TEMPERATURA EM °C
  Vout = adc * Vs/adcMax;
  Rt = R1 * Vout / (Vs - Vout);
  T = 1/(1/To + log(Rt/Ro)/Beta);
  Tc = T - 273.15;
  Tf = Tc * 9 / 5 + 32;
  Serial.print("Temperatura: ");
  Serial.println(Tc);
  Serial.println(" °C");
 //CONDIÇÃO PARA ALERTA DOS LEDS
 if (Tc < 30) { //Valor de temperatura editável para sua preferência
    digitalWrite(PINO_LEDVERDE, HIGH); // Acende o LED verde
    digitalWrite(PINO_LEDAMARELO, LOW);   // Desliga o LED amarelo
  } else {//caso maior que o valor de temperatura minimo, acenderá o amarelo.
    digitalWrite(PINO_LEDVERDE, LOW);  // Desliga o LED verde
    digitalWrite(PINO_LEDAMARELO, HIGH);  // Acende o LED amarelo
  }
  delay(2000); // atraso entre as leituras
}

 

ENTENDENDO A FUNDO

Arquitetura

Apesar da sua aparente simplicidade na arquitetura, o NTC 10k possui uma composição interna que permite uma resposta altamente sensível às variações de temperatura. Sua estrutura é baseada em materiais semicondutores, nos quais a
condutividade elétrica é significativamente influenciada pela temperatura.

Funcionamento

Para compreender o funcionamento do NTC10K, é fundamental reconhecer que se trata de um resistor. Os resistores são componentes que regulam o fluxo de corrente em um circuito. No caso do NTC10K, sua resistência é variável em função da temperatura. Em outras palavras, quando a temperatura ao redor do sensor se modifica, sua resistência também varia, possibilitando maior ou menor passagem de corrente elétrica. Essa informação é então enviada ao microcontrolador, como o ESP32, que, por meio de cálculos de conversão, interpreta a quantidade de corrente recebida, proporcionando a leitura da temperatura ambiente.

Portas Digitais e Analógicas

Até agora, havíamos utilizado exclusivamente a função digital das portas. Nesta aula, aprendemos a empregar a porta analógica. Vamos agora entender a diferença entre Portas Digitais e Analógicas para escolher qual é mais adequada para o nosso projeto:

Porta digital: caracteriza-se por possuir apenas dois níveis lógicos (0 ou 1; ligado ou desligado; 0 ou 3.3V). Isso implica que não é possível detectar variações no intervalo entre esses dois níveis.

Porta analógica: por outro lado, essa função consegue identificar todas as variações dentro do intervalo, possibilitando uma análise ou controle mais preciso de todas as nuances presentes entre esses níveis lógicos.

Conclusão

E assim finalizamos esta aula sobre o sensor NTC 10k. Exploramos a leitura de temperatura e como utilizar essa informação para controlar LEDs de maneira prática. O conhecimento adquirido abre portas para uma variedade de aplicações em que a detecção de temperatura é crucial.

Convidamos você a participar ativamente desta comunidade. Deixe seu like, inscreva-se no canal e compartilhe suas dúvidas, conquistas e ideias nos comentários. Sua interação é o que dá vida a este canal. Estamos aqui para aprender juntos e moldar o futuro da tecnologia DIY e IoT. Até a próxima aula!


Buzzer com ESP32 - Curso ESP32 básico

Buzzer com ESP32- Curso ESP32 básico

Olá, entusiastas da eletrônica e da inovação! No tutorial de hoje, iremos explorar o piezoelétrico, também conhecido como buzzer. Vamos descobrir seus diferentes tipos, diversas aplicações e aprender como utilizá-lo de maneira prática. O piezoelétrico é um componente fascinante e versátil. Após esta aula, você estará preparado para incorporá-lo de forma criativa e funcional em seus projetos.

Lembre-se que esse tutorial faz parte do Curso Esp32 que compõe nosso Kit IoT ESP32 – para Professores e Makers iniciantes

https://www.youtube.com/watch?v=bUDSkKMUMd0

kit robotica educacional com Arduino ESP ou Microbit

Conhecendo o Buzzer

Os buzzers são dispositivos eletromecânicos ou piezoelétricos que transforma energia elétrica em som audível são componentes simples, porém de extrema importância em sistemas que necessitam emitir alertas ou melodias. Com baixo custo, facilidade de conexão e operação, os buzzers se destacam como excelentes dispositivos sonoros. Eles são amplamente utilizados para adicionar funcionalidade sonora em uma variedade de aplicações, tornando-se uma escolha popular quando se trata de som.

• Presentes no Dia a Dia: Buzzers estão em dispositivos comuns como telefones celulares, relógios despertadores, aparelhos de micro-ondas e brinquedos, produzindo sons que variam de simples bipes a melodias completas.
• Funcionamento Vibratório: Buzzers criam som através de um elemento vibratório que faz o ar ao redor vibrar quando eletricamente excitado.
• Frequência e Tons: A frequência determina o tom do som que um buzzer produz. Isso permite criar uma variedade de tons, tornando-os ótimos para projetos de som.
• Aplicações de Alerta: Buzzers são comumente usados em alarmes de incêndio, sistemas de segurança e veículos para sinalizar eventos importantes, como portas abertas.

Tipos de Buzzer

Vamos explorar os conceitos básicos sobre o buzzer passivo e o buzzer ativo, dois dispositivos utilizados para produzir sons audíveis em diversos projetos. Entenderemos suas características e aplicações para que você possa escolher o mais adequado para seus projetos específicos.

  1. Buzzer Ativo: Emite um som quando uma corrente elétrica é aplicada a ele.
    •Aplicações:
    O buzzer ativo é amplamente utilizado em situações em que apenas um único e simples som é necessário, como alertas sonoros em dispositivos eletrônicos, sistemas de segurança ou lembretes em projeto.
  2. Buzzer Passivo: Diferentemente do buzzer ativo, o buzzer passivo possui um circuito interno que é capaz de gerar um tom específico quando uma tensão é aplicada.
    • Aplicações:
    O buzzer ativo é utilizado em projetos que requerem a geração de variados tipos de som, como a reprodução de notas musicais. Para isso, é necessário utilizar uma controladora externa que forneça o sinal adequado para o buzzer passivo produzir diferentes tons.

Mergulhando na Prática

Vamos agora colocar a mão na massa! Então pegue o seu kit, pois estamos prestes a mostrar como utilizar os diferentes tipos de buzzer.

Componentes necessários

• ESP32
• Protoboard
Buzzer Ativo
• Buzzer Passivo
• Resistor de 100 Ω
• Jumper MXM

 

Nesses projetos, iremos conectar ambos os tipos de buzzers ao ESP32 utilizando o mesmo circuito, realizando ajustes apenas no código específico do buzzer em uso na ocasião.

PROJETO 1

Buzzer Ativo: Vamos enviar alertas sonoros a cada segundo, utilizando sua capacidade de produzir som quando alimentado com uma tensão contínua.

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 3 
//                            PROGRAMA 1 : BUZZER ATIVO

const int PINO_BUZZER = 23; // Pino D23 conectado ao buzzer

void setup() {
  pinMode(PINO_BUZZER, OUTPUT); // Define o PINO do buzzer como saída
}

void loop() 
{
  digitalWrite(PINO_BUZZER, HIGH); // Ligar o buzzer
  delay(1000); // Deixa o buzzer ligado por 1 segundo
  digitalWrite(PINO_BUZZER, LOW); // Desligar o buzzer
  delay(1000); // Deixa o buzzer desligado por 1 segundo
}

 

PROJETO 2

Buzzer Passivo: Utilizaremos sua característica de reproduzir melodias para tocar a icônica "Marcha Imperial" de Star Wars, demonstrando como podemos criar efeitos musicais utilizando esse componente.

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 3 
//                            PROGRAMA 2 : BUZZER PASSIVO

const int PINO_BUZZER = 23; // Pino D23 conectado ao buzzer passivo
const int CANAL_PWM = 0;   // Canal PWM utilizado para o buzzer

void setup() 
{
  ledcSetup(CANAL_PWM, 1000, 8); // Configuração do canal PWM (frequência de 1000 Hz, resolução de 8 bits)
  ledcAttachPin(PINO_BUZZER, CANAL_PWM); // Associa o pino do buzzer ao canal PWM
}

void loop() 
{
  // Toca a "Marcha Imperial"
  int melody[] = {
    440, 440, 440, 349, 523, 440, 349, 523, 440,
    659, 659, 659, 698, 523, 784, 740, 698, 659
  };

  int tempo[] = 
  {
    500, 500, 500, 350, 150, 500, 350, 150, 1000,
    500, 500, 500, 350, 150, 500, 350, 150, 1000
  };

  for (int i = 0; i < sizeof(melody) / sizeof(melody[0]); i++) 
  {
    ledcWrite(CANAL_PWM, melody[i]);
    delay(tempo[i] * 1.30); // Pequeno delay para espaçar as notas
    ledcWrite(CANAL_PWM, 0); // Desliga o buzzer ao final de cada nota
    delay(50); // Pequeno delay para evitar cliques entre as notas
  }

  delay(2000); // Aguarda 2 segundos antes de repetir a música
}

//ledc -> utilizada para controlar as portas PWM que são portas onde é possivel variar a corrente enviada para o módulo, permitindo valores intermediários entre 0v e 3.3v.

ENTENDENDO A FUNDO

Arquitetura

No mercado, encontramos uma ampla variedade de buzzers com diferentes tamanhos, cores e potências. Apesar das suas características específicas variarem, todos possuem a mesma funcionalidade essencial: emitir um som específico.
Buzzers são componentes simples, mas têm uma funcionalidade fascinante. Eles são conhecidos como "buzzer piezoelétrico" ou "buzzer passivo". A parte fundamental deum buzzer é um cristal piezoelétrico. Quando uma tensão é aplicada a esse cristal, ele
começa a vibrar em uma frequência específica, criando som.


Frequência de Ressonância: Cada buzzer tem uma frequência de ressonância natural,
que é determinada pelo tamanho e forma do cristal piezoelétrico. Quando você fornece
a tensão correta, o buzzer entra em ressonância e emite som na frequência de
ressonância.
Controle de Som: Com um microcontrolador, você pode controlar a frequência e a
duração dos sons emitidos pelo buzzer. Isso permite criar melodias, sirenes, efeitos
sonoros e muito mais.
Tensão e Polaridade: Os buzzers geralmente operam com baixa tensão (geralmente 3
a 5 volts) e possuem polaridade, o que significa que é importante conectá-los
corretamente para evitar danos. O terminal positivo (anodo) deve ser conectado à
tensão positiva (VCC) e o terminal negativo (catodo) ao terra (GND).
Podemos identificar a polaridade do buzzer através de algumas características:
• Tamanho do conector: O extremo menor representa o lado negativo,
enquanto o maior representa o lado positivo.
• Chanfro (corte): Fica localizado no extremo negativo do buzzer, facilitando a
identificação visual da polaridade.
• Marcação: Geralmente, um símbolo de "+" é utilizado para representar o
extremo positivo do buzzer.

Conclusão

Chegamos ao final de mais uma aula em que exploramos os buzzers e suas aplicações. Utilizamos esses dispositivos em projetos simples, mas isso abre as portas para inúmeras possibilidades criativas e funcionais. Lembre-se de que os buzzers são componentes versáteis e podem ser uma adição valiosa aos seus futuros projetos, oferecendo uma variedade de maneiras de incorporar som e alertas ao seu trabalho. Continuem explorando e experimentando com essa tecnologia sonora emocionante!

Convidamos você a participar ativamente desta comunidade. Deixe seu like, inscreva-se no canal e compartilhe suas dúvidas, conquistas e ideias nos comentários. Sua interação é o que dá vida a este canal. Estamos aqui para aprender juntos e moldar o futuro da tecnologia DIY e IoT. Até a próxima aula!


Led com ESP32 - Curso ESP32 básico

Led com ESP32 - Curso ESP32 básico

Olá, amantes da eletrônica e da inovação! Nesse tutorial vamos dar um passo adiante e explorar as possibilidades dos LEDs, aprendendo sobre sua ampla funcionalidade e aplicações. Além disso, vamos entender as diferenças entre sensores e atuadores, trabalhando com esses dois tipos de dispositivos nesta aula e em todas as seguintes. Preparem-se para mergulhar em novos conceitos e experiências práticas com o fascinante mundo dos LEDs, sensores e atuadores no ESP32.

Lembre-se que esse tutorial faz parte do Curso Esp32 que compõe nosso Kit IoT ESP32 – para Professores e Makers iniciantes

https://www.youtube.com/watch?v=Psgn6KGQmMo

kit robotica educacional com Arduino ESP ou Microbit

Conhecendo o LED

O LED (Light Emitting Diode), ou Diodo Emissor de Luz, é um componente eletrônico semicondutor que emite luz quando uma corrente elétrica passa por ele. O LED é amplamente utilizado em diversas aplicações de iluminação, indicadores visuais e displays.
Características do LED:
• Pequeno tamanho: Os LEDs são dispositivos compactos, tornando-os ideais para aplicações onde o espaço é limitado.
• Baixo consumo de energia: Os LEDs consomem menos energia em comparação com outras fontes de luz, o que os torna eficientes em termos de energia.
• Longa vida útil: Os LEDs possuem uma vida útil muito longa, em média de 50.000 a 100.000 horas, o que reduz a necessidade de substituição frequente.
• Rapida resposta: Os LEDs acendem e apagam rapidamente, tornando-os ideais para aplicações onde é necessária uma resposta instantânea.
• Disponibilidade de cores: LEDs estão disponíveis em diversas cores. Além disso, temos a tecnologia RGB, cuja sigla em inglês significa "Red, Green, Blue" (vermelho, verde, azul), permitindo o controle destas três cores distintas. Essa combinação possibilita a criação de uma vasta variedade de cores em um único componente.
• Baixa tensão de operação: Os LEDs operam com baixas tensões, geralmente em torno de 2 a 3,3 volts, o que permite o uso em sistemas de baixa potência.

Mergulhando na Prática

Vamos agora colocar a mão na massa! Então pegue o seu kit, pois estamos prestes a mostrar como utilizar o LED e o botão em dois projetos.

Componentes necessários

ESP32
Protoboard
Botão
LED (qualquer cor)
Resistor de 100 Ω
Resistor de 10k Ω
Jumper MXM

PROJETO 1
 Para esse projeto, o objetivo é controlar um LED para que ele pisque em um intervalo de tempo específico. Vamos utilizar o ESP32 para criar um código simples que irá ligar e desligar o LED em sequência, criando um efeito de piscar.

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 2 
//                            PROGRAMA 1 : PISCA PISCA


const int PINO_LED = 15; // PINO D15

void setup() {
  pinMode(PINO_LED, OUTPUT); // Define o PINO do LED como saída
}

void loop() {
  digitalWrite(PINO_LED, HIGH); // Liga o LED
  delay(1000); // Espera 1 segundo. * Alterar o valor dessa variavel muda o tempo de duração em MILISEGUNDOS que o led permanece LIGADO.
  digitalWrite(PINO_LED, LOW); // Desliga o LED
  delay(1000); // Espera 1 segundo. * Alterar o valor dessa variavel muda o tempo de duração em MILISEGUNDOS que o led permanece DESLIGADO.
}

//const int -> declara uma variavel apenas uma vez e a partir daquele momento ela se torna fixa.
//int -> por sua vez quando utilizar somente o "int" é declarada uma variavel inteira que a qualquer momento do código pode ser alterada.

 

PROJETO 2

 Em seguida, vamos aprimorar nosso projeto utilizando um botão para ligar e desligar o LED. Com essa nova funcionalidade, você poderá pressionar o botão para alternar o estado do LED, ligando-o ou desligando-o conforme sua preferência. Essa interação simples adicionará um controle manual ao projeto e permitirá que você experimente diferentes estados do LED. 

//                                VIDA DE SILICIO
//                                    KIT ESP32
//                                      AULA 2 
//                            PROGRAMA 2 : CONTROLE DO LED

const int PINO_LED = 15;   // Pino D15 conectado ao LED
const int PINO_BOTAO = 2;  // Pino D2 conectado ao botão
bool estadoAnteriorBotao = HIGH; // Variável para armazenar o estado anterior do botão
bool estadoLed = false;    // Variável para armazenar o estado do LED

void setup() {
  pinMode(PINO_LED, OUTPUT);     // Define o PINO do LED como saída
  pinMode(PINO_BOTAO, INPUT_PULLUP); // Define o PINO do botão como entrada com resistor de pull-up interno
}

void loop() {
  int botaoPressionado = digitalRead(PINO_BOTAO); // Lê o estado do botão

  // Verifica se o botão foi pressionado (LOW é pressionado devido ao resistor de pull-up)
  if (botaoPressionado == LOW && estadoAnteriorBotao == HIGH) {
    estadoLed = !estadoLed;// Inverte o estado do LED
    digitalWrite(PINO_LED, estadoLed); // Liga ou desliga o LED conforme o estado atual
  }

  estadoAnteriorBotao = botaoPressionado; // Atualiza o estado anterior do botão
}

//bool -> abreviação de "boolean" que refere-se ao estado da variavel em questão seja alto/baixo ou verdadeiro/falso.
//if/else -> "IF" refere-se a uma condição "SE" tal ação acontecer faça isso. Por sua vez "ELSE" realizará no caso de "SE NÃO" acontecer a ação esperada faça aquilo.


ENTENDENDO A FUNDO

ARQUITETURA

Os LEDs são componentes eletrônicos que possuem polaridade, o que significa que devem ser conectados de forma correta para funcionarem adequadamente.
Entender sua polaridade é crucial para utilizá-los eficazmente em projetos eletrônicos.
Existem várias maneiras de identificar as conexões positivas e negativas de um LED:
1. Chanfros (Corte): Muitos LEDs possuem um pequeno chanfro ou corte em sua extremidade, indicando o lado negativo (-). Esse detalhe físico é uma dica visual importante para determinar a polaridade do LED.
2. Diferença entre os Pinos: Em alguns LEDs, a diferença entre os pinos é uma pista para identificar a polaridade. Normalmente, o pino maior representa o lado positivo (+), enquanto o pino menor representa o lado negativo (-). Esta é outra maneira de
garantir a conexão correta.

Além disso, entender a eletrônica interna de um LED pode ser útil. Um LED é um diodo semicondutor que emite luz quando uma corrente elétrica flui através dele. A emissão de luz ocorre quando elétrons se recombinam com lacunas na estrutura do
material semicondutor do LED. Isso libera energia na forma de fótons de luz visível. Ao conectar um LED corretamente, permitindo que a corrente flua na direção correta (do ânodo para o cátodo), ele emitirá luz de forma eficiente. Portanto, prestar atenção à polaridade é fundamental ao usar LEDs em projetos para garantir seu funcionamento adequado e evitar danos aos componentes.
A compreensão desses aspectos mais profundos sobre LEDs pode ser valiosa ao projetar circuitos mais avançados e ao solucionar problemas em eletrônica.

DIFERENÇA ENTRE SENSOR E ATUADOR

No caso deste tutorial, utilizamos o LED como ATUADOR e o botão como SENSOR. Mas você sabe o que isso significa? Por isso, é essencial explicar a diferença entre duas categorias fundamentais: sensores e atuadores. Esses elementos desempenham papéis distintos nos sistemas, e compreender suas funções é crucial para avançarmos em nosso aprendizado.
Sensor: Um sensor é um dispositivo que atua como um "sentido" para o sistema, captando informações do ambiente físico ao seu redor. Ele coleta dados como temperatura, luz, pressão ou movimento e converte essas informações em sinais elétricos ou digitais para que o sistema possa processá-las e tomar decisões com base nesses dados.
Atuador: Por outro lado, um atuador age como um "músculo" do sistema, respondendo aos sinais ou comandos recebidos para realizar ações físicas. Ele recebe os sinais elétricos ou digitais do sistema e converte-os em movimento mecânico, força, ou alguma outra forma de energia para executar uma tarefa específica.

Conclusão

E assim chegamos ao final de mais uma aula, onde aprendemos a controlar um LED para que ele pisque em um intervalo de tempo específico. Além disso, aprimoramos nosso projeto adicionando um botão para ligar e desligar o LED, proporcionando uma experiência interativa. Continuem explorando e praticando, pois a cada aula, novas descobertas aguardam por vocês.

Convidamos você a participar ativamente desta comunidade. Deixe seu like, inscreva-se no canal e compartilhe suas dúvidas, conquistas e ideias nos comentários. Sua interação é o que dá vida a este canal. Estamos aqui para aprender juntos e moldar o futuro da tecnologia DIY e IoT. Até a próxima aula!


ESP32 - Utilizando o Brown Out Detector (BOD) para quedas de alimentação

ESP32 - Utilizando o Brown Out Detector (BOD) para quedas de alimentação

Em muitos projetos precisamos gerenciar, com cautela, a alimentação do nosso sistema, evitando mal funcionamento ou até perda de dados na RAM. Podemos, por exemplo, entrar em Deep Sleep ou salvar dados presentes na RAM numa memória não-volátil quando detectamos uma queda de alimentação, assim evitando a perda destes dados, é ai que entra o Brown Out Detector (BOD). O ESP32 conta com um BOD internamente com níveis de tensões e modos de operações configuráveis, nos permitindo tomar atitudes em casos de queda ou má alimentação.

[toc]

kit arduino robótica educacional

O que é Brown Out Detector (BOD) ?

Brown Out Detector (BOD), é um hardware interno ou externo que detecta problemas na alimentação de um sistema. Muito dos microcontroladores atuais tem este item disponível, inclusive o ESP32.

Há algumas formas que o BOD pode funcionar e você deve analisar especificamente para o seu microcontrolador, entretanto, tudo que será explicado abaixo é relacionado ao ESP32, que pode mudar levemente para algum outro microcontrolador.

Brown Out Detector (BOD)
Brown Out Detector (BOD)

O BOD presente no ESP32 gera uma interrupção na CPU, nos permitindo tratar este "problema de alimentação", como salvar variáveis da RAM em memória não-volátil, ligar/desligar saídas, ativar sistemas de emergência com SCR, etc. Também permite a configuração de alguns parâmetros para melhor aproveitamento do mesmo, veja uma pequena lista de funcionalidades:

  • Tensão de trigger configurável com precisão de +- 50mV: 2.43, 2.48, 2.58, 2.62, 2.67, 2.7, 2.77, 2.8V.
  • Desativação do circuito RF (WiFi/Bluetooth) e/ou FLASH interna, afim de aumentar o precioso tempo restante com energia disponível.

O tempo de funcionamento que será citado abaixo, é imaginando um caso em que a alimentação do sistema é completamente removida. Mesmo assim, o BOD ainda tem velocidade suficiente para gerar a interrupção e a CPU processar alguns dados antes que a tensão fique abaixo do limite absoluto (2.3V) quando o ESP32 é desligado. O WROOM é recomendado para funcionar no mínimo com 2.7V, então é interessante configurar o nível de trigger neste valor ou acima.

Se nós queremos obter um maior tempo de funcionamento, utilizaremos o nível de trigger mais alto (2.8V), mas se a alimentação no ESP32 for instável, isso pode gerar falsos alarmes até mesmo com WiFi ativo, uma vez que os picos de consumo pode fazer a tensão cair a este nível. Para contornar este problema, basta melhorar seu circuito de alimentação ou deixar o nível de trigger mais baixo como 2.43V (o que reduziria o tempo de funcionamento). Vamos observar tudo isso melhor na prática!

Mãos à obra - BOD

O código foi feito na Arduino IDE, entretanto, funciona da mesma forma na IDF, bastando remove os itens do Arduino como DigitalWrite().

Componentes necessários

1x Módulo ESP32

Programando

Você também pode obter o código (ou arquivo .ino) no repositório do GitHub: https://github.com/urbanze/vds_esp32_bod

extern "C"
{
    #include <driver/rtc_cntl.h>
}

#define LED 2

void setup()
{
    pinMode(LED, OUTPUT);
    init_bod();
}

void loop()
{
}

void IRAM_ATTR bod_isr(void*z)
{
    //Liga o LED
    digitalWrite(LED, 1);

    //Mostra no Serial Monitor. Voce nao conseguira ler nada se remover o cabo USB
    ets_printf("\nBOD Trigged (2.8V)\n");

    //Aborta a execucao, forcando o reinicio
    abort();
}

void init_bod()
{
    uint32_t value = 0;
    value |= (1<<30);//Ativa o BOD
    value |= (2<<16);//Ciclos de espera, precisa ser >1 & <1024
    value |= (1<<15);//Desativa o RF
    value |= (7<<27);//Nivel de trigger (2.8V). Para 2.43V ficaria (0<<27)

    //Configura o registrador do BOD
    (*(volatile uint32_t *)(0x3FF480D4)) |= value;

    //Configura a ISR (bod_isr) pro BOD
    rtc_isr_register(bod_isr, NULL, (1<<7));

    //Habilita a interrupcao do BOD
    (*(volatile uint32_t *)(0x3FF4803C)) |= (1<<7);
}

Colocando para funcionar

Para conseguir gravar um GIF, foi adicionado um capacitor na alimentação do ESP32, fazendo com que seu tempo de funcionamento dure mais e possamos capturar no GIF.

Ao remover o cabo de alimentação do computador, a tensão começa a cair e logo que chega em 2.8V, o BOD entra em ação, ativando o LED para que possamos visualizar.

Figura 2 - BOD atuando

Entendendo a fundo

Podemos observar o funcionamento de um BOD neste curto vídeo da Microchip, que mantém o microcontrolador em reset enquanto a tensão não é estabilizada acima do definido. 

https://www.youtube.com/watch?v=G90Xd2ssxog

 

O BOD do ESP32 não funciona desta maneira, infelizmente. Apenas reinicia e é logo iniciado novamente (o que pode gerar alguns raros problemas) no exemplo deste código. O ideal é sempre utilizar um BOD externo.

Apesar da rápida interrupção quando é detectado a tensão baixa, provavelmente você não conseguirá salvar dados na flash do ESP32 com a maioria das API's (bibliotecas) nativas (Arduino ou ESP-IDF) por não serem tão rápidas assim. Talvez utilizando as API's de Low-Level (spi_flash) ou até outras memórias externas seja possível.

Considerações finais

O BOD é muito importante em diversos projetos onde necessitamos monitorar a alimentação presente no sistema, afim de conseguir tomar atitudes com dados voláteis e até acionar outros sistemas como alarmes e etc. O BOD interno não substitui um externo (dedicado), sendo indicado em projetos mais "sérios".

Referências

ESP32 - Technical Reference Manual

 

 


ESP32 - Utilizando o RTC interno para datas

ESP32 - Utilizando o RTC interno do ESP32 

Se você já tentou fazer algum acionamento por datas e horários específicos, já deve conhecer os RTC's (Real Time Clock), que são na maioria dos casos, placas externas e dedicadas a esta função. Manter uma placa dedicada para este propósito pode ser necessário quando a precisão deve ser alta e atrasos/avanços em datas e horas são indesejáveis (Clock Drift), mas em muitos casos (principalmente com internet disponível) você pode utilizar o RTC interno do seu microcontrolador (se disponível, como no caso do ESP32) para baratear produtos. Neste tutorial, nós vamos aprender a utilizar o RTC interno do ESP32 para manter a nossa data atualizada.

kit arduino robótica educacional

[toc]

O que é um RTC ?

RTC (Real Time Clock, Relógio de Tempo Real) é um "sistema" utilizado para manter datas atualizadas e "seguras" em caso de quedas de energia (na maioria do casos). O ESP32 tem um RTC interno que faz esse trabalho de manter a data atualizada, porém assim como os outros RTC externos que se compram com Arduino, ele também precisa de uma bateria dedicada em caso de queda da alimentação, pois, caso contrário, a hora irá se perder ou congelar. Para manter a data atualizada e de fácil gerenciamento pelo MCU, vamos utilizar a data no formato Unix time, que são os segundos corridos desde 01/01/1970.

 

  • Depois da data configurada no código, o ESP32 manterá a data atualizada automaticamente mesmo durante DEEP-SLEEP, então você poderá lê-la a qualquer momento que estará atualizada pro momento atual.
  • O clock do interno do RTC no ESP32 tem 5% de variação (drift), então você pode perceber a data atrasada ou adiantada caso utilize o sistema por longos períodos. Para corrigir isso, basta atualizar a data de tempos em tempos com NTP por exemplo, ou até aplicar algoritmos de correção do drift.
ESP32 Block (RTC)

O que é Unix time ?

Unix time é a contagem de segundos desde 01/01/1970 que os sistemas computacionais usam para guardar datas em memórias, efetuar operações como IF's e também mostrar as informações de data e hora ao usuário formatadas, claro. Foi esse mesmo Unix time que foi responsável pelo famoso "Bug do milênio" nos anos 2000, que fez alguns computadores voltarem para 01/01/1970 por conta da variável utilizada sofrer de Overflow.

No momento que escrevo esse post, o Unix time esta com o valor de 1551355200 segundos desde 01/01/1970. Se você quer pegar o Unix time de agora ou uma data especifica, consulte: https://www.unixtimestamp.com/


Mãos à obra - Utilizando o RTC do ESP32

Componentes necessários

Programando

Foi utilizada a ESP-IDF, mas funciona perfeitamente na Arduino IDE bastando trocar o void app_main() pelo void setup() e adicionar o void loop() ao fim do código, como é feito na Arduino IDE.

Se você ainda não conhece ou instalou a ESP-IDF (local de programação nativo do ESP32), veja nosso artigo clicando AQUI.

A biblioteca responsável pelas funções de tempo (time.h) já vem baixada por padrão nos arquivos do ESP32, basta apenas inclui-la.

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_system.h>
#include <time.h>
#include <sys/time.h>

struct tm data;//Cria a estrutura que contem as informacoes da data.


void app_main()
{
	timeval tv;//Cria a estrutura temporaria para funcao abaixo.
	tv.tv_sec = 1551355200;//Atribui minha data atual. Voce pode usar o NTP para isso ou o site citado no artigo!
	settimeofday(&tv, NULL);//Configura o RTC para manter a data atribuida atualizada.
	



	while (1)
	{
		vTaskDelay(pdMS_TO_TICKS(1000));//Espera 1 seg


		time_t tt = time(NULL);//Obtem o tempo atual em segundos. Utilize isso sempre que precisar obter o tempo atual
		data = *gmtime(&tt);//Converte o tempo atual e atribui na estrutura

		
		char data_formatada[64];
		strftime(data_formatada, 64, "%d/%m/%Y %H:%M:%S", &data);//Cria uma String formatada da estrutura "data"


		printf("\nUnix Time: %d\n", int32_t(tt));//Mostra na Serial o Unix time
		printf("Data formatada: %s\n", data_formatada);//Mostra na Serial a data formatada




		/*
			Com o Unix time, podemos facilmente controlar acoes do MCU por data, visto que utilizaremos os segundos
			e sao faceis de usar em IFs

			Voce pode criar uma estrutura com a data desejada e depois converter para segundos (inverso do que foi feito acima)
			caso deseje trabalhar para atuar em certas datas e horarios

			No exemplo abaixo, o MCU ira printar o texto **APENAS** na data e horario (28/02/2019 12:00:05) ate (28/02/2019 12:00:07)
		*/
		if (tt >= 1551355205 && tt < 1551355208)//Use sua data atual, em segundos, para testar o acionamento por datas e horarios
		{
			printf("Acionando carga durante 3 segundos...\n");
		}
	}

	
}

 

Colocando para funcionar

Testando o código

Entendendo a fundo

struct tm data;
struct tm
{
   tm_sec;         /* seconds,  range 0 to 59          */
   tm_min;         /* minutes, range 0 to 59           */
   tm_hour;        /* hours, range 0 to 23             */
   tm_mday;        /* day of the month, range 1 to 31  */
   tm_mon;         /* month, range 0 to 11             */
   tm_year;        /* The number of years since 1900   */
   tm_wday;        /* day of the week, range 0 to 6    */
   tm_yday;        /* day in the year, range 0 to 365  */
   tm_isdst;       /* daylight saving time             */
};

A estrutura "data" nos permite obter os dados individuais da data atual, como por exemplo mês, dia, hora, segundo, ano, etc.

Se você deseja obter apenas a hora atual, basta utilizar data.tm_hour

 

 

strftime(data_formatada, 64, "%d/%m/%Y %H:%M:%S", &data);

A função strftime() formata a data atual (da estrutura indicada) num formato que você deseja. Caso você queira alterar o formato da data, veja mais detalhes clicando AQUI


Considerações finais 

Unix time é de enorme importância na computação por facilitar extremamente as operações por datas e horários, já que podemos trabalhar facilmente com os segundos dentro de IF's e etc. Continue praticando e olhe a referência abaixo para mais detalhes sobre a biblioteca time.h utilizada.


Referências

https://en.wikipedia.org/wiki/Unix_time

https://pt.wikipedia.org/wiki/Problema_do_ano_2000

https://www.tutorialspoint.com/c_standard_library/time_h.htm


Primeiros passos com Firebase - ESP8266

Primeiros passos com Firebase - ESP8266

Neste tutorial vamos fazer um circuito que permita observar a temperatura e umidade de um sensor via internet, mostrando como podemos receber sinais de um sensor DHT22 que chegam a um ESP8266 e enviá-los pela internet para uma plataforma Firebase, fazendo uma aplicação bem simples de Internet das Coisas, a famosa IoT , do inglês Internet of Things.

 

kit robotica educacional com Arduino ESP ou Microbit

O que é o Firebase?

O Firebase, produto oferecido atualmente pela Google e utilizado por empresas em todo o mundo, que integra um conjunto de tecnologias disponíveis em diversas linguagens, entregando serviços como:

  • Banco de dados armazenados em nuvem e sincronizados em tempo real;
  • Autenticação de usuários, inclusive por meio de login em provedores como Google e Facebook;
  • Facilitação na hospedagem web;
  • Pode ser usado para testes e manutenção durante o desenvolvimento dos seus apps, assim como o monitoramento dos mesmos.

Com as muitas ferramentas e serviços disponíveis pela plataforma, o desenvolvimento de apps, se torna mais ágil e problemas comuns são resolvidos mais facilmente.

A possibilidade de criar um único SDK contendo APIs do Firebase para uso tanto em Android, como também no iOS e na web é uma das facilidades oferecidas a desenvolvedores, assim como a implementação de bate-papo na aplicação e a viabilidade de testes AB, melhorando a experiência do usuário.

Há recursos também para expansão e envolvimento do público com a sua aplicação, tal como o conhecido Google Analytics, Slack e PlayStore, por exemplo.

No campo da IoT, quando tem-se objetos e aparelhos físicos conectados e em comunicação por meio da internet, também há espaço para o Firebase. Combinados os serviços oferecidos com microcontroladores, como o Arduino, são inúmeras as possibilidades de aplicações, seja em monitoramento de sensores para telemetria, ou em vertíveis (wearables), tecnologias que podem ser vestidas, como relógios inteligentes, por exemplo.

O que é IoT?

IoT, que vem do inglês "Internet of Things", refere-se à conexão da Internet com objetos do dia a dia, permitindo que estes coletem e troquem dados entre si. Basicamente, trata-se de dispositivos que, anteriormente, não tinham capacidade de conexão com a internet, como geladeiras, lâmpadas, relógios, agora estarem conectados à web para coletar e trocar dados, otimizando e automatizando processos.

O que é SDK?

SDK, que é a sigla para "Software Development Kit", refere-se a um conjunto de ferramentas de software que permitem aos desenvolvedores criar aplicações para uma determinada plataforma ou framework específico. O SDK fornece uma série de bibliotecas, guias, documentações, código e outras ferramentas para facilitar o desenvolvimento.

O que é API?

API, que significa "Application Programming Interface", é um conjunto de regras e protocolos que permite a comunicação entre diferentes software. Pode ser entendida como uma ponte que permite que diferentes programas de software se comuniquem entre si. As APIs são essenciais para permitir a integração de sistemas, permitindo que aplicativos e plataformas trabalhem em conjunto.

O que é um banco de dados?

Um banco de dados é um sistema estruturado de armazenamento que permite a coleta, organização, armazenamento e recuperação de dados. Estes dados podem ser de diversos tipos, como textos, números, imagens, entre outros. Os bancos de dados são fundamentais para sistemas e aplicações, pois fornecem uma maneira organizada de gerenciar grandes volumes de informações.

O que são Vestíveis ou wearables?

Vestíveis, ou "wearables", são tecnologias que podem ser usadas como peças de vestuário ou acessórios, como relógios, pulseiras, óculos, entre outros. Estes dispositivos normalmente possuem sensores e estão conectados à internet, coletando e fornecendo dados em tempo real para os usuários. Exemplos populares incluem relógios inteligentes, óculos de realidade aumentada e fones de ouvido inteligentes.


Mãos à Obra - Usando o Firebase em projetos de IoT

Vamos explorar algumas funcionalidades do Firebase com um exemplo prático de um circuito teste, entendendo o código necessário para um projeto simples!

Neste tutorial vamos fazer um circuito que permita observar a temperatura e umidade de um sensor via internet. Utilizaremos um DHT22, que age como um sensor de temperatura e umidade, porém você pode aplicar a outros sensores para obter diferentes informação que você deseja obter podem ser diferentes.

Componentes necessários

Montando o projeto

A montagem deve ser feita seguindo o esquema:

Ilustração do circuito e sua montagem

Olhando o DHT de frente, para a parte onde há aberturas e é feita a leitura, usa-se o pino 1 (mais à esquerda) para alimentação e o pino 4 (mais à direita) como terra.  Eles devem ser ligados, respectivamente, ao Vin e ao Gnd do ESP. Ainda seguindo essa lógica, o pino 2 do DHT deve ser ligado a uma porta digital do ESP que, no caso, foi a porta digital 5 (pino D5 do ESP). O pino 2 também deve ser ligado à alimentação (Vin) com um resistor de 10K entre eles.

Veja como ficou no nosso projeto:

Criando um banco de dados na Firebase

Entre os serviços oferecidos pelo Firebase está o Realtime Database que, como o próprio nome já diz, é um banco de dados que armazena e sincroniza dados em tempo real. Estruturalmente, ele é um banco NoSQL hospedado em nuvem, o que nos livra da necessidade de configurar servidores. Outra grande vantagem é a facilidade de integrá-lo em aplicações, seja em aplicativos iOS, Android e até Web, como é o nosso caso.

Para criar o banco:

a) Acesse a console em https://firebase.google.com  e faça login com uma conta Google.

b) Na próxima tela, adicione um novo projeto.

c) No menu à esquerda, escolha Database, depois Realtime Database e coloque modo público. Dessa forma você terá o banco e a URL que será usada para acessá-lo.

d) O último passo é o segredo do banco, uma espécie de senha. No menu lateral, é preciso clicar na engrenagem, ao lado de ‘Project Overview’ > Configurações do Projeto > Contas de serviço > Chaves secretas do banco de dados. Clicando em mostrar, o segredo pode ser obtido.

Programando

- Configurando a Arduino IDE para NodeMCU

Acesse o caminho Arquivo > Preferências e insira a URL http://arduino.esp8266.com/stable/package_esp8266com_index.json, como descrito nas fotos abaixo.

Feito isso, clique em OK e as placas esp8266 já estarão disponíveis no gerenciador de placas pelo caminho Ferramentas > Placa > Gerenciador de Placas > Instalar ‘esp8266 by ESP8266 Community’.

- Adicionando bibliotecas na Arduino IDE:

Biblioteca do Firebase

Para instalar a biblioteca do Firebase, primeiro é preciso baixá-la do GitHub: (https://github.com/googlesamples/firebase-arduino/archive/master.zip). Depois, é só acessar a Arduino IDE, adicioná-la seguindo o caminho Sketch > Incluir Biblioteca > Adicionar Biblioteca .ZIP e escolher o arquivo que foi baixado.

Biblioteca do DHT

O DTH é uma família de sensores de temperatura e umidade. O modelo que vamos utilizar aqui é o DHT22, que permite distinguir temperaturas na amplitude de -40°C até 80°C. É preciso instalar duas bibliotecas: a ‘Common sensor library’ (https://github.com/adafruit/Adafruit_Sensor) e a ‘DHT Sensor Library’ (https://github.com/adafruit/DHT-sensor-library), e incluí-las na IDE do arduino, assim como feito anteriormente.

- Escrevendo o código

O código do ESP precisa de certas alterações:

  • FIREBASE_HOST: forneça a URL do banco criado anteriormente.
  • FIREBASE_AUTH: forneça o Segredo do seu banco no Firebase.
  • WIFI_SSID e WIFI_PASSWORD: dados da sua rede WiFi.

Uma prática comum na programação são os comentários. No código abaixo, os comentários (indicados por "//") explicitam o significado e funcionalidade de cada trecho.

// Inclusão das bibliotecas necessárias
#include <DHT.h>
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>
#include <Ticker.h>

// Parâmetros do banco
#define FIREBASE_HOST "URL_do_banco"
#define FIREBASE_AUTH "Segredo_do_banco"

//Parâmetros da rede
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "Password"
#define DHT_PIN D5
#define DHTTYPE DHT22

// Intervalos de publicação. Configurado a cada 30 segundos
#define PUBLISH_INTERVAL 1000*30
DHT dht(DHT_PIN, DHTTYPE);
Ticker ticker;
bool publishNewState = true;

void publish(){
  publishNewState = true;
}

void setupPins(){
  dht.begin(); 
}

void setupWifi(){
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("connecting");
  while (WiFi.status() != WL_CONNECTED) {
	Serial.print(".");
	delay(500);
  }

  Serial.println();
  Serial.print("connected: ");
  Serial.println(WiFi.localIP());
}

void setupFirebase(){
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
}

void setup() {
  Serial.begin(115200);
  setupPins();
  setupWifi();	
  setupFirebase();
  // Registra o ticker para publicar de tempos em tempos
  ticker.attach_ms(PUBLISH_INTERVAL, publish);
}

void loop() {
  // Apenas publique quando passar o tempo determinado
  if(publishNewState){
	Serial.println("Publish new State");
	// Obtem os dados do sensor DHT
	float humidity = dht.readHumidity();
	float temperature = dht.readTemperature();
	if(!isnan(humidity) && !isnan(temperature)){
  	// Manda para o firebase
  	Firebase.pushFloat("temperature", temperature);
  	Firebase.pushFloat("humidity", humidity);	
  	publishNewState = false;
	}else{
  	Serial.println("Error Publishing");
	}
  }
 
  delay(200);
}

Pelo Serial Monitor da Arduino IDE será possível ver a conexão com a internet, o endereço IP associado e as publicações de valores no banco. Cada ‘Publish new state’ é uma nova instância de dado gerada e armazenada no Firebase. Esses dados são gerados de acordo com a constante PUBLISH_INTERVAL e o valor é passado em milisegundos. No nosso exemplo, para cada 30 segundos o valor é de 1000*30.

Na console do firebase podem ser vistos os valores que estão sendo lidos:

 


1, 2, 3, Testando...

Vamos criar um site simples, utilizando as tecnologias web padrão HTML5, CSS3 e Javacript e hospedando-o diretamente no Firebase Hosting, outro serviço também muito lindo oferecido pelo Firebase.

 

- Ferramentas e configurações necessárias

Para fazer deploy da aplicação no Firebaseprecisamos instalar o firebase-tools, que é uma ferramenta de linha de comando para gerenciar o banco de dados e hosting de aplicações dentro da própria plataforma. Essa ferramenta é baseada em NodeJS, então precisamos da ferramenta instalada. Baixe o NodeJS no site oficial. Junto também será instalado o gerenciador de pacotes — NPM (similar ao PIP para Python).

Feito isso, é só rodar o comando no terminal: npm install -g firebase-tools

Ao final da instalação rode o comando a seguir e coloque suas credenciais do Firebase:

firebase login

 

- Programação

Crie uma pasta para o seu projeto e utilize o seguinte comando dentro da pasta:

firebase init

Assim, você estará vinculando a pasta ao projeto criado no console do Firebase, então escolha corretamente o projeto criado anteriormente. Uma pasta public será criada, onde ficarão os arquivos que podem ser hospedados no Firebase e acessados na web e também alguns arquivos de configuração do próprio projeto.

Há ainda um servidor embutido no firebase-tools. Dessa forma, estando na pasta, você também pode rodar firebase serve, para iniciar um servidor web na pasta public, na porta 5000 por padrão.

Usando a IDE da sua preferência, utilize o código de exemplo da aplicação que pode ser encontrado nesse link (app.js e o front-end em index.html). Para adequar a aplicação ao seu projeto no Firebase, deve-se alterar o começo do arquivo app.js, com as configurações do console do projeto no Firebase, seguindo os passos:

  1. Clique em Overview no menu lateral
  2. Clique em “Adicionar o Firebase ao seu aplicativo da Web”
  3. Copie o trecho dentro da segunda tag <script> e substitua pelo código correspondente no arquivo app.js

Feito isso, é só dar deploy da aplicação no hosting do Firebase. Rode o comando firebase deploy, assim você vai enviar os arquivos da pasta public pra lá e será mostrado um link para que você acesse sua aplicação online.

A aplicação deve se parecer com isso:


Considerações finais

Sobreviveu?

Simmm, acabou! Tudo certo até aqui? Finalizado este tutorial, você tem uma aplicação web que une um sensor a serviços do Firebase, contando com dados em tempo real e guardados em nuvem, ou seja, você tem uma aplicação de IoT. Esperamos que você tenha gostado e, caso tenha usado um sensor diferente, tenha sugestões, críticas ou elogios, não deixe de comentar abaixo (:


Lendo sensores analógicos em Deep Sleep com ULP - ESP32

Leitura de sensores analógicos pelo ADC com ULP

Neste tutorial, aprenderemos a ler um sensor analógico através do ADC no ESP32 em Deep Sleep, utilizando o ULP. Esse método de leitura, permite uma economia de bateria gigantesca, já que não precisamos acordar o microcontrolador para efetuar a leitura, situação na qual o gasto é bem maior do que quando mesmo procedimento é feito pelo ULP.

Figura 1 - ULP.

[toc]

kit robotica educacional com Arduino ESP ou Microbit

Por que utilizar?

Imagine que em seu projeto portátil, é preciso ler o sensor de temperatura a cada 30 segundos e para isso, logicamente, precisamos acordar o microcontrolador para efetuar essa tarefa, entretanto, o consumo do ESP32 nesse caso seria de 40mA apenas para ler o sensor. Com o ULP, podemos fazer essa leitura em Deep Sleep e o consumo enquanto o ULP está funcionando não passaria de 150uA, com uma média de consumo dependendo do duty cycle do ULP. Com isso, economizaríamos nesse caso de 150uA (100% duty cycle), aproximadamente 270x mais bateria do que se acordássemos o microcontrolador para essa mesma tarefa.

É fácil perceber o aumento incrível na duração da bateria que poderia ser obtido apenas ao usar o ULP para ler o sensor, as aplicações desse guerreiro são muito grandes, mas o foco é para Sleep.

Se você ainda não conhece o ULP, clique aqui para ver a introdução sobre este incrível coprocessador de baixo consumo presente no ESP32.


Mãos a obra - Lendo um sensor de temperatura em Deep Sleep

Componentes necessários

Códigos do projeto

- Main code (C ou C++), responsável pela programação do ESP32 em si.

#include <C:/msys32/ESP32/ESP32/components/arduino/cores/esp32/Arduino.h>
#include <C:/msys32/ESP32/esp-idf/components/driver/include/driver/rtc_io.h>
#include <C:/msys32/ESP32/esp-idf/components/driver/include/driver/adc.h>
#include <C:/msys32/ESP32/esp-idf/components/ulp/ulp.c>
#include <C:/msys32/ESP32/ESP32/build/main/ulp_main.h>
extern "C"
{
#include <C:/msys32/ESP32/esp-idf/components/esp32/include/esp_clk.h>
}
//Pode ser preciso arrumar os diretorios das bibliotecas
//Pode ser preciso remover o "extern 'C'{}" e definir a biblioteca fora dele, alguns usuarios relatam erro sem o uso do extern

extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
void ulp();


extern "C" void app_main()
{
	initArduino();//inicia configuracoes do arduino, caso nao use o Arduino component, remova essa linha
	pinMode(2, OUTPUT);

	if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_ULP)//se o wakeup for por causa do ULP, tomara alguma atitude
	{
		digitalWrite(2, 1);
		delay(500);
		digitalWrite(2, 0);
	}
	else//se nao, iniciara o ULP
	{
		ulp();//configura e inicializa o ulp
	}
	

	esp_sleep_enable_ulp_wakeup();//habilita o wakeup pelo ULP
	esp_deep_sleep_start();//entra em deep sleep eterno
}




void ulp()
{
	adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_11db);
	adc1_config_width(ADC_WIDTH_12Bit);
	adc1_ulp_enable();
	//configura o ADC1 #4 (GPIO32) para 3.3V 12bit e atribui o uso ao ULP
	
	ulp_set_wakeup_period(0, 10000000);//ativa o timer de wakeup do ULP apos cada HALT para 10seg

	ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));//carrega os arquivos
	ulp_run((&ulp_main - RTC_SLOW_MEM) / sizeof(uint32_t));//inicia o ULP
}

- ULP code (Assembly .S), responsável pela programação do ULP em si.

#include "soc/soc_ulp.h"
#include "soc/rtc_io_reg.h"
#include "soc/sens_reg.h"
#include "soc/rtc_cntl_reg.h"


.bss//secao das variaveis


.text//secao do codigo


	.global main
	main:

		move r0, 0//r0 = 0
		move r1, 0//r1 = 0
		stage_rst//stage_cnt = 0

		leitura:
			stage_inc 1//stage_cnt++
			adc r1, 0, 4+1//r1 = leitura ADC GPIO32
			add r0, r0, r1//r0 = r0+r1
			jumps leitura, 4, lt//loop responsavel pelas leituras, equivale a um FOR()

		rsh r0, r0, 2//calcula a media das 4 leituras r0 = r0/4
		jumpr wakeup, 496, ge//se a media da leitura que esta em r0 for maior ou igual que 496 (40 graus celsius), acorda o mcu
		halt//coloca o ULP em sleep e ativa o timer de wakeup (definido com 10 segundos no main code)

	wakeup:
		wake//acorda o mcu
		halt

Entendendo a fundo

Software

leitura:
			stage_inc 1
			adc r1, 0, 4+1
			add r0, r0, r1
			jumps leitura, 4, lt

		rsh r0, r0, 2
		jumpr wakeup, 496, ge
		halt

A parte interessante e diferente do código é justamente a leitura do canal ADC, nós poderíamos fazer mais simples sem utilizar uma estrutura de repetição FOR(), entretanto, é sempre interessante fazer uma média de leituras (inclusive com delay's) para evitar ruídos e coisas do tipo. Já ensinamos a fazer o laço FOR() no tutorial introdutório do ULP.

  1. É feito a leitura do canal ADC no GPIO32 4x e a cada leitura, o valor é somado no registrador R0.
  2. Após as 4 leituras precisamos tirar a média entre eles, entretanto, não há mnemônicos simples para divisão como "DIV". Usaremos os operadores de BitWise (RSH - Right Shift Bit) para dividir o valor por 4. Por causa da divisão facilitada com o RSH na base 2 (2, 4, 8, 16...), também faremos uma quantidade de leituras na base 2.

Não se esqueça de conferir o Set de Instruções do ULP nas referências em caso de dúvidas.

-Mnemônico ADC

adc r1, 0, 4+1

Efetua a leitura do ADC no GPIO32 e atribui o valor ao registrador R1.

O segundo e terceiro operador (parâmetro) deste mnemônico se refere a tabela abaixo, onde:

Segundo operador: Controlador ADC (ADC1 = 0 ou ADC2 = 1). Usamos "0" pois o GPIO32 faz parte do ADC1.

Terceiro operador: MUX+1. O GPIO32 esta descrito como "...CH4", logo foi usado seu canal+1 (4+1).

Figura 2 - Pinagem MUX do ADC.

-Mnemônico RSH

rsh r0, r0, 2

O Right Shift Bit foi usado para calcular a média das 4 leituras. Lembre-se que os valores decimais (após a vírgula) são excluídos, restando apenas os inteiros.

-Mnemônico JUMPR

jumpr wakeup, 496, ge

Esse é o nosso "IF a moda antiga", que pula para a label "wakeup" se o valor do ADC for maior ou igual que 496. Ocasionando no Wake up do ESP32 pelo ULP.

Pelo fato de operações aritméticas não serem tão simples neste Assembly do ULP, em vez da condicional (jumpr) que faz o wake up do ESP32 usar valores como 32°C, onde é preciso efetuar varias contas, usaremos o valor direto do ADC que economiza processamento e tempo. O valor 496 no ADC com o LM35 equivale a 40°C .

Mais informações sobre o LM35 podem ser vistas clicando aqui.


Considerações finais

Mesmo que as aplicações do ULP estejam voltadas a Sleep, podemos usa-lo até com o ESP32 ligado, para por exemplo ler o canal ADC enquanto o ESP32 faz outra tarefa em que não se possa "perder tempo" lendo os lentos canais de ADC. Também é possível criar funções ISR para criar interrupções entre ULP e Main Core, deixando a brincadeira em um nível muito mais sério e interessante.


Desafios

O desafio desta vez é criar a rotina de interrupção citada acima (ISR) para uma comunicação extremamente rápida e eficiente entre ULP e Main Core. Você pode procurar no datasheet sobre o registrador (bit) que o comando WAKE do ULP ativa quando o ESP32 não esta em Sleep e criar a ISR.

Referências

http://esp-idf.readthedocs.io/en/latest/api-guides/ulp_instruction_set.html

https://portal.vidadesilicio.com.br/ultra-low-power-coprocessor-ulp-esp32/


Ultra Low Power coprocessor (ULP) - ESP32

Ultra Low Power coprocessor 

Neste tutorial, você irá aprender a instalar e usar o incrível ULP do ESP32, uma ferramenta extremamente poderosa e útil em projetos portáteis onde se faz o uso de baterias. Para programar o ULP, você vai precisar dos seguintes itens que não serão ensinados aqui:

  • Conhecimento em Assembly e registradores.
  • ESP-IDF instalada.

Deixaremos todas referencias sobre esses itens e os do tutorial ,como por exemplo, instalação do ULP, ao fim do tutorial.

[toc]

kit robotica educacional com Arduino ESP ou Microbit

O que é o ULP e como funciona?

Ultra Low Power coprocessor (ULP) - ESP32
Figura 1 - Coprocessador

O ULP é um coprocessador que podemos utilizar no ESP32 como um terceiro processador, entretanto, este foi projetado para uso em Deep Sleep, visto que seu consumo é extremamente baixo (150uA). Com ele, podemos fazer por exemplo, leituras de sensores ADC e a partir disso, acordar o MCU para tomar alguma decisão mais complexa, como enviar o dado para um banco de dados. Também é possível utilizar I2C e manipular os GPIO do RTC Domain.

Este pequeno processador acessa a região da memória chamada RTC_SLOW_MEM (8kB), onde é armazenado seu código ASM e também variáveis globais que são compartilhadas entre todos processadores. Com essas variáveis, podemos fazer a comunicação entre o ULP e os processadores principais (Main Core). Lembre-se que essas variáveis são mantidas entre os Deep Sleep's, então podemos guardar valores nessa região para usar após o Wake-UP.

O ULP contém 4 registradores de 16bit para uso geral (R0, R1, R2, R3) e mais um registrador de 8bit especifico para contagens (STAGE_CNT), como em loops com FOR(). Para programa-lo ,utilizamos a linguagem Assembly, uma linguagem de baixo nível extremamente rápida, eficiente e econômica em  termos de memória, mas não em linhas (hehehe).

Principais aplicações do ULP

  • Monitorar sensores digitais ou analógicos em Deep Sleep ocasionando um aumento gigantesco no tempo de duração de uma bateria.
  • Ajudar no processamento principal, caso necessário um poder de processamento maior.
  • Efetuar tarefas secundárias, como manipulação de GPIO's, sensores, criação de ISR's e etc, enquanto o Main Core faz uma tarefa pesada ou Time Sensitive.

Mãos a obra - Piscando um LED com o ULP em Assembly com um ESP32

Instalando o Core do ULP na ESP-IDF

Antes de sair usando o ULP loucamente, precisamos instalar os arquivos do Core (arquivos do sistema) para que o ULP funcione e seja compilado corretamente pelo Assembler da IDF (GNU) e após a instalação, precisamos ativa-lo e atribuir uma memória (ao mesmo), no "menuconfig".Para realizar estes procedimentos, siga os passos a seguir:

Se você ainda não tem a ESP-IDF instalada, instale-a antes de prosseguir: https://portal.vidadesilicio.com.br/instalando-esp-idf-no-windows-esp32/

1-) Baixe o .ZIP que contem os arquivos já prontos para serem colocados na IDF: https://github.com/espressif/binutils-esp32ulp/wiki

Figura 2 - Download do Core.

2-) Abra o .ZIP, acesse a pasta "esp32ulp-elf-binutils" e dentro dessa haverá outras tres pastas, copie-as para dentro do diretório "\msys32\mingw32\" da sua IDF.

Figura 3 - Copiando os arquivos do ULP pra IDF.

Já instalamos os arquivos, agora precisamos adicionar algumas linhas ao "component.mk" da pasta do seu projeto. Você precisa fazer os passos abaixo para todos projetos que pretende usar o ULP.

Você deve usar os diretórios do seu projeto.

3-) Abra o arquivo "component.mk" que se encontra na pasta "main" do seu projeto com o bloco de notas ou similar.

Figura 4 - Component.mk.

4-) Adicione o seguinte trecho ao arquivo:

ULP_APP_NAME ?= ulp_$(COMPONENT_NAME)
ULP_S_SOURCES = $(COMPONENT_PATH)/ulp/ulp.S
ULP_EXP_DEP_OBJECTS := main.o
include $(IDF_PATH)/components/ulp/component_ulp_common.mk
Figura 5 - Trecho adicionado ao mk.

5-) Abra o mingw32, vá ao diretório do seu projeto e use o "make menuconfig" para habilitar o ULP. No nosso caso, para ir ao diretório do projeto com o mingw32 é "cd /esp32/esp32".

Figura 6 - Abrindo o diretório.

Vá em "component config > esp32 specific" e habilite-o. Ao habilitar, aparecerá uma opção de configurar a memória reservada ao ULP, deixaremos o padrão por enquanto (512B).

Figura 7 - Habilitando o ULP.

Salve e saia do "menuconfig".

6-) Na pasta "main" do seu projeto, crie uma pasta "ulp" e dentro dessa, crie um arquivo "ulp.S".

Nota: você pode criar e editar (programar) o arquivo "ulp.S" com o bloco de notas caso não tenha uma IDE como Visual Studio (usada no tutorial).

Esses nomes precisam ser iguais ao trecho adicionado no "componente.mk".

Ultra Low Power coprocessor (ULP) - ESP32
Figura 8 - Arquivo do ULP.

Após a criação desse arquivo, podemos finalmente programar o incrível ULP. Esse arquivo é onde iremos programar o Assembly à ele.

Haverão dois códigos, um para o Main Core (main.c ou main.cpp) e outro pro ULP (ulp.S). O que faremos é basicamente atribuir o código Assembly ao trecho da memória RTC_SLOW_MEM e liga-lo. Após isso, o ESP32 entrará em Deep Sleep enquanto o ULP piscará um LED para mostrar funcionamento. Não se esqueça de ler o "Entendendo a fundo" que há explicações sobre o código Assembly e o funcionamento do ULP.

Estamos usando a ESP-IDF com Arduino component, isso nos permite usar tanto as bibliotecas do Arduino quanto da IDF. Se você usar a IDF sem o Arduino component, o código ficará praticamente igual, mudando apenas alguns detalhes como a alteração de extern "C" void app_main()  para void app_main() , em caso de dúvidas, comente!

Componentes necessários

  • 1x - ESP32 (Usaremos o NodeMCU32).
  • 1x - LED (Usaremos o LED Onboard).

Código do projeto

main.cpp

#include <C:/msys32/ESP32/ESP32/components/arduino/cores/esp32/Arduino.h>
#include <C:/msys32/ESP32/esp-idf/components/driver/include/driver/rtc_io.h>
#include <C:/msys32/ESP32/esp-idf/components/ulp/ulp.c>
#include <C:/msys32/ESP32/ESP32/build/main/ulp_main.h>
//Pode ser preciso arrumar os diretorios das bibliotecas

extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");

void ulp();

extern "C" void app_main()
{
	initArduino();//Inicia algumas configuracoes do Arduino Core, se voce nao usa Arduino component, apague essa linha
	ulp();//carrega e inicia o ULP

	ESP.deepSleep(1800000000);//entra em deep sleep
}

void ulp()
{
	rtc_gpio_init(GPIO_NUM_2);//inicia o GPIO2 no RTC DOMAIN
	rtc_gpio_set_direction(GPIO_NUM_2, RTC_GPIO_MODE_OUTPUT_ONLY);//Define o GPIO2 como saida

	ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));//Carrega o binario do codigo assembly na memoria
	ulp_run((&ulp_main - RTC_SLOW_MEM) / sizeof(uint32_t));//Inicia o ULP
}

ulp.S

#include "soc/soc_ulp.h"
#include "soc/rtc_io_reg.h"
#include "soc/sens_reg.h"
#include "soc/rtc_cntl_reg.h"


.bss//Variaveis sao declaradas dentro da secao .bss


.text//O codigo é feito dentro da secao .text

	.global main
	main://O codigo e iniciado aqui, equivale ao void setup()

		

	jump loop//Isso nao e necessario, mas foi colocado para organizacao
 
	loop:
		
		WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S+12, 1, 1)//GPIO2 HIGH
		stage_rst
		1: stage_inc 1
		wait 32000
		jumps 1b, 125, lt//delay 500ms
		

		WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+12, 1, 1)//GPIO2 LOW
		stage_rst
		1: stage_inc 1
		wait 32000
		jumps 1b, 125, lt//delay 500ms

		
		jump loop//volta ao inicio do loop

Colocando para funcionar

Após programar, basta dar upload para o ESP32 pelo próprio mingw32 e a mágica irá acontecer.

Ultra Low Power coprocessor (ULP) - ESP32
GIF - Blink.

Entendendo a fundo

ULP

Apesar de termos apresentado apenas uma ideia sobre o ULP, devemos entender que este é muito mais complexo que isso devido ao fato de ter como aplicação alvo o Deep sleep.

Algumas características do ULP:

  • Clock (pode ser alterado e calibrado): 8.5MHz ±7%.
  • Memória: RTC_SLOW_MEM com 8kB.
  • Timer de Wake-UP (pode ser desativado): 150kHz.
  • 4 Registradores de 16bit (R0-R3).
  • 1 Registrador de 8bit (STAGE_CNT).
  • Funciona tanto nos modos de operações normais até Deep sleep.
  • Capacidade de fazer leituras de sensores analógicos/digitais externos, I2C e vários outros itens.

Funcionamento e dicas do ULP

O ULP é um coprocessador FSM (Finite state machine) que podemos usar para praticamente qualquer objetivo, entretanto é preciso tomar alguns cuidados como o timer de Wake-UP. Esse timer que vem por padrão ativado, serve para acordar o ULP periodicamente após encontrar o comando HALT no código Assembly. No nosso exemplo não foi usado HALT para encerrar o código do ULP pois usamos ele em um loop infinito. Se você não tomar cuidado esse comando e esquecer o timer ativado (é possível desativa-lo para garantir o funcionamento em certos casos), provavelmente o ULP não irá funcionar da forma que você espera.

Após o binário ser carregado e o ULP iniciado pelo código principal, o ULP irá iniciar a execução do código na label "main" que foi definida no ulp_run() , a partir desse ponto, será executado linha após linha até encontrar o comando HALT ou cair em um loop infinito como mostrado nesse tutorial.

Ao usar o comando WAKE o ESP32 irá acordar e executar todo o código novamente do começo, isso pode gerar problemas com o ulp_run() uma vez que o ULP já esta em execução e será reiniciado, para isso você deve adicionar uma condicional de Wake-UP que verifica o motivo do ESP32 ter acordado e caso não tenha sido pelo ULP, deve ter sido queda de energia ou similares, logo, precisamos inicia-lo novamente.

Toda explicação de funcionamento do ULP, comandos do Assembly, registradores e etc, estão na referencia técnica do ESP32 que se encontra no fim do tutorial.

Software

ulp.S

-Macro WRITE_RTC_REG()

WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+12, 1, 1)//GPIO2 LOW

Essa macro escreve um valor no registrador, sendo bem parecido com o tutorial que já fizemos sobre: Manipulando os registradores do ESP32, Porem, é usado os registrador do RTC Domain, por isso ativamos os pino 12 do RTC, que equivale ao GPIO2.

-Delay em Assembly

stage_rst
1: stage_inc 1
wait 32000
jumps 1b, 125, lt//delay 500ms

O blink faz com que o LED fique 500ms acesso e 500ms apagado, mas como que isso foi feito? Foi usado os ciclos do clock do ULP que é por padrão 8.5MHz ±7%, vamos arredondar para 8MHz ou seja, a cada 1 segundo, o clock irá oscilar 8 milhões de vezes. Pensando nisso, podemos calcular a quantidade de ciclos necessário para efetuar um delay.

Para fazer o delay, iremos usar 3 itens que nos ajudarão a "pular" ciclos do clock, fazendo com que o processador fique em espera:

  • NOP (No Operation): pula 1 ciclo do clock.
  • WAIT X: equivale a usar vários NOP's, limite de 65535.
  • Registrador: guardará um valor auxiliar na contagem.

Veja os passos para efetuar o delay de 500ms no Assembly do ULP com o registrador STAGE_CNT:

1-) Segundos * clock = ciclos para pular

0.5 * 8000000 = 4000000

2-) Cada WAIT pode conter no máximo 65535, que não é nem perto do que precisamos (4000000), logo, vamos utilizar uma variável (registrador) auxiliar que irá se comportar igual ao FOR(). Será usado WAIT 32000, mas você pode escolher qualquer um desde que esteja dentro dos limites.

ciclos para pular / wait = total de operações do loop

4000000 / 32000 = 125 operações

Agora, basta fazer um FOR() em Assembly para que se assemelhe a isso:

for (int i = 0; i < 125; i++)
{
    //blabla
}

Usaremos o registrador STAGE_CNT que é indicado para contagens:

stage_rst//Reseta o registrador (STAGE_CNT = 0)
1: stage_inc 1//Incrementa o registrador em +1 (STAGE_CNT++)
wait 32000//Equivale a 32000 NOP's
jumps 1b, 125, lt//Pula para label "1before" enquanto o registrador for menor que 125

Considerações finais

Infelizmente pelo ESP32 ainda não "cair em uso" aqui no Brasil, só encontramos informações de fora e principalmente no Datasheet. Espero que com esse "ponta pé inicial" mais pessoas comecem a postar materiais sobre ULP, uma vez que as aplicações para esse pequeno campeão que não encontramos em qualquer lugar são gigantescas e muito importantes em projetos portáteis, onde permite o processamento de informações enquanto todo o resto do microcontrolador permanece em Sleep para economia da bateria. Bons estudos e aproveite essa ferramenta extraordinária.

Se você já conseguiu usar o ULP, veja este tutorial para leitura de sensores analógicos ou digitais em Deep Sleep com o ULP no ESP32.

https://portal.vidadesilicio.com.br/lendo-sensores-analogicos-deep-sleep-ulp-esp32/

Referencias

https://esp-idf.readthedocs.io/en/v3.0-rc1/api-guides/ulp.html

https://esp-idf.readthedocs.io/en/v3.0-rc1/api-guides/ulp_instruction_set.html

http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf

https://portal.vidadesilicio.com.br/instalando-esp-idf-no-windows-esp32/


Instalando a ESP IDF no Windows - ESP32

Instalando a ESP IDF no Windows - ESP32

Neste tutorial, vamos aprender a instalar a Toolchain juntamente com a ESP IDF, que é um ambiente completo de desenvolvimento pro ESP32, onde é suportado todas features, opções e configurações sobre o microcontrolador, permitindo que o ESP32 se encaixe perfeitamente nos mais variados projetos, desde simples até industriais!

[toc]

O que é a ESP IDF e quais são os pontos fortes?

Normalmente chamada apenas de IDF, podemos dizer que esta engloba todos os conjuntos de API's e configurações do ESP32. Já a Toolchain (mingw32) consiste em uma ferramenta que compila e constrói o código que escrevemos juntamente com as configurações escolhidas no "menuconfig". Por fim, ESP IDF é o conjunto de bibliotecas feitas pro ESP32.

Os principais pontos a serem levados em consideração para você trocar a Arduino IDE ou outra, pela IDF são:

  • Suporte a todas features, incluindo Bluetooth, Flash Encryption e Secure Boot (itens importantes para quem pretende criar e vender produtos).
  • Configuração total do sistema, como por exemplo eFuses, clock, watchdog's, timer's, memória dinâmica para WiFi e até tempo de Wake-UP após Deep sleep.

Mãos a obra - Testando a ESP IDF

Instalando a Toolchain e ESP IDF

Usaremos alguns diretórios padrões para instalação, você pode optar por escolher qualquer nome e local, mas tome cuidado ao seguir o tutorial "ao pé da letra".

1-) Faça o download da Toolchain em: http://esp-idf.readthedocs.io/en/latest/get-started/windows-setup.html

Figura 1 - Download Toolchain.

2-) Abra o .ZIP e copie a pasta "msys32" para a raiz do seu HD "C:\".

Figura 2 - Copiando a pasta.

3-) Faça o download do .ZIP da ultima release que encontrar, nesse caso é a 3.0-rc1: https://github.com/espressif/esp-idf/releases

Nota: há outras maneiras de baixar a IDF, como pelo próprio Toolchain. Caso precise de outros métodos, veja as referencias.

Figura 3 - Download da IDF.

4-) Crie uma pasta chamada "ESP32" na raiz da "msys32" que você copiou no passo 2. Logo em seguida, abra o .ZIP do passo 3, copie a pasta dentro desse novo diretório "ESP32" e renomeie para "esp-idf". Ficara parecido com: "C:\msys32\ESP32\esp-idf"

Figura 4 - Pasta renomeada.

5-) Precisamos adicionar uma variável à Toolchain que guardará o diretório da pasta "esp-idf", sem isso não funcionará corretamente.

Vá no diretório "C:\msys32\etc\profile.d" copie e cole qualquer script (extensão .SH), fazendo com que o arquivo fique duplicado.

Figura 5 - Duplicando um script.

Renomeie este script duplicado para "export_idf_path" e abra-o com algum editor de texto como bloco de notas e apague tudo o que estiver escrito. Escreva essa nova e única linha que indica ao Toolchain o diretório da esp-idf que instalamos:

export IDF_PATH="C:\msys32\ESP32\esp-idf"

Figura 6 - export_idf_path editado para o caminho da esp-idf.

Finalmente instalamos todo o ambiente de programação e desenvolvimento do ESP32 no Windows, agora vamos copiar a pasta de algum exemplo da IDF para que seja nosso local de trabalho.

Vamos copiar a pasta do projeto "hello world" que se encontra em "C:\msys32\ESP32\esp-idf\examples\get-started\" no mesmo local que nossa pasta "esp-idf" e renomeá-la "esp32".

Figura 6 - Pasta hello world a ser copiada.
Figura 7 - Hello world copiado e renomeado.

Pronto! Podemos usufruir de todas features e configurações do ESP32. Se você não souber usar o painel da IDF, logo abaixo em "Entendendo a fundo", explicaremos como usar a IDF para compilar e configurar seus projetos.

Componentes necessários

Código do projeto

Não iremos programar nada! Apenas dar upload do antigo "hello world"  que copiamos logo acima, veja abaixo em "Entendendo a fundo" como dar upload do código ao ESP32 pelo painel da IDF.

Colocando para funcionar

Após o upload do código e ver o monitor, já temos algumas informações sobre o nosso microcontrolador.

Figura 8 - IDF MONITOR.

Entendendo a fundo

IDF

Para dar upload dos códigos, ver o "Serial monitor", editar configurações do Bootloader e etc, precisamos usar o painel (CMD) da IDF.

Antes de mostrarmos alguns comandos da IDF, vamos configurar o nosso projeto ESP32 (antigo hello world) para que o upload seja feito e vejamos funcionando.

1-) Abra o programa "mingw32" que se encontra em "C:\msys32\", abra a pasta do projeto com "cd /esp32/esp32" e abra o menu de configurações com "make menuconfig"

Figura 9 - Abrindo a pasta do projeto e configurando.

Aqui é o paraíso do ESP32, onde conseguimos configurar praticamente tudo desse microcontrolador, desde clock até alocação de memórias dinâmicas e Watchdog.

Precisamos escolher a porta COM em que seu ESP32 está plugado no computador, você encontra isso em "Gerenciador de dispositivos" no Windows, o nosso está na porta COM8.

2-) Vá em "Serial flasher config" e altere a "Default serial port" para sua porta COM, o nosso será COM8. Você também pode alterar a velocidade de upload caso seu conversor suporte, normalmente é o CP2102 que suporta até a opção "921600".

Aconselhamos fortemente que se você pretende usar o ESP32 para algo comercial ou projeto sério, leia e configure todas as opções do ESP32 corretamente para seu projeto, você pode ver a ajuda de cada configuração apertando "H" e nas referencias.

Agora que configuramos a porta COM correta para upload, salve e saia do menuconfig.

3-) Digite "make flash monitor" para que comece a compilação do seu código, isso pode demorar MUITO toda vez que você altera o menuconfig, pois o Toolchain recompila todos os componentes, entretanto, após a primeira compilação depois da alteração do menuconfig, não demora mais que 60 segundos.

A dica para acelerar essa primeira compilação é usar todos os núcleos do seu processador. É indicado usar o numero de núcleos + 1. Nosso computador tem 4 núcleos, então vamos usar o seguinte comando: "make flash monitor -j5", isso deixa a compilação extremamente mais rápida.

Nosso código será finalmente enviado ao ESP32 e automaticamente após o termino, será aberto o "Serial monitor" que mostrará algumas informações sobre seu microcontrolador.

A partir daqui você já pode aproveitar a IDF, também existem alguns comandos interessantes e únicos:

  • make help: mostra todos os comandos da IDF e o que fazem.
  • make: mostra alguns comandos de compilação e endereços dos binários.
  • make flash: da upload do código ao ESP32.
  • make monitor: abre o "Serial monitor".
  • make clean: apaga a pasta BUILD do projeto.
  • make erase_flash: apaga toda a FLASH do ESP32, incluindo seções de memória não volátil como NVS, FAT e EEPROM.
  • make size: mostra o tamanho dos binários como o uso da FLASH e RAM.

Considerações finais

A ESP-IDF é um prato cheio pra quem pretende se aprofundar no ESP32 desde motivos profissionais ou educacionais, uma vez que este é barato e confiável até para aplicações industriais, diferente do ESP8266.

Você ainda pode usar bibliotecas do Arduino como a WiFi, Serial e WiFiClient em vez das originais da IDF, isso é chamado de "Arduino component", onde podemos usar tanto as bibliotecas e funções do Arduino, quanto da IDF. Para isso, precisará alterar algumas coisas da pasta do seu projeto que são ensinadas aqui: https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md

Referencias

http://esp-idf.readthedocs.io/en/latest/get-started/windows-setup.html

http://esp-idf.readthedocs.io/en/latest/get-started/index.html

http://esp-idf.readthedocs.io/en/latest/get-started/add-idf_path-to-profile.html

https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md


manipulando registradores esp32

Manipulando os registradores - ESP32

Registradores - ESP32

Com o sucesso gigantesco do ESP32 que veio para bater de frente dos PIC32 e STM32, ganhando em alguns aspectos como velocidade, não podemos deixar de lado a manipulação de registradores que não estavam presentes, de maneira fácil, no ESP8266. Neste tutorial, vamos aprender a manipular os registradores de porta (GPIO) do ESP32 de forma simples para efetuar um Blink extremamente compacto e o mais rápido possível.

[toc]

O que são registradores em um microcontrolador?

São pequenos endereços de memória que nos permitem, via software, controlar pinos, processos, interrupções e coisas do tipo de forma extremamente eficiente. Podemos dizer que isso se assemelha ao assembly, visto que é um dos itens de mais baixo nível que conseguimos controlar diretamente pelo código e com isso temos uma eficiente forma de programação em questão de velocidade e confiança.

O ESP32 conta com centenas de registradores de 32bits para que possamos manipular com eficiência todo o hardware disponível, todas as informações estão disponíveis no Datasheet que estará ao fim deste tutorial.

Observação importante: em alguns casos de registradores como o correspondente ao famoso "pinMode()" que declara um pino como saída por exemplo, há mais de um registrador que faz essa mesma tarefa e também mais formas de escrever ou ler registradores, entretanto, sobre os registradores, usaremos os registradores atômicos, que nos garantem a escrita ordenada em um ambiente Triple-Core.

 


Mãos a obra - Piscando um LED através da manipulação de registradores

Componentes necessários

Código do projeto

void setup()
{
	REG_WRITE(GPIO_ENABLE_REG, BIT2);//Define o GPIO2 como saída
}

void loop()
{
	REG_WRITE(GPIO_OUT_W1TS_REG, BIT2);//GPIO2 HIGH (set)
        delay(250);
	REG_WRITE(GPIO_OUT_W1TC_REG, BIT2);//GPIO2 LOW (clear)
        delay(250);
}

Colocando para funcionar


Entendendo a fundo

Software

Quem esta acostumado com registradores pode estranhar esse jeito de manipula-los, parecendo muito mais fácil do que em outros microcontroladores. A verdade é que "REG_WRITE" é uma macro para facilitar a manipulação dos registradores que é definida no arquivo "soc.h", lá você também encontra macros como REG_READ que é usada para leitura de registradores, REG_SET_FIELD e etc.

Os três registradores usados são:

  • GPIO_ENABLE_REG (Figura 1): Registrador que habilita o GPIO(0-31) como saída.
  • GPIO_OUT_W1TS_REG (Figura 2): Registrador que define o GPIO(0-31) em HIGH (Vcc). (SET)
  • GPIO_OUT_W1TC_REG (Figura 3): Registrador que define o GPIO(0-31) em LOW (GND). (CLEAR)

 

Figura 1 - GPIO_ENABLE_REG

 

Figura 2 - GPIO_OUT_W1TS_REG

 

Figura 3 - GPIO_OUT_W1TC_REG

 

Uma forma bem comum de se utilizar registradores para pinos, é a manipulação direta (nesse caso a 32 bits, logo, 32 pinos) de uma única vez em uma linha! Com isso é possível economizar varias linhas e também deixar o código mais rápido. Se você pretende definir dois pinos como saída, a sentença ficará dessa forma (serve para os outros registradores também):

REG_WRITE(GPIO_ENABLE_REG, BIT2 + BIT4);//Define o GPIO2 e GPIO4 como saída

Esses são os registradores básicos para manipular um pino de saída, se você pretende ler pinos de entrada, terá que usar outros registradores que estão detalhados no Datasheet.

 

Observação: alguns registradores não estão com os nomes definidos nos arquivos do ESP32, logo, você não conseguirá manipular o registrador pelo nome (igual feito acima com GPIO_ENABLE_OUT e etc). Para manipular os registradores que não estão definidos, é necessário pegar o endereço do registrador na memória que se encontra no Datasheet. Veja como ficaria a manipulação sem o nome definido:

 

Figura 4 - Endereço dos registradores.
REG_WRITE(0x3ff44020, BIT2);//Define o GPIO2 como saída

while (1)
{
	REG_WRITE(0x3ff44008, BIT2);//GPIO2  = HIGH
	delay(250);
	REG_WRITE(0x3ff4400C, BIT2);//GPIO2 = LOW
	delay(250);
}

 


Considerações finais

Manipulando diretamente os registradores, conseguimos fazer tarefas com uma extrema velocidade e confiança, sendo necessária para vários projetos. Leia bem o Datasheet se você pretende dominar este incrível microcontrolador e boa sorte com os registradores.

Referências

Todos os registradores, informações e detalhes sobre o ESP32 se encontram nesse Datasheet:

http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf


Controle de potência via PWM - ESP32

Controle de potência via PWM - ESP32 

A modulação por largura de pulso (PWM) é uma técnica amplamente utilizada em diversos meios, principalmente para controle de potência e velocidade. Neste tutorial, você aprenderá a configurar o PWM no ESP32 através do recurso LED PWM e fazer um LED "respirar" (fade) ou acender com metade do brilho.

[toc]

Pulse Width Modulation

Controle de potência via PWM - ESP32

Com o PWM, podemos controlar a tensão média em um componente, e por consequência a potência, como um LED, a velocidade de um motor DC ou até converter o sinal PWM criado (onda quadrada) para uma onda senoidal com a adição de alguns poucos itens.

As imagens (GIF) abaixo mostram o duty cycle variando, que altera a tensão média entregue ao componente. Em alguns casos como motores, também é preciso configurar corretamente a frequência de chaveamento e ter atenção ao nível de pico máximo aceito na alimentação, entretanto isso ficará de "lição de casa" para pesquisarem.

Controle de potência via PWM - ESP32
Brilho de LED com a variação do duty cycle
Controle de potência via PWM - ESP32
Tensão média com a variação do duty cycle

 


Mãos a obra - Variando o brilho do LED

Componentes necessários

Código do projeto

void setup()
{
	pinMode(2, OUTPUT);//Definimos o pino 2 (LED) como saída.

	ledcAttachPin(2, 0);//Atribuimos o pino 2 ao canal 0.
	ledcSetup(0, 1000, 10);//Atribuimos ao canal 0 a frequencia de 1000Hz com resolucao de 10bits.
	
}

void loop()
{
	for (int i = 0; i < 1024; i++)
	{
		ledcWrite(0, i);//Escrevemos no canal 0, o duty cycle "i".
		delay(2);
	}

	for (int i = 1023; i > 0; i--)
	{
		ledcWrite(0, i);
		delay(2);
	}
}

Colocando para funcionar

O código fará um "fade" no LED, dando a sensação de "respiração", aumentando e diminuindo o brilho gradativamente.


Entendendo a fundo

Software

-Função ledcAttachPin()

ledcAttachPin(PINO, CANAL);

Esta função apenas atribui um pino a um canal. Podemos escolher qualquer pino a qualquer canal, este vai de 0 a 15, totalizando 16 canais.

Cada canal é independente do outro, mas você também pode atribuir vários pinos a um mesmo canal.

Pino: Qualquer.

Canal: 0 - 15.

-Função ledcSetup()

ledcSetup(CANAL, FREQUENCIA, RESOLUCAO);

Esta função configura um canal para trabalhar a uma determinada frequência e resolução.

Canal: 0 - 15.

Frequência: 1 - 40MHz.

Resolução: 1 - 16 bits.

-Função ledcWrite()

ledcWrite(CANAL, DUTY CYCLE);

Esta função "escreve" o duty cycle ao canal. Lembramos que o valor colocado no parâmetro duty cycle não é em porcentagem e sim em decimal.

Exemplo: para um duty cycle de 50% com 10bits (2^10 = 1024) de resolução, devemos escrever 512.

Canal: 0 - 15.

Duty cycle: 0 - 100% (em decimal).


Indo além com PWM 

Tensão média

Podemos calcular a tensão média (V) entregue ao componente através de uma simples conta que relaciona o sinal HIGH com o duty cycle.

Sinal HIGH do ESP32 (Vcc): ~3.3V.

Duty cycle: 32%.

Ao efetuar a conta de 3.3*0.32, chegamos a conclusão que a tensão média (Vm) entregue será de 1.056V!

Vamos testar este código e verificar as tensões com um multímetro.

void setup()
{
	pinMode(23, OUTPUT);//Definimos o pino 23 como saída.
	pinMode(22, OUTPUT);//Definimos o pino 22 como saída.
	pinMode(21, OUTPUT);//Definimos o pino 21 como saída.
	pinMode(19, OUTPUT);//Definimos o pino 19 como saída.

	ledcAttachPin(23, 0);//Atribuimos o pino 23 ao canal 0.
	ledcSetup(0, 1000, 10);//Atribuimos ao canal 0 a frequencia de 1000Hz com resolucao de 10bits.
	ledcWrite(0, 256);//Escrevemos um duty cycle de 25% no canal 0.

	ledcAttachPin(22, 1);//Atribuimos o pino 22 ao canal 1.
	ledcSetup(1, 1000, 10);//Atribuimos ao canal 1 a frequencia de 1000Hz com resolucao de 10bits.
	ledcWrite(1, 512);//Escrevemos um duty cycle de 50% no canal 1.

	ledcAttachPin(21, 2);//Atribuimos o pino 21 ao canal 2.
	ledcSetup(2, 1000, 10);//Atribuimos ao canal 2 a frequencia de 1000Hz com resolucao de 10bits.
	ledcWrite(2, 768);//Escrevemos um duty cycle de 75% no canal 2.

	ledcAttachPin(19, 3);//Atribuimos o pino 19 ao canal 3.
	ledcSetup(3, 1000, 10);//Atribuimos ao canal 3 a frequencia de 1000Hz com resolucao de 10bits.
	ledcWrite(3, 1023);//Escrevemos um duty cycle de 100% no canal 3.
}

void loop()
{

}

Testando este código e verificando o pino respectivo com um multímetro, podemos perceber que as contas são iguais ou próximas. Lembrando que o próprio multímetro tem sua faixa de precisão (erro), que neste caso é (+-0.5% + 3D com 1mV de resolução).

Todos os testes a seguir tem Vcc teórico de 3.3V, as imagens são as leituras do nosso multímetro.

Caso 1, 25% = 0.825V

25%

Caso 2, 50% = 1.65V

50%

Caso 3, 75% = 2.475V

75%

Caso 4, 100% = 3.3V

100%

Todos os valores lidos, mesmo estando próximos aos teóricos, há o erro do multímetro. Aplicando a formula de erro ao valor lido, todos os valores obtidos estão dentro da faixa tolerável de erro, ou seja, estão corretos!

Frequência X resolução

Um problema recorrente com alguns componentes é a frequência necessária de funcionamento. Motores por exemplo, é bastante usado entre 20kHz e 200kHz.

O recurso "LED PWM" do ESP32 é baseado em um clock de 80MHz, logo podemos fazer algumas contas básicas para se chegar a frequência máxima com a resolução escolhida.

Nos exemplos acima, foi usado uma frequência de 1kHz com 10bits de resolução, entretanto pode ser necessário o uso de uma frequência muito maior e a resolução é uma das barreiras para isso. Vamos fazer essa conta com os dados citados para chegar na frequência máxima (Fm).

A resolução deve ser em decimal e não "bits".

80MHz / 10bits

80000000 / 1024 = 78125Hz

A frequência máxima que conseguimos chegar com uma resolução de 10bits no ESP32 é de ~78kHz. Vamos testar!

Caso 1, 32kHz com 10bits

Caso 1

Caso 1.1, 80kHz com 10bits

Caso 1.1

Como feito nas contas, a frequência máxima realmente foi de ~78kHz para 10bits, mesmo atribuindo 80kHz no código. Agora vamos brincar com frequências mais altas deixando a resolução em 3bits e ver a frequência máxima.

80MHz / 3bits = Fm

80000000 / 8 = 10MHz

Caso 2, 2MHz com 3bits

Caso 2

Caso 2.1: 11MHz com 3bits

Caso 2.1

Novamente, as contas mostraram um máximo de 10MHz e mesmo atribuindo 11MHz, ficou limitado a 10MHz.


Considerações finais

O PWM é extremamente útil em diversos projetos, permitindo o controle de potência, velocidade, brilho e até inversores (DC-AC) através da modulação da tensão. Apesar de parecer simples apenas "inverter o estado do pino", com frequências um pouco mais altas, não é qualquer microcontrolador que aguenta se manter com uma frequência estável ou se quer chegar em frequências acima de 10MHz. O ESP32 com 1bit de resolução nos permite chegar a 40MHz, dando uma vasta gama de possibilidades em aplicações.


Lendo dados do Google planilhas com ESP - Banco de dados

Lendo dados do Google planilhas com ESP - Banco de dados

No tutorial Banco de dados com Google planilhas com ESP, aprendemos a enviar dados para o Google Planilhas. Entretanto, para fazer justo ao nome "banco de dados", também precisamos recuperar dados da planilha para manipula-los ou até criar comandos de controle pela planilha, que permitirá, por exemplo, ativar atuadores ou ler dados que colocamos na planilha. Dessa forma, neste tutorial iremos aprender como ler os dados do Google Planilhas através de um ESP.

[toc]

Configurações iniciais - Requisitando dados do Google planilhas

O processo necessário para adquirir dados da planilha é quase o mesmo em relação ao método de envio (GET), entretanto para fazer isso, precisamos obter uma chave secreta. Esta chave faz o papel de "senha", para que ninguém consiga ler seus dados sem ela.

Atenção: Há maneiras mais seguras, como restringir o acesso da chave ou usar autenticador. Será mostrado o método mais simples.

Passo 1-) Entre na plataforma de gerenciamento de API's da Google: https://console.developers.google.com/apis , crie um novo projeto e de um nome qualquer.

Este projeto será apenas para "guardar" sua chave com a respectiva API, neste caso, Google planilhas.

Figura 1 - Criando um projeto de API.

 

Passo 2-) Vá em "Credenciais" e crie uma "Chave de API"

Figura 2 - Criando a Chave de API.

 

Figura 3 - Chave de API.

 

Feche a janela e a partir de agora, já temos nossa chave necessária para requisição de dados (e futuramente, altera-los).

 

Passo 3-) Volte para a página inicial do Google APIs, clique em "Biblioteca", selecione "Google Sheets API" e "Ativar"

Figura 4 - Ativando a API.

 

 

 

Terminamos de criar nossa chave e ativa-la, agora podemos manipular qualquer planilha que tenhamos salvo no Google Drive!


Mãos a obra - Lendo o Google planilhas

Componentes necessários

Código do projeto

Atenção: é necessário que você use os dados da sua planilha e faça uma alteração na mesma, explicaremos logo abaixo.

#include <ESP8266WiFi.h>

WiFiClientSecure cl;//Cria um cliente seguro (para ter acesso ao HTTPS)
String textFix = "GET /v4/spreadsheets/12IYuWdV0aJa8mQPhsR5C6AVEwZufyC05wufTrTJsSg/values/";
String key = "?key=IzaSyDmot3XwHfsNhqeuKdINMYxpyFK4cY";//Chave de API
//Essas Strings serao auxiliares, 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 sua rede
    delay(3000);//Espera um tempo para se conectar no WiFi

}

void loop()
{

    if (cl.connect("sheets.googleapis.com", 443) == true)//Tenta se conectar ao servidor do Google APIs na porta 443 (HTTPS)
    {
        String toSend = textFix;//Atribuimos a String auxiliar na nova String que sera enviada
        
        toSend += "C2:C4";//Os valores que queremos ler da planilha. Para uma única célula, use algo como "A2"; para ler varios, use algo como "A1:C4".
        toSend += key;//Adicionamos a chave na String
        toSend += " HTTP/1.1";//Completamos o metodo GET para nosso formulario.

        cl.println(toSend);//Enviamos o GET ao servidor-
        cl.println("Host: sheets.googleapis.com");//-
        cl.println();//-
			

        Serial.println("Dado recebido:\n");//Mostra no Serial Monitor todo o pacote recebido.-
        Serial.print(cl.readString());//-
        cl.stop();//Encerramos a conexao com o servidor.
    }
    else
    {
        Serial.println("Erro ao se conectar");
    }
	

    delay(5000);

}

Ajustando o código para sua planilha

Antes de testar, precisamos alterar os dados do código para os seus dados e também compartilhar o link da sua planilha. Sem isso não irá funcionar!

Lembrando: altere apenas os dados destacados, o restante é necessário para funcionamento correto.

Passo 1-) Vá no começo do código e altere a chave (destacada) por sua chave.

Figura 5 - Alterando a Chave de API.

 

Passo 2-) Ainda nesta parte, altere o ID com o da planilha que você deseja obter os dados. Para isso vá em seu Google Drive, entre na planilha e pegue o ID:

Neste caso, vamos pegar a própria planilha criada na primeira parte do material.

configurando o google planilhas - banco de dados

Figura 6 - Alterando o ID da planilha.

 

Se você testar o código, verá que não temos permissão para acessar o banco de dados no Google planilhas. Isso acontece pois nossa "Chave de API" precisa estar com o link público (Qualquer pessoa com o link pode visualizar). Você pode contornar isso usando os Autenticadores ou adicionando Emails confiáveis ao sistema. Usaremos o mais simples para didática e fácil entendimento. Veja a saída do Serial monitor:

Figura 7 - Serial Monitor: Erro de permissão ao acessar o banco de dados no Google Planilhas

 

Passo 3-) Para deixar o link público, vá na sua planilha e siga os passos:

  • 1-) Clique em "Compartilhar" no canto superior direito.
  • 2-) Clique em "Avançado".

 

  • 3-) Clique em "Alterar...".

 

  • 4-) Clique em "Ativado: qualquer pessoa com link" e salve.

Colocando para funcionar

Agora podemos testar e já estará funcionando!

lendo as células do google planilhas - banco de dados com ESP
Figura 8 - Serial Monitor: Resposta de um grupo de células do nosso banco de dados no Google Planilhas

 

Veja que o pedido foi de um grupo de células, neste caso, C2:C4. Isso significa que iremos receber os dados das células C2,C3 e C4 em ordem da respectiva chamada.


Entendendo a fundo

Software

- String auxiliar (textFix)

String textFix = "GET /v4/spreadsheets/12IYuWdV0aJa8mQPhsR5C6AVEwZufyC05wufTrTJsSg/values/";

Basicamente é onde colocamos o ID da nossa planilha, você deve alterar para o ID de sua planilha!

- String auxiliar (key)

String key = "?key=IzaSyDmot3XwHfsNhqeuKdINMYxpyFK4cY";//Chave de API

Esta outra String, é onde atribuímos nossa Chave de API, você deve alterar para sua Chave de API.

- Obtenção dos dados

toSend += "C2:C4";

Aqui fica a grande jogada, onde conseguimos pegar células individuais, ou grupos de células. Vamos a um breve resumo.

Nossa planilha:

Banco de dados no Google Planilhas
Nosso banco de dados no Google Planilhas

 

Célula individual: Imagine que você precisa do valor da célula C2("Vida").

toSend += "C2";

 

Grupo de células: Imagine que você precisa do valor de um grupo de células, neste caso C2, C3 e C4 ("Vida", "De", "Silicio").

toSend += "C2:C4";

 

Podemos ver a resposta do Google ao pedido C2:C4 no Serial Monitor:

Lendo o banco de dados no Google planilhas
Lendo o banco de dados no Google planilhas

 

Você pode estar se perguntando: "Como vou usar essa String cheia de 'lixo' ?"

Este será o desafio de vocês! Futuramente criaremos um tutorial sobre manipulação de Strings. Mas aqui vai uma dica, procure sobre estes comandos em programação:

Com elas, você é capaz de pegar partes e caracteres específicos da String e ainda criar protocolos de mensagens para uma comunicação efetiva.


Desafio

Tente pegar apenas o valor que você queria da planilha. Você irá usar os dois comandos citados acima para "limpar" a String recebida pelo Google e assim tornando-a útil para o uso no microcontrolador.

Fechamento

Agora que você consegue obter valores da planilha, pode usar dados da planilha para algum processamento interno ou criar comandos de controle através da planilha! As possibilidades são muitas e depende de você. Boa sorte.

Referências

  • https://developers.google.com/sheets/guides/concepts
  • https://developers.google.com/sheets/guides/values

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.

Figura 3 - Alterando o nome da planilha.
Figura 3 - Alterando o nome da planilha.

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.

Figura 7 - Abrindo o link do formulário.
Figura 7 - Abrindo o link do formulário.

Após digitar o numero e clicar em "Enviar", será mostrado o aviso que a resposta foi registrada.

Figura 8 - Resposta enviada.
Figura 8 - Resposta enviada.

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.

Figura 9 - Resposta do formulário na planilha.
Figura 9 - Resposta do formulário na planilha.

Agora que aprendemos a utilizar o formulário em conjunto com a planilha, precisamos apenas integrar no Microcontrolador.


Mãos à obra

Componentes necessários

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:

    1. Clique no formulário com o botão direito do mouse e selecione "Exibir código fonte da pagina" (Ctrl+U);
    2. Agora pesquise pelo nome do campo inserido no formulário usando a ferramenta de pesquisa do navegador (Ctrl+F);
    3. 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,[""];
    4. O entry vai ser o numero após o colchete “12345678”,
    5. Inclua "entry." antes do número, fincando “entry.12345678”;
    6. 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

Multiprocessamento - ESP32

Multiprocessamento com ESP32

As vezes é necessário que façamos o uso de sistemas multicores para as mais diversas finalidades, como por exemplo, fazer verificações de dados pela Serial, I2C ou sensores, enquanto o outro processador (Core) faz uma outra atividade em que não possa ser interrompida ou seja indesejado esse tipo de ação. Aprenderemos o que é multiprocessamento e usaremos o incrível ESP32 que tem ao todo três cores, para criar dois LOOP(), permitindo que você rode dois códigos ao mesmo tempo!

Lembrando: O terceiro core do ESP32 é um ULP, que é apenas programado em Assembly. Também é possível programa-lo para as mais diversas finalidades. Será mostrado apenas a programação do core principal.

Para conhecer mais sobre o ESP32 você pode conferir nosso tutorial: Conhecendo o ESP32

[toc]

Computação paralela - Multiprocessamento

computação paralela - Multiprocessamento
computação paralela - Multiprocessamento

Computação paralela é um assunto extremamente complicado, porem podemos simplificar de um método prático:

Você tem um supermercado com um caixa e em horários de pico, o caixa não é rápido suficiente para atender os clientes, então é necessário contratar outro funcionário que fique em outro caixa, fazendo assim que a velocidade de espera seja até 50% menor. (será atendido o dobro de clientes em relação a apenas um caixa)

Um sistema computacional paralelo, permite realizar diversos cálculos (tarefas, algoritmos, etc) simultaneamente. Há diversas maneiras de se paralelizar um código que é normalmente escrito em sequência: em bit, instrução, de dado ou de tarefa. O método mais simples é por exemplo dividir um FOR() pela metade a atribuir cada metade em cores diferentes, diminuindo o tempo de execução em até 50%. Apesar de parecer ser extremamente útil, há inúmeros problemas relacionados, como condição de corrida: o acesso simultâneo da mesma variável pode gerar erros em cálculos ou se o próprio calculo for dependentes de outros resultados, a paralelização disto é inconveniente, uma vez que utilizar semáforos para sincronizar as tarefas (exclusão mutua), pode ser mais lento que o simples código em sequencial. A questão à se pensar com uso de semáforos para sincronia de processos, deve ser analisada com o grau de granulação, uma vez que o uso excessivo de semáforos, pode deixar o processo mais lento que o código sequencial (single core).


Mãos à obra

Componentes necessários

Código do projeto

int tempo;//Variavel que armazena o tempo.

void setup()
{
	Serial.begin(115200);//Inicia a comunicaçao serial
	pinMode(2, OUTPUT);//Define o led Onboard como saída


	Serial.printf("\nsetup() em core: %d", xPortGetCoreID());//Mostra no monitor em qual core o setup() foi chamado
	xTaskCreatePinnedToCore(loop2, "loop2", 8192, NULL, 1, NULL, 0);//Cria a tarefa "loop2()" com prioridade 1, atribuída ao core 0
	delay(1);
}

void loop()//O loop() sempre será atribuído ao core 1 automaticamente pelo sistema, com prioridade 1
{
	Serial.printf("\n Tempo corrido: %d", tempo++);
	delay(1000);//Mantem o processador 1 em estado ocioso por 1seg
}

void loop2(void*z)//Atribuímos o loop2 ao core 0, com prioridade 1
{
	Serial.printf("\nloop2() em core: %d", xPortGetCoreID());//Mostra no monitor em qual core o loop2() foi chamado
	while (1)//Pisca o led infinitamente
	{
		digitalWrite(2, !digitalRead(2));
		delay(100);
	}
}

Colocando para funcionar

Podemos observar tanto no Serial Monitor quanto no ESP32, o funcionamento esperado do código. Enquanto o core 1 faz a contagem do tempo e espera 1seg para repetir a mensagem (o que o deixa em IDLE [travado]), o core 0 pisca o led, mostrando que um não interfere no outro.


Entendendo a fundo

Software

-Função xTaskCreatePinnedToCore()

xTaskCreatePinnedToCore(loop2, "loop2", 8192, NULL, 1, NULL, 0);

Esta função cria uma tarefa e atribuí a um especifico processador. O FreeRTOS pode definir automaticamente em qual core a tarefa será rodada, para isto, use xTaskCreate() (Mais informações no site FreeRTOS).

Neste caso, criamos a tarefa loop2, com "tamanho" de 8192 Bytes (words), nenhum parâmetro, prioridade 1 e atribuída ao core 0.

Vamos esclarecer os parâmetros em ordem (da esquerda à direita):

xTaskCreatePinnedToCore(pxTaskCodepcNameusStackDepthpvParametersuxPrioritypxCreatedTaskxCoreID)

pxTaskCode: Ponteiro para a tarefa, apenas o nome da tarefa.   loop2.

pcName: O nome (String) da tarefa (entre aspas), é usado para facilitar o debug.   "loop2".

usStackDepth: O tamanho de Stack reservada à tarefa, mais informações clique aqui.   8192.

pvParameters: O valor a ser passado para a tarefa no momento de criação. Nossa tarefa não precisa de parâmetros, então:   NULL.

uxPriority: A prioridade da tarefa. É comum se usar 1 para tarefas simples, já que funções de delay (IDLE) tem prioridade 0.   1.

Se duas tarefas com mesma prioridade estiverem na fila, a primeira da fila irá ser executada e depois a próxima. Caso uma tarefa com prioridade 1 esteja na fila, porém uma tarefa com prioridade 2 também, será executado a tarefa com prioridade 2 e depois as outras.

pxCreatedTask: Valor opcional caso seja necessário manipulação das tarefas (Handle).   NULL.

xCoreID: Atribuí a tarefa a um core especifico.   0.

Observações:

  • Se você por exemplo criar dois loops, ao chamar uma subrotina (função), ela será executada no core em que foi chamada.
  • Caso você não crie uma tarefa "infinita", será necessário deletar a tarefa com xTaskDelete().
  • No caso do loop2() criado, é necessário o uso de pelo menos delay(1) dentro do loop, para que o Task Watchdog não seja ativado. Há maneiras de contornar isso, mas precisa fazer alterações no BootLoader.

-Função xPortGetCoreID()

xPortGetCoreID()

Esta função retorna o core em que a tarefa esta sendo executada.


Fechamento

A computação paralela se mostra útil quando necessário alto poder computacional ou monitoramento de itens específicos. Este assunto é gigantesco, complicado e intrigante, foi mostrado apenas o básico sobre o assunto; se você quer se aprofundar mais, veja os PDFs que foram citados no começo.

Dúvidas? Sugestões? Críticas? Comente abaixo!

 


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

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

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

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

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

[toc]

Armazenando informações

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

Módulo micro SD

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

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

Sensor de temperatura e umidade DHT11

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

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

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

Componentes utilizados

Montando o projeto

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

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

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

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

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

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

Programando

- Bibliotecas

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

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

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

-  Código utilizado

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

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


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

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

bool cartaoOk = true;

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

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

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

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

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

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

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

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

Colocando pra funcionar

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


Entendendo a Fundo

Software

- Incluindo bibliotecas necessárias

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

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

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

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

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

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

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

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

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

- Função setup

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

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

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

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

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

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

- Variáveis de armazenamento

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

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

- Leitura da temperatura

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

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

- Leitura da umidade

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

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

- Validando a leitura dos dados

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

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

- String para gravação

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

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

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

- Gravando dados em arquivo

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

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

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

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

e em seguida fechamos o arquivo com:

dataFile.close();               // Fechamos o arquivo

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

delay(1500);

Desafio

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


Considerações finais

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


Usando o Display TFT 1.8" ST7735 com NodeMCU ou Arduino

Display TFT 1.8" ST7735 - Utilizando o display com o NodeMCU ou Arduino

A existência de uma interface de visualização de dados é algo muito importante tanto no desenvolvimento de um software quanto no mundo dos sistemas embarcados de maneira geral, de modo que, em virtude de sua importância, precisamos sempre estar construindo interfaces concisas e de fácil entendimento. Entretanto isso é uma tarefa bastante desafiadora no mundo maker, devido a baixa quantidade de recursos disponíveis nas plataformas utilizadas. Sendo assim, apresentamos o Display TFT 1.8" com o controlador ST7735, que por sua vez, consiste em um módulo bem interessante e que pode ser utilizado com o propósito citado.

Nesse tutorial focamos no uso do Display TFT 1.8" ST7735 usando a plataforma NodeMCU. Ainda assim, fizemos uma explicação de como fazer a mesma experiência usando a plataforma Arduino no Tópico: Usando o Display TFT 1.8" ST7735 na plataforma Arduino.

[toc]

O Display TFT 1.8" ST7735

Esta pequena tela tem uma resolução de 128x160 pixels, o que permite sua utilização como um pequeno painel de visualização, sendo possível até mesmo fazer o seu uso em mini computadores como o Raspberry Pi e o Orange Pi. Além disso, ela também conta com uma interface para conexão de cartões SD em sua parte traseira. A tela conta com um total de 8 pinos, sendo dois destes para alimentação, um para o backlight e os outros 5 para comunicação que é feita via SPI.

 Display TFT 1.8" ST7735
Display TFT 1.8" ST7735

Mãos à obra - Imprimindo informações no display usando um NodeMCU

Componentes utilizados:

Montando o projeto

Para realizar a montagem, iremos conectar os pinos na seguinte ordem:

A montagem final deve estar semelhante a imagem abaixo:

 Display TFT 1.8" ST7735

 Veja como ficou a nossa montagem na prática:

montagem Display TFT 1.8" ST7735

Se tudo estiver montado corretamente, quando o sistema for ligado teremos uma tela em branco.

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

Programando

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

Esse passo a passo foi tirado do tutorial: Conhecendo a Família ESP – Internet das coisas

– 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> NodeMCU 1.0 (caso esteja usando uma versão mais antiga do NodeMCU, pode ser que tenha que usar a versão 0.9)

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 seguir!

- Bibliotecas

Neste projeto estaremos utilizando duas bibliotecas, sendo uma para estabelecer a comunicação com o display, e outra para renderizar figuras de forma simplificada. Para isso, iremos fazer o download das duas bibliotecas da seguinte forma:

  •  Na ide do arduino, navegamos até a opção Sketch, selecionamos a opção Incluir biblioteca e navegamos até a opção Gerenciar Bibliotecas como mostra a figura abaixo:

  • Ao selecionar a opção Gerenciar bibliotecas, será aberto um painel como mostra a figura a seguir:
  • Nesta Janela iremos procurar as bibliotecas Adafruit ST7735 e Adafruit GFX Library, ambas podem ser instaladas através deste ambiente (Caso ocorra algum erro ou a imagem não apareça corretamente, a tela pode estar utilizando o controlador ILI9341, neste caso faça o download da biblioteca Adafruit ILI9341).
Biblioteca Adafruit ST7735

Biblioteca Adafruit GFX Library

- Programando

Agora que temos o nosso sistema montado, e as bibliotecas já instaladas, podemos partir para o código. Observem o código a seguir e que pode ser utilizado para diversos projetos.

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#define D3 0
#define D4 2 
#define D5 14 
#define D7 13 
#define D8 15 
#define TFT_CS     D8
#define TFT_RST    D4  
#define TFT_DC     D3
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST); // Instância do objeto tipo Adafruit_ST7735 que recebe como argumentos os pinos de controle
#define TFT_SCLK D5   
#define TFT_MOSI D7 
void setup(void){

  tft.setCursor(0,30); // Move o cursor para a coluna 30 na linha 0 
  tft.initR(INITR_BLACKTAB); // Inicializa a tela com um fundo preto
  tft.setTextSize(2); // Seta o tamanho da fonte de texto para o tamanho 2
  tft.fillScreen(ST7735_BLACK); // Preenche a tela com a cor preta
  tft.setTextColor(ST7735_BLUE); // Seta a cor do texto para Azul
  tft.print("Vida"); // Escreve a palavra Vida Com a cor que foi setada na linha acima
  tft.setTextColor(ST7735_WHITE); // Seta a cor do texto para Branco
  tft.print("De "); // Escreve a palavra Vida com a cor que foi setada na linha acima
  tft.setTextColor(ST7735_BLUE); // Seta a cor do texto para Azul
  tft.print("Silicio"); // Escreve a palavra Silício, com a cor que foi setada na linha acima

} 
void loop(){
  tft.invertDisplay(true); // Inverte as cores que estão na tela
  delay(500); // Aguarda 0,5 segundos
  tft.invertDisplay(false); // Volta as cores originais
  delay(500); // Aguarda 0,5 segundos
} 

Colocando para funcionar

Veja o resultado que obtivemos.

 Display TFT 1.8" ST7735
Display TFT 1.8"

Usando o Display TFT 1.8" ST7735 na plataforma Arduino

As bibliotecas da Adafruit de uma maneira geral possuem um grau bastante elevado de extensibilidade, ou seja podem ser utilizadas em diversas plataformas, como o nodeMCU e também o arduino. Caso você necessite utilizar este mesmo display em outra plataforma, como por exemplo o arduino uno, basta com que siga o padrão de conexão mostrado na tabela abaixo:

Já no código, podemos eliminar a grande parte dos #DEFINES criados anteriormente, utilizando apenas três pinos para estabelecer a comunicação, após isso, o código será exatamente o mesmo de antes.

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#define TFT_CS     10
#define TFT_RST    8  
#define TFT_DC     9
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST); // Instância do objeto tipo Adafruit_ST7735 que recebe como argumentos os pinos de controle
void setup(void){
  tft.setCursor(0,30); // Move o cursor para a coluna 30 na linha 0 
  tft.initR(INITR_BLACKTAB); // Inicializa a tela com um fundo preto
  tft.setTextSize(2); // Seta o tamanho da fonte de texto para o tamanho 2
  tft.fillScreen(ST7735_BLACK); // Preenche a tela com a cor preta
  tft.setTextColor(ST7735_BLUE); // Seta a cor do texto para Azul
  tft.print("Vida"); // Escreve a palavra Vida Com a cor que foi setada na linha acima
  tft.setTextColor(ST7735_WHITE); // Seta a cor do texto para Branco
  tft.print("De "); // Escreve a palavra Vida com a cor que foi setada na linha acima
  tft.setTextColor(ST7735_BLUE); // Seta a cor do texto para Azul
  tft.print("Silicio"); // Escreve a palavra Silício, com a cor que foi setada na linha acima
 
} 
void loop(){
  tft.invertDisplay(true); // Inverte as cores que estão na tela
  delay(500); // Aguarda 0,5 segundos
  tft.invertDisplay(false); // Volta as cores originais
  delay(500); // Aguarda 0,5 segundos
}

E pronto, agora temos o mesmo código sendo executado no arduino


Entendendo a Fundo

Software

– Incluindo as bibliotecas a serem utilizadas no projeto

Inicialmente, observe que foi necessário incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca Adafruit_GFX.h fornece um conjunto de funções gráficas para telas LCD e OLED simplificando o uso desses displays.

A biblioteca Adafruit_GFX sempre trabalha em conjunto com uma segunda biblioteca fornecida para cada tipo específico de display, no nosso caso usamos a biblioteca para o controlador ST7735: Adafruit_ST7735.h.

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library

Existem vários tipos de versões de display com controladores diferentes. Para conseguir usar o seu display adequadamente, é fundamental que se saiba exatamente qual o controlador para que consiga encontrar as bibliotecas especificas para ele.

– Declarando o objeto tft

Em seguida, cria-se o objeto que é responsável por realizar a troca de mensagens entre o nodeMCU e o display.  O método construtor da classe Adafruit_ST7735 recebe como parâmetros, os pinos responsáveis por interfacear a comunicação SPI entre o microcontrolador e o display.

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

Lembre-se: tft é apenas o nome que escolhemos, sendo assim, é importante ressaltar que, o objeto identificado por tft poderia ser chamado de qualquer outro nome, como por exemplo, lcd ou display, respectivamente.

- Movendo o cursor do LCD

tft.setCursor(0,30);

Essa função é responsável por mover o cursor responsável por escrever o texto na tela, neste caso o cursor será movido no eixo Y uma distância de 30 pixels da posição onde ela se encontra (no caso a posição 0,0), ficando este na posição (0,30).

- Inicializando a tela

Essa função inicializa o chip do controlador do display no caso o ST7735.

tft.initR(INITR_BLACKTAB);

- Definindo o tamanho da fonte

A biblioteca Adafruit_ST7735 conta com 5 tipos de tamanhos de fonte, sendo eles enumerados do menor 0 até o maior 5, e este valor sendo definido por um número inteiro.

tft.setTextSize(2);

- Preenchendo toda a tela com uma cor

A função fillScreen, como o próprio nome já diz, preenche tudo que está sob a tela com uma única cor, no caso sendo representada pelo define ST7735_NomedaCor.

tft.fillScreen(ST7735_BLACK);

- Definindo a cor do texto

De forma semelhante a função fillScreen, a função setTextColor muda a cor da fonte utilizada para escrever a mensagem desejada.

tft.setTextColor(ST7735_BLUE);

- Escrevendo na tela

A função print, escreve na tela o vetor de caracteres passados como parâmetro, porém é importante ressaltar que a cor e o tamanho da fonte serão sempre os últimos que foram setados antes da chamada desta função.

tft.print("Vida");

- Invertendo as cores do display

Já a função invertDisplay, inverte a cor de tudo que está sendo mostrado na tela no momento,caso o argumento repassado seja true,  caso seja false a cor não será invertida, ou voltará ao estado original.

tft.invertDisplay(true);

Veja que nesse programa inicializamos e escrevemos na tela na função setup() que é executada apenas umas vez. Na função loop() interagimos com a tela invertendo as cores do LCD.

Para um aplicação prática, em geral iremos escrever valores variáveis, tais como temperatura ou vazão. Nesse caso iremos trabalhar com as funções gráficas do display dentro da função loop().


Desafio

O desafio, para este tutorial, consiste em utilizar a seguinte função:

void desenhaCirculos(uint8_t radius, uint16_t color) {
  for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
    for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
      tft.drawCircle(x, y, radius, color);
    }
  }
}

Esta função possibilita o desenho de círculos em sequencia na tela, sendo estes espaçados com base em seu raio, ou seja, quanto menor o raio mais círculos teremos na tela, e quanto maior o raio, menos círculos serão desenhados na tela. Você consegue utilizando esta função desenhar círculos de tamanho variável na tela conforme o valor do raio varia ?


Considerações finais

Este tutorial, teve como objetivo apresentar um display muito utilizado como interface homem máquina em plataformas embarcadas. O seu baixo custo e bom funcionamento o tornam um módulo muito interessante de ser utilizado nos mais diversos tipos de aplicações, onde precisamos fornecer informações ao usuário. Espero que tenham gostado do conteúdo apresentado, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.