0

Internet of Things IoT – Estação meteorológica com NodeMCU e OLED

Este projeto é direcionado para a Internet das Coisas (IoT) , desta vez com o microcontrolador NodeMCU! Neste artigo, desenvolveremos uma estação meteorológica doméstica, onde se exibirá informações tais como temperatura e condições climáticas, tanto para o dia corrente quanto para os próximos 3 dias. Nossa estação também exibirá informações internas da casa, como temperatura e humidade relativa do ar.

O diagrama em blocos abaixo, nos dá uma visão geral sobre o projeto:

No vídeo abaixo, pode ver como ficará o projeto final:

 

1: Lista de materiais

 

  • NodeMCU ESP8266-12E
  • 0.96″ I2C IIC SPI Serial 128X64 White OLED LCD LED Display Module
  • DHT22 AM2302 Temperature And Humidity Sensor
  • Mini BreadBoard
  • Male-Female Dupont Cables
  • Fonte externa de 5V ou bateria

2: Instalando o OLED no NodeMCU


Agora é hora de instalar nosso velho conhecido, o display OLED SSD1306, cujas principais caraterísticas são:

  • Tamanho do display: 0.96 “
  • Comunicação Serial I2C IIC SPI
  • 128X64
  • Display de carateres cor branca

Interligue os pinos do OLED ao NodeMCU, conforme descritos abaixo e no diagrama elétrico acima:

  • SDA ==> D1 (5)
  • SCL * ==> D2 (4) * Você também poderá encontrar “SDC” ao invés de SCL
  • VCC ==> 3.3V ou 5V
  • GND ==> GND

O SSD1306 pode ser alimentado tanto com 5V (externo) como com 3.3V fornecidos diretamente do módulo NodeMCU.
Depois de ligar o OLED, devemos fazer download e instalar a biblioteca no IDE do Arduino. Usamos em projetos anteriores a biblioteca desenvolvida pela ACROBOT, que apesar de fácil de usar, é mais limitada. Desta vez exploraremos a poderosa biblioteca gráfica desenvolvida por Daniel Eichhorn. No link abaixo e faça o download da biblioteca, instalando-a no IDE do Arduino:

https://github.com/squix78/esp8266-oled-ssd1306

Certifique-se de usar a versão 3.0.0 ou superior.
Depois de reiniciado o IDE, a biblioteca já deverá estar instalada.

A biblioteca suporta o protocolo I2C para aceder ao modulo OLED, usando a biblioteca Wire.h:

#include
#include "SSD1306.h"
SSD1306 display(ADDRESS, SDA, SDC);

Listaremos apenas algumas API mais importantes, as quais serão utilizadas com o OLED.

A. Controle de exibição do display:

void init(); // Initialise the display
void resetDisplay(void); // Cycle through the initialisation
void displayOn(void); // Turn the display on
void displayOff(void); // Turn the display offs
void clear(void); // Clear the local pixel buffer
void invertDisplay(void); // Inverted display mode
void normalDisplay(void); // Normal display mode
void setContrast(char contrast); // Set display contrast
void flipScreenVertically(); // Turn the display upside down

B. Desenho gráfico

void setColor(OLEDDISPLAY_COLOR color); // Sets the color of all pixel operations
void setPixel(int16_t x, int16_t y); // Draw a pixel at given position
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1); // Draw a line from position 0 to position 1
void drawHorizontalLine(int16_t x, int16_t y, int16_t length); // Draw a line horizontally
void drawVerticalLine(int16_t x, int16_t y, int16_t length); // Draw a lin vertically
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const char *image); // Draw a bitmap in the internal image format

C. Operações com texto:

void drawString(int16_t x, int16_t y, String text); // Write the text at given position
uint16_t getStringWidth(const char* text, uint16_t length); // Returns the width of the const char* with the current font settings
uint16_t getStringWidth(String text); // Convenience method for the const char version
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment); // TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH
void setFont(const char* fontData); // Sets the current font.
// Available default fonts: ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24

D. Frames (“Ui Library”)

A Ui Library é utilizada para fornecer um conjunto básico de elementos Ui chamados, Frames e Overlays. Um Frame é usado para fornecer informações onde o comportamento padrão é exibir um Frame por um tempo definido e passar para o próximo (como “Paginas”). A biblioteca também fornece um Indicador de qual frame (ou página) está sendo mostrada. Um overlay, por outro lado, é uma informação (por exemplo, um relógio) que é exibido sempre na mesma posição.

void init(); // Initialise the display
void setTargetFPS(uint8_t fps); //Configure the internal used target FPS
void enableAutoTransition(); //Enable automatic transition to next frame
void disableAutoTransition(); // Disable automatic transition to next frame.
void setAutoTransitionForwards(); // Set the direction if the automatic transitioning
void setAutoTransitionBackwards(); // Set the direction if the automatic transitioning
void setTimePerFrame(uint16_t time); //Set the approx. time a frame is displayed
void setTimePerTransition(uint16_t time); //Set the approx. time a transition will take
void setFrameAnimation(AnimationDirection dir); //Configure what animation is used to transition
void setFrames(FrameCallback* frameFunctions, uint8_t frameCount); //Add frame drawing functions
int8_t update(); // This needs to be called in the main loop

Uma vez que o OLED e sua biblioteca estejam instalados, escreveremos um simples programa, o “Hello World” para testá-los. Entre com o código abaixo em seu IDE, o resultado deverá ser algo como mostrado na foto:

/* Hello World OLED Test */
#include // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
SSD1306 display(0x3c, 5, 4); // Initialise the OLED display using Wire library
void setup()
{
Serial.begin(115200);
display.init(); // Initialising the UI will init the display too.
display.flipScreenVertically();

display.clear();
drawHelloWorld();
display.display();
}
void loop()
{

}
void drawHelloWorld()
{
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Hello world");
display.setFont(ArialMT_Plain_16);
display.drawString(0, 10, "Hello world");
display.setFont(ArialMT_Plain_24);
display.drawString(0, 26, "Hello world");
}

Agora, carregue a sketch: SSD1306SimpleDemo.ino, a qual faz parte dos EXEMPLOS incluídos com biblioteca.

Antes de executar o código, altere a ligação dos pinos OLED em conformidade:

 

// Initialise the OLED display using Wire library
SSD1306 display(0x3c, 5, 4);

O vídeo abaixo mostra o OLED executando o código teste:

 

3: Obtendo os dados internos (“Indoor”)

Neste momento, nosso NodeMCU já pode comunicar com o mundo pelo display. Instalemos agora um sensor digital de Temperature e Humidade, o nosso habitual DHTxx (DHT11 ou DHT22). O site da ADAFRUIT fornece ótimas informações sobre esses sensores. Abaixo, algumas informações retiradas do site:

Visão geral

Os sensores de temperatura e humidade de baixo custo da família DHT, são muito básicos e lentos, mas ótimos para hobbies ou pequenos projetos domésticos. Os sensores DHT são construídos em duas partes, um sensor de humidade capacitiva e um termistor. Há também um chip muito básico no interior que faz a conversão analógica para digital. O sinal digital gerado é bastante simples de ser lido usando-se qualquer micro controlador como o Arduino, Raspberry Pi ou outros.

DHT11 vs DHT22

Temos duas versões do sensor DHT, eles se parecem e têm a mesma pinagem, mas possuem algumas características diferentes. Aqui estão as especificações:

DHT11

  • Bom para leituras de 20-80% de humidade com 5% de precisão
  • Bom para leituras de temperatura de 0-50 ° C ± 2 ° C de precisão
  • Não mais de 1 Hz taxa de amostragem (uma vez por segundo)
  • Ultra baixo custo
  • Alimentação: 3 a 5V
  • Consumo: 2.5mA max (durante a conversão de dados)
  • Tamanho do corpo 15.5mm x 12mm x 5.5mm
  • 4 pinos com espaçamento de 0,1″

DHT22

  • Bom para leituras de 0-100% de humidade com precisão de 2 a 5%
    Bom para leituras de temperatura de -40 a 125 ° C Precisão de ± 0,5 ° C
    Não mais de 0,5 Hz taxa de amostragem (uma vez a cada 2 segundos)
    Baixo custo
    Alimentação: 3 a 5V
    Consumo: 2.5mA max (durante a conversão de dados)
    Tamanho do corpo 15.1mm x 25mm x 7.7mm
    4 pinos com espaçamento de 0,1″

Como pode ver, o DHT22 é um pouco mais preciso e melhor sobre um intervalo ligeiramente maior. Ambos usam um único pino digital e são “lentos”, pois você não pode consultá-los mais de uma vez a cada segundo (DHT11) ou dois (DHT22).

Ambos os sensores funcionam bem para obter informações sobre o interior da casa a serem exibidas em nossa Estação Meteorológica Doméstica.

O DHTxx tem 4 pinos (olhando para o sensor, como mostra a foto, o pino 1 é o mais à esquerda):

  1. VCC (conectado a 5V externo ou a 3.3V de NodeMCU)
  2. Dados
  3. Não conectado
  4. Terra.

