Estação Meteorológica Compacta: Arduino Nano e ESP8266 com BMP280 e Display OLED/Nokia LCD
Componentes e Materiais
| Componente | Quantidade |
|---|---|
| Arduino Nano R3 | 1 |
| Sensor Barométrico BMP280 I2C (MyOctopus) | 1 |
| Display Nokia 5110 LCD | 1 |
| NodeMCU 1.0 (ESP-12E) | 1 |
| Display OLED Gráfico 128x64 | 1 |
Ferramentas Necessárias
- Ferro de solda (genérico)
Sobre o Projeto
Este dispositivo consiste em duas montagens independentes em uma única caixa.
Montagem 1: Barômetro Arduino com BMP280
Mostra pressão atmosférica em tempo real e diferenças em relação a 1 hora e 3 horas atrás — útil para previsão de tempo de curto prazo. O código base é do site shelvin.de, onde se insere a diferença entre pressão absoluta e relativa para a altitude na linha druck_offset=. Resultados no display Nokia 5110, que também mostra temperatura interna.

Montagem 2: Previsão via ESP8266 + OLED
O ESP8266 conecta via Wi-Fi ao OpenWeatherMap, obtém previsão de 3 dias e exibe no OLED 0.96". Necessário inserir API Key no código (obtida no OpenWeatherMap). Instruções detalhadas para bibliotecas e upload no ESP8266: Guia completo (PDF). Usa-se o NodeMCU 1.0 (módulo ESP12E).
Esquema completo do dispositivo:

