Termostato digital com display OLED, calibração automática, limite ajustável e alarme sonoro
O Thermostat é um termostato digital completo com interface gráfica em display OLED. Ele lê um potenciômetro como sensor de temperatura simulado (facilmente substituível por um sensor real como NTC/DHT11), processa as leituras com média de 60 amostras ao longo de 60 segundos e exibe a temperatura atual ao lado do limite configurável pelo usuário.
Quando a temperatura medida atinge ou ultrapassa o limite, o sistema dispara um alarme visual (caixa invertida com "MAX" no display) e sonoro (buzzer com padrão de bip não-bloqueante), sem travar a interface.
O projeto foi otimizado com três técnicas de performance simultâneas: amostragem de 1 Hz para precisão, display a 15 FPS para fluidez visual, e buzzer não-bloqueante para resposta rápida ao alarme.
| Quantidade | Componente | Especificação |
|---|---|---|
| 1x | Arduino Uno ou Nano | Microcontrolador ATmega328P |
| 1x | Display OLED SSD1306 | 128×64 px, interface I2C |
| 2x | Potenciômetro | 10kΩ linear |
| 1x | Buzzer piezoelétrico passivo | Conectado ao pino D8 |
| — | Jumper wires | Macho-macho |
| 1x | Protoboard | — |
Potenciômetro de Temperatura (A0):
- Pino central → A0
- Extremidade esquerda → GND
- Extremidade direita → 5V
- Faixa: 0–1023 ADC mapeado para 0–50°C
Potenciômetro de Limite (A1):
- Mesma ligação — ajusta o limite de 0 a 50°C instantaneamente
Ao ligar, o sistema entra em uma fase de calibração obrigatória. Durante 60 segundos, o Arduino:
- Coleta 1 leitura/segundo do sensor (A0)
- Acumula as leituras em
acumuladorLeituras - Exibe no display o progresso com um cabeçalho "CALIBRANDO Xs" e uma barra de progresso animada
if (contadorSegundos >= 60) {
long media = acumuladorLeituras / 60; // média das 60 amostras
temperatura_exibida = map(media, 0, 1023, 0, 50); // converte para °C
sistemaPronto = true;
}A calibração por média elimina leituras ruidosas e garante um valor estável logo na primeira exibição.
Após a calibração, o display exibe dois painéis lado a lado:
Painel esquerdo (84×46 px): temperatura atual em fonte grande com símbolo °C
Painel direito (42×46 px): limite configurado com rótulo "MAX"
Quando o alarme está ativo, o painel direito inverte para fundo sólido com texto branco e exibe um ícone piscante de som.
Para não sobrecarregar o barramento I2C — que bloquearia a leitura dos sensores — o display só é redesenhado a cada 66ms (~15 FPS):
if (millis() - ultimoFrame >= 66) {
ultimoFrame = millis();
u8g2.firstPage();
do { draw(); } while (u8g2.nextPage());
}A biblioteca U8g2 usa um buffer de página (_2_ no nome do construtor), que divide o display em faixas horizontais e envia cada faixa separadamente — reduzindo o uso de RAM em comparação com o buffer completo (_F_), que exigiria ~1KB apenas para o framebuffer.
O buzzer usa millis() para criar um padrão de bip sem delay():
| Estado | Duração |
|---|---|
Bip ligado (tone(8, 2000)) |
100ms |
Bip desligado (noTone(8)) |
1000ms |
if (estadoBuzzer) {
if (tempoAtual - tempoAnteriorBuzzer >= 100) {
estadoBuzzer = false;
noTone(pino_BUZZER);
}
} else {
if (tempoAtual - tempoAnteriorBuzzer >= 1000) {
estadoBuzzer = true;
tone(pino_BUZZER, 2000);
}
}Isso permite que o display e os sensores continuem funcionando normalmente durante o alarme.
O potenciômetro de limite (A1) é lido em todo ciclo do loop, sem amostragem, para que o usuário veja a alteração refletida imediatamente no display — melhor experiência de usuário ao girar o knob.
thermostat/
├── README.md # Esta documentação
└── sketch_thermostat/
└── sketch_thermostat.ino # Código completo do projeto
Instale via Arduino IDE → Tools → Manage Libraries:
| Biblioteca | Autor | Uso |
|---|---|---|
U8g2 |
Oliver Kraus | Driver universal para displays OLED/LCD, inclui fontes e gráficos |
Wire |
Arduino (built-in) | Comunicação I2C |
Por que U8g2 e não Adafruit SSD1306? A U8g2 oferece suporte a modo de buffer de página (menor uso de RAM), uma biblioteca de fontes muito mais rica (
u8g2_font_fur20_tfpara a temperatura grande,u8g2_font_8x13B_trpara os rótulos) e funções de desenho mais completas comodrawRBox()(retângulo com bordas arredondadas) edrawRFrame().
- Instale a biblioteca U8g2 via Library Manager.
- Monte o circuito conforme a pinagem acima.
- Abra o sketch:
sketch_thermostat/sketch_thermostat.inono Arduino IDE. - Selecione a placa:
Tools → Board → Arduino Uno(ou Nano). - Selecione a porta:
Tools → Port → COMx. - Faça upload:
Ctrl+U. - Aguarde os 60 segundos da fase de calibração — a barra de progresso indica o avanço.
- Após a calibração, gire o potenciômetro A0 para simular variação de temperatura.
- Gire o potenciômetro A1 para ajustar o limite de alarme.
- Quando a temperatura simulada atingir o limite, o buzzer bipa e o display exibe o alarme "MAX".
Para usar um sensor real (ex: NTC 10kΩ ou DHT11), substitua a leitura de A0:
NTC em divisor de tensão:
// Substitui: int leituraInstantanea = analogRead(pino_POT_AMBIENTE);
// Por:
int leituraInstantanea = analogRead(A0);
float tensao = leituraInstantanea * (5.0 / 1023.0);
float resistencia = 10000.0 * (5.0 / tensao - 1.0);
// Aplicar equação de Steinhart-Hart para converter resistência em °CDHT11/DHT22:
#include <DHT.h>
DHT dht(A0, DHT11);
float leituraInstantanea = dht.readTemperature() * (1023.0 / 50.0); // normaliza para escala 0-1023| Parâmetro | Valor |
|---|---|
| Faixa de temperatura exibida | 0–50°C |
| Taxa de amostragem do sensor | 1 Hz (1 leitura/segundo) |
| Período de calibração | 60 segundos |
| FPS do display | ~15 FPS (66ms/frame) |
| Frequência do bip de alarme | 2000 Hz |
| Padrão do bip | 100ms ON / 1000ms OFF |
| Velocidade do barramento I2C | 400 kHz (fast mode) |
| Buffer do display U8g2 | Modo página (_2_) |
Desenvolvido por Felipe Grolla

