Início›Projetos›Estação Meteorológica
⬤ Intermédio · Projeto Integrado

🌤️ Estação Meteorológica

⏱️ 45–60 min📊 Intermédio🏫 Cenário LED oficial
DHTLDRBrilhoLED RGBBuzzerSerial CSV

Nesta página

🎯 Objetivo do Projeto

Construir uma estação meteorológica que meça temperatura, humidade relativa e luminosidade em tempo real. O sistema fornece alertas visuais (LED RGB) e sonoros (buzzer) quando os valores saem dos limites confortáveis, e envia dados via Serial para registo em ficheiro CSV no Raspberry Pi.

Temperatura
DHT11
Módulo #19 — pino D2
Humidade
DHT11
Módulo #19 — pino D2
Luminosidade
LDR
Módulo #22 — pino A0
Feedback visual
LED RGB
Módulo #27 — D9/D10/D11
Alerta sonoro
Buzzer P
Módulo #21 — pino D8
Registo
CSV
Via Serial → Raspberry Pi

🔌 Módulos e Pinagem

MóduloPino do móduloPino ArduinoNota
DHT11 (#19)VCC / GND / S5V / GND / D2Biblioteca Adafruit DHT obrigatória
LDR (#22)VCC / GND / AO5V / GND / A0Pino analógico — lê 0–1023
LED RGB (#27)VCC / GND / R / G / B5V / GND / D9 / D10 / D11Pinos PWM ~
Buzzer Passivo (#21)VCC / GND / S5V / GND / D8tone() para alertas melódicos
⚠️
Usa o mesmo GND para todos os módulos — liga-os ao mesmo pino GND do Arduino ou usa uma breadboard como barramento de GND. Módulos com GND flutuante dão leituras erradas.

🔨 Fases de Montagem

Fase 1 — DHT11: temperatura e humidade

Liga o DHT11 (VCC→5V, GND→GND, S→D2). Carrega o sketch de teste individual (Sensor DHT) e confirma que lê temperatura e humidade correctas no Serial Monitor antes de avançar.

Fase 2 — LDR: luminosidade

Adiciona o LDR (VCC→5V, GND→GND, AO→A0). Testa com Serial.println(analogRead(A0)) — valores ~100 com luz intensa, ~900+ no escuro. Ajusta conforme o teu ambiente.

Fase 3 — LED RGB: feedback visual

Liga o LED RGB (R→D9, G→D10, B→D11, GND→GND, VCC→5V). Testa as 3 cores individualmente com analogWrite() antes de integrar.

Fase 4 — Buzzer: alertas sonoros

Adiciona o buzzer passivo (S→D8, VCC→5V, GND→GND). Testa com tone(8, 1000, 300) — deve soar 300ms a 1kHz.

Fase 5 — Integração do sketch completo

Substitui os sketches de teste pelo sketch integrado abaixo. Ajusta os limiares TEMP_MAX, HUM_MAX e LUZ_MIN para o teu ambiente.

💻 Código Completo

proj_estacao_meteorologica.ino
#include <DHT.h>

// ── Pinos ───────────────────────────────────────────
#define DHT_PIN    2
#define LDR_PIN    A0
#define LED_R      9
#define LED_G      10
#define LED_B      11
#define BUZZER_PIN 8

// ── Limiares (ajusta ao teu ambiente) ───────────────
#define TEMP_MAX   28.0   // °C — acima: alerta vermelho
#define TEMP_MIN   15.0   // °C — abaixo: alerta azul
#define HUM_MAX    70.0   // % — acima: alerta
#define LUZ_MIN    200    // raw — abaixo: pouca luz (0–1023)
#define INTERVALO  3000   // ms entre leituras

DHT dht(DHT_PIN, DHT11);

void setCor(int r, int g, int b) {
  analogWrite(LED_R, r);
  analogWrite(LED_G, g);
  analogWrite(LED_B, b);
}

void bip(int freq, int ms) {
  tone(BUZZER_PIN, freq, ms);
}

void setup() {
  Serial.begin(9600);
  dht.begin();
  pinMode(LED_R, OUTPUT); pinMode(LED_G, OUTPUT); pinMode(LED_B, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);

  // Cabeçalho CSV — para registo no Raspberry Pi
  Serial.println("timestamp_ms,temperatura,humidade,luminosidade,estado");
}

void loop() {
  delay(INTERVALO);

  float t = dht.readTemperature();
  float h = dht.readHumidity();
  int   l = analogRead(LDR_PIN);

  if (isnan(t) || isnan(h)) {
    Serial.println("ERRO,ERRO,ERRO,ERRO,erro_sensor");
    return;
  }

  // Determinar estado e cor do LED
  String estado = "OK";
  if (t > TEMP_MAX) {
    setCor(255, 0, 0);            // Vermelho — calor
    bip(880, 400);
    estado = "temp_alta";
  } else if (t < TEMP_MIN) {
    setCor(0, 0, 255);            // Azul — frio
    bip(440, 400);
    estado = "temp_baixa";
  } else if (h > HUM_MAX) {
    setCor(0, 200, 255);          // Ciano — humidade alta
    bip(660, 300);
    estado = "hum_alta";
  } else if (l < LUZ_MIN) {
    setCor(255, 200, 0);           // Amarelo — pouca luz
    estado = "luz_baixa";
  } else {
    setCor(0, 255, 80);            // Verde — tudo OK
    estado = "OK";
  }

  // Linha CSV: timestamp,temp,hum,lux,estado
  Serial.print(millis()); Serial.print(",");
  Serial.print(t, 1);    Serial.print(",");
  Serial.print(h, 1);    Serial.print(",");
  Serial.print(l);        Serial.print(",");
  Serial.println(estado);
}

🍓 Registo CSV no Raspberry Pi

ℹ️
Liga o Arduino ao Raspberry Pi via USB. O Raspberry Pi vê o Arduino como uma porta série (/dev/ttyACM0). O script Python lê a porta série e escreve os dados num ficheiro CSV.
estacao_logger.py
#!/usr/bin/env python3
# Logger da Estação Meteorológica
# Lê dados do Arduino via Serial e guarda em CSV com timestamp real
# Instalar: pip3 install pyserial
import serial, csv, time
from datetime import datetime

PORTA   = "/dev/ttyACM0"   # ou /dev/ttyUSB0
BAUD    = 9600
FICHEIRO = f"estacao_{datetime.now().strftime('%Y%m%d_%H%M')}.csv"

with serial.Serial(PORTA, BAUD, timeout=5) as ser:
    with open(FICHEIRO, "w", newline="") as f:
        writer = csv.writer(f)
        # Ler e escrever cabeçalho
        cabecalho = ser.readline().decode().strip().split(",")
        cabecalho = ["data_hora"] + cabecalho[1:]  # substitui timestamp_ms
        writer.writerow(cabecalho)
        print(f"A registar em {FICHEIRO} ...")

        while True:
            linha = ser.readline().decode().strip()
            if not linha or "ERRO" in linha:
                continue
            campos = linha.split(",")
            if len(campos) >= 5:
                agora = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                writer.writerow([agora] + campos[1:])
                f.flush()
                print(f"{agora} | T:{campos[1]}°C H:{campos[2]}% L:{campos[3]} [{campos[4]}]")

🚀 Como Expandir o Projeto

🏆 Para ir mais longe

Kit B 37 · PR.FT6_15 · Arduino UNO · Raspberry Pi · Início · led.dge.medu.pt