Uma vez que normalmente usará o sensor em distâncias inferiores a 20m, um resistor de 10K ohms deve ser conectado entre os pinos Data e VCC. O pino de saída será conectado ao pino D3 do NodeMCU (veja o diagrama acima).

Uma vez instalado o sensor em nosso módulo, faça o download da biblioteca DHT do repositório GitHub da Adafruit e instale-o no arquivo de bibliotecas do Arduino.

Uma vez recarregado o IDE do Arduino, a “biblioteca de sensores DHT” deverá estar instalada.

Definamos os parâmetros e variáveis associadas para o sensor (usaremos em primeiro lugar o DHT22):

/* DHT22 */
#include "DHT.h"
#define DHTPIN D3
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
int localHum = 0;
int localTemp = 0;
Agora criaremos uma função para leitura dos dados:

/***************************************************
* Get indoor Temp/Hum data
****************************************************/
void getDHT()
{
float tempIni = localTemp;
float humIni = localHum;
localTemp = dht.readTemperature();
localHum = dht.readHumidity();
if (isnan(localHum) || isnan(localTemp)) // Check if any reads failed and exit early (to try again).
{
Serial.println("Failed to read from DHT sensor!");
localTemp = tempIni;
localHum = humIni;
return;
}
}

Uma vez de posse dos dados, usemos o OLED para mostrá-los:

/***************************************************
* Draw Indoor Page
****************************************************/
void drawDHT()
{
int x=0;
int y=0;
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0 + x, 5 + y, "Hum");

display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(43 + x, y, "INDOOR");
display.setFont(ArialMT_Plain_24);
String hum = String(localHum) + "%";
display.drawString(0 + x, 15 + y, hum);
int humWidth = display.getStringWidth(hum);
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(95 + x, 5 + y, "Temp");
display.setFont(ArialMT_Plain_24);
String temp = String(localTemp) + "°C";
display.drawString(70 + x, 15 + y, temp);
int tempWidth = display.getStringWidth(temp);
}

A foto abaixo mostra como os dados serão apresentados no display:

Poderá fazer o download do código completo para operação “indoor” a partir do GitHub:

Home Weather Station Indoor code

4: Obtendo os dados externos (“Outdoor”):

Nossos dados meteorológicos serão fornecidos por um serviço gratuito, o “Weather Underground“. Você precisará criar uma conta em seu site e obter uma chave para poder se utilizar da API. Faça-o, seguindo as instruções no link abaixo:

https://www.wunderground.com/weather/api

Nossa estação meteorológica doméstica é baseada no extraordinário trabalho desenvolvido por Daniel Eichhorn (@ squix78). Siga as instruções constantes de seu GitHub para obter as bibliotecas apropriadas. Você precisará ao menos, instalar as bibliotecas abaixo:

Depois de ter as bibliotecas instaladas e o IDE reiniciado, baixe o programa completo a partir de meu GitHub:

MJRoBot Home Weather Station code

Depois de ter o código carregado no IDE do Arduino, abra o arquivo stationCredentials.h e entre com seus dados pessoais:

/* WIFI */
const char* WIFI_SSID = "YOUR SSID";
const char* WIFI_PWD = "YOUR PASSWORD";
/* Wunderground Settings */
const boolean IS_METRIC = true;
const String WUNDERGRROUND_API_KEY = "YOUR KEY";
const String WUNDERGRROUND_LANGUAGE = "EN";
const String WUNDERGROUND_COUNTRY = "CL";
const String WUNDERGROUND_CITY = "Santiago";

Observe que as informações meteorológicas que iremos recuperar do serviço W.Underground serão sobre Santiago (“city”) e CL (“country”: Chile). Você também deve alterá-las com os dados de sua cidade.

Sua estação meteorológica doméstica deverá estar funcionando agora! Nas fotos abaixo, você pode ver meu protótipo funcionando:

5: Colocando a estação “na caixa”

A última etapa é montar nossa estação em uma caixa. Fiz duas montagens diferentes em caixas plásticas. Agora cada um decide a melhor maneira de “empacotar” seu projeto.

 

Em outra montagem, aproveitei e também testei a estação com o DHT11.

Não se esqueça de alterar os dados do DHT no arquivo “stationDefines.h”.

 

6: Conclusão

Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica e do IoT!

Visite o meu depositário no GitHub para obter os arquivos atualizados:

MJRoBot Home Weather Station depository

 

Via MJRobot

Comments

Comentários

ArduinoPortugal.pt

Deixar uma resposta