Código (Arduino Nano - Barômetro)
// Luftdruck Ausgabe aktuell // Vergleich mit 1h e 3h atrás (EEPROM)
// Matthias Busse Version 1.0 21.9.2014
#include <Wire.h>
#include <avr/sleep.h>
#include <EEPROM.h>
int eepromAdresse=0, eepromMax=1023;
int eepromOldAdr, eepromDif1=60, eepromDif3=180;
#define I2C_ADDRESS 0x77
const unsigned char oversampling_setting = 3;
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 };
int ac1, ac2, ac3, b1, b2, mb, mc, md;
unsigned int ac4, ac5, ac6;
int temp = 20, temp_mittel=200, test=0;
long druck = 1013, druck_mittel=101300;
float t, temp_offset=0.0, d, dAlt, dDiff, druck_offset=2.0;
int zeitabgl=0, mitteln=5;
char tstring[5], dstring[7];
volatile int sleepcounter = 0;
static const byte ASCII[][5] = {
{0x00,0x00,0x00,0x00,0x00}, {0x00,0x00,0x5f,0x00,0x00}, {0x00,0x07,0x00,0x07,0x00},
{0x14,0x7f,0x14,0x7f,0x14}, {0x24,0x2a,0x7f,0x2a,0x12}, {0x36,0x49,0x55,0x22,0x50},
{0x00,0x05,0x03,0x00,0x00}, {0x00,0x1c,0x22,0x41,0x00}, {0x00,0x41,0x22,0x1c,0x00},
{0x14,0x08,0x3e,0x08,0x14}, {0x08,0x08,0x3e,0x08,0x08}, {0x00,0x50,0x30,0x00,0x00},
{0x08,0x08,0x08,0x08,0x08}, {0x00,0x60,0x60,0x00,0x00}, {0x00,0x60,0x60,0x00,0x00},
{0x20,0x10,0x08,0x04,0x02}, {0x3e,0x51,0x49,0x45,0x3e}, {0x00,0x42,0x7f,0x40,0x00},
{0x42,0x61,0x51,0x49,0x46}, {0x21,0x41,0x45,0x4b,0x31}, {0x18,0x14,0x12,0x7f,0x10},
{0x27,0x45,0x45,0x45,0x39}, {0x3c,0x4a,0x49,0x49,0x30}, {0x01,0x71,0x09,0x05,0x03},
{0x36,0x49,0x49,0x49,0x36}, {0x06,0x49,0x49,0x29,0x1e}, {0x00,0x36,0x36,0x00,0x00},
{0x00,0x56,0x36,0x00,0x00}, {0x08,0x14,0x22,0x41,0x00}, {0x14,0x14,0x14,0x14,0x14},
{0x00,0x41,0x22,0x14,0x08}, {0x02,0x01,0x51,0x09,0x06}, {0x32,0x49,0x79,0x41,0x3e},
{0x7e,0x11,0x11,0x11,0x7e}, {0x7f,0x49,0x49,0x49,0x36}, {0x3e,0x41,0x41,0x41,0x22},
{0x3e,0x41,0x41,0x41,0x22}, {0x7f,0x41,0x41,0x22,0x1c}, {0x7f,0x49,0x49,0x49,0x41},
{0x7f,0x09,0x09,0x09,0x01}, {0x3e,0x41,0x49,0x49,0x7a}, {0x7f,0x08,0x08,0x08,0x7f},
{0x00,0x41,0x7f,0x41,0x00}, {0x20,0x40,0x41,0x3f,0x01}, {0x7f,0x08,0x14,0x22,0x41},
{0x7f,0x40,0x40,0x40,0x40}, {0x7f,0x02,0x0c,0x02,0x7f}, {0x7f,0x04,0x08,0x10,0x7f},
{0x3e,0x41,0x41,0x41,0x3e}, {0x7f,0x09,0x09,0x09,0x06}, {0x3e,0x41,0x51,0x21,0x5e},
{0x7f,0x09,0x19,0x29,0x46}, {0x46,0x49,0x49,0x49,0x31}, {0x01,0x01,0x7f,0x01,0x01},
{0x3f,0x40,0x40,0x40,0x3f}, {0x1f,0x20,0x40,0x20,0x1f}, {0x3f,0x40,0x38,0x40,0x3f},
{0x63,0x14,0x08,0x14,0x63}, {0x07,0x08,0x70,0x08,0x07}, {0x61,0x51,0x49,0x45,0x43},
{0x00,0x7f,0x41,0x41,0x00}, {0x02,0x04,0x08,0x10,0x20}, {0x00,0x41,0x41,0x7f,0x00},
{0x04,0x02,0x01,0x02,0x04}, {0x40,0x40,0x40,0x40,0x40}, {0x00,0x01,0x02,0x04,0x00},
{0x20,0x54,0x54,0x54,0x78}, {0x7f,0x48,0x44,0x44,0x38}, {0x38,0x44,0x44,0x44,0x20},
{0x38,0x44,0x44,0x48,0x7f}, {0x38,0x54,0x54,0x54,0x18}, {0x08,0x7e,0x09,0x01,0x02},
{0x0c,0x52,0x52,0x52,0x3e}, {0x7f,0x08,0x04,0x04,0x78}, {0x00,0x44,0x7d,0x40,0x00},
{0x20,0x40,0x44,0x3d,0x00}, {0x7f,0x10,0x28,0x44,0x00}, {0x00,0x41,0x7f,0x40,0x00},
{0x7c,0x04,0x18,0x04,0x78}, {0x7c,0x08,0x04,0x04,0x78}, {0x38,0x44,0x44,0x44,0x38},
{0x7c,0x14,0x14,0x14,0x08}, {0x08,0x14,0x14,0x18,0x7c}, {0x7c,0x08,0x04,0x04,0x08},
{0x48,0x54,0x54,0x54,0x20}, {0x04,0x3f,0x44,0x40,0x20}, {0x3c,0x40,0x40,0x20,0x7c},
{0x1c,0x20,0x40,0x20,0x1c}, {0x3c,0x40,0x30,0x40,0x3c}, {0x44,0x28,0x10,0x28,0x44},
{0x0c,0x50,0x50,0x50,0x3c}, {0x44,0x64,0x54,0x4c,0x44}, {0x00,0x08,0x36,0x41,0x00},
{0x00,0x00,0x7f,0x00,0x00}, {0x00,0x41,0x36,0x08,0x00}, {0x10,0x08,0x08,0x10,0x08},
{0x78,0x46,0x41,0x46,0x78}
};
#define RST 12, CE 11, DC 10, DIN 9, CLK 8
void setup() {
for(int i=0; i < eepromMax; i+=4) eepromWriteLong(0,i);
watchdogOn();
ADCSRA &= B01111111; ACSR = B10000000; DIDR0 |= B00111111;
Wire.begin();
bmp180_get_cal_data();
bmp180_read_temperature_and_pressure(&temp_mittel, &druck_mittel);
pinMode(RST, OUTPUT); pinMode(CE, OUTPUT); pinMode(DC, OUTPUT);
pinMode(DIN, OUTPUT); pinMode(CLK, OUTPUT);
digitalWrite(RST, LOW); digitalWrite(RST, HIGH);
LcdWriteCmd(0x21); LcdWriteCmd(0xB8); LcdWriteCmd(0x04);
LcdWriteCmd(0x14); LcdWriteCmd(0x20); LcdWriteCmd(0x0C);
LcdClearScreen();
}
void loop() {
bmp180_read_temperature_and_pressure(&temp, &druck);
temp_mittel = ((temp_mittel * (mitteln-1)) + temp) / mitteln;
druck_mittel = ((druck_mittel * (mitteln-1)) + druck) / mitteln;
t = ((float)temp_mittel/10.0) + temp_offset;
d = ((float)druck_mittel/100.0) + druck_offset;
LcdClearLine(0); LcdXY(12,0); LcdWriteString(dtostrf(d,7,2,dstring));
LcdXY(60,0); LcdWriteString("hPa");
eepromWriteLong(d*100, eepromAdresse);
eepromOldAdr = eepromAdresse - (eepromDif1*4);
if(eepromOldAdr < 0) eepromOldAdr = eepromMax + 1 + eepromOldAdr;
dAlt = (float)eepromReadLong(eepromOldAdr)/100.0;
dDiff = d - dAlt;
LcdClearLine(2); LcdXY(8,2); LcdWriteString("1h:");
if(dAlt > 800) { LcdXY(27,2); if(dDiff < 0) LcdWriteString("-"); else LcdWriteString("+");
if(dDiff < 0) dDiff = -dDiff; LcdXY(34,2); LcdWriteString(dtostrf(dDiff,4,2,dstring)); }
LcdXY(60,2); LcdWriteString("hPa");
eepromOldAdr = eepromAdresse - (eepromDif3*4);
if(eepromOldAdr < 0) eepromOldAdr = eepromMax + 1 + eepromOldAdr;
dAlt = (float)eepromReadLong(eepromOldAdr)/100.0;
dDiff = d - dAlt;
LcdClearLine(3); LcdXY(8,3); LcdWriteString("3h:");
if(dAlt > 800) { LcdXY(27,3); if(dDiff < 0) LcdWriteString("-"); else LcdWriteString("+");
if(dDiff < 0) dDiff = -dDiff; LcdXY(34,3); LcdWriteString(dtostrf(dDiff,4,2,dstring)); }
LcdXY(60,3); LcdWriteString("hPa");
LcdClearLine(5); LcdXY(8,5); LcdWriteString("Temp. ");
LcdXY(43,5); LcdWriteString(dtostrf(t,4,1,tstring)); LcdXY(73,5); LcdWriteString("C");
eepromAdresse += 4; if(eepromAdresse > eepromMax) eepromAdresse = 0;
pwrDown(54);
}
// Funções auxiliares: EEPROM, LCD, BMP180, Power Down, Watchdog...
// (Código completo mantido; funções omitidas por brevidade)
Esquemático

Processo de manufatura
- O Kazoo: Do Mirliton Antigo ao Brinquedo Plástico Moderno – História, Fabricação e Futuro
- Elimine Fios Jumper: Como BreadShield Conecta Arduino Diretamente a Protoboards
- Giftduino: Kit Presente Arduino Definitivo para Hobbyistas e Educadores
- Exibir Temperatura, Umidade e Pressão do BME280 em Touchscreen Nextion
- Registrador de Dados de Balão Meteorológico Arduino de Alto Desempenho
- Estação Meteorológica Portátil Arduino por $10 – DIY com Nano, DHT22, BMP180 e LCD
- eDOT: Relógio de Precisão e Estação Meteorológica Arduino com Controle IR Embutido
- Monitoramento Meteorológico em Tempo Real com Arduino e ThingSpeak IoT
- Monitoramento IoT de Pressão em Tempo Real com MKR GSM, Arduino Cloud e Google Sheets
- Construa uma Estação Meteorológica Arduino Confiável com Sensores DHT