Higrômetro de Espelho Resfriado DIY com Arduino: Monitoramento Preciso de Temperatura e Umidade
Componentes e Materiais
- 1x Arduino UNO
- 1x Fonte 12V 10A
- 1x Ventoinha 12V 40mm alta potência
- 1x TEC 12V 40mm (Peltier)
- 1x Dissipador 40mm
- 1x Espelho pequeno
- 1x Adesivo termicamente condutivo
- 1x Pasta térmica
- 1x Driver motor BTS7960
- 1x LED 3mm Amarelo
- 1x Sensor de luz OPT101
- 1x Módulo MOSFET IRF520
- 1x Termômetro digital DS18B20 (1-Wire)
- 1x Sensor umidade/temperatura Si7021 (SparkFun Breakout)
Ferramentas Necessárias
- Pistola de cola quente
Aplicativos e Serviços Online
- Arduino IDE
Sobre o Projeto
Sobre
Medir umidade pode ser feito de várias formas. O mais popular é sensor capacitivo. Infelizmente, perdem precisão rapidamente quando operados continuamente em ambiente muito úmido. Um Higrômetro de Espelho Resfriado (Chilled Mirror Hygrometer) não sofre deste problema e é muito mais preciso, especialmente em alta umidade. Infelizmente, um comercial custa literalmente milhares de dólares. A operação básica é simples, então é possível fazer um. Não terá precisão de 0,1 grau do comercial, mas para a maioria dos propósitos é suficiente e certamente mais preciso que sensor capacitivo.
Este projeto é prova de conceito, não pronto para produção. Muitas melhorias possíveis, mas prova que funciona.
Como Funciona
Um Higrômetro de Espelho Resfriado usa Peltier (TEC) para resfriar superfície reflexiva até aparecer condensação. A condensação é detectada com fonte de luz e sensor óptico. A temperatura da superfície do espelho é registrada no momento que condensação aparece. Esta temperatura equivale ao ponto de orvalho. A Umidade Relativa pode então ser calculada usando ponto de orvalho e temperatura ambiente.
Simplificações (vs. Comercial)
- Espelho: Comercial usa platina/ródio sobre cobre (melhor condutividade térmica). Aqui uso espelho comum. Lâminas de aço inox polido seriam melhores.
- Sensor de temperatura: Comercial usa PRT (Termômetro de Resistência de Platina) embutido sob espelho. Aqui uso sensor SMD montado na superfície — modifica distribuição de calor, reduz precisão, mas muito mais fácil de construir.
- Tamanho: Comercial usa espelho ~5mm (menos potência, menor). Aqui uso 4cm. Peltier pequeno requer voltagem muito baixa e driver customizado. Difícil montar sensor SMD em espelho pequeno deixando espaço para reflexão.
- Caixa bloqueadora de luz: Versão atual não tem. Recomenda-se impressão 3D para bloquear luz externa e fixar fonte/sensor. Deve ser bem ventilada (usar ventoinha do Peltier para ventilação, aspirar ar para dentro, não soprar). Interior deve ser acessível para limpeza do espelho.
- Ponto de geada: Implementação atual não mede ponto de geada (requer diferenciar cristais de gelo de gotas d'água, precisando segundo sensor óptico para luz espalhada).
Como Construir
- Pegue o Peltier, limpe ambas superfícies, aplique adesivo termicamente condutivo no lado quente. Distribua uniformemente. Se não tiver adesivo, use pasta térmica com algumas gotas de supercola nas bordas. Limpe superfície do dissipador e pressione dissipador + Peltier; deixe secar.
- Após secar, fixe o espelho da mesma forma, limpando a face inferior primeiro. Importante: pasta térmica uniforme e sem bolhas de ar, senão distribuição de calor no espelho será não uniforme.
- Quando tudo seco, fixe a ventoinha. Use ventoinha potente para resfriar dissipador (esquenta bastante). Como fixar depende do dissipador; usei cola quente.
Ligue ventoinha, depois Peltier para verificar se há pelo menos duas áreas no espelho onde condensação aparece simultaneamente. Não ligue Peltier por muito tempo (criaria perfil uniforme). Quer ver quando condensação apenas começa a ficar visível. Se não gostar, tente novamente com novo Peltier, espelho e dissipador (difícil remover e restaurar superfície lisa).
Importante: Fotografe ou marque área onde condensação aparece uniformemente — é onde deve montar sensor de temperatura da superfície e medir luz refletida.
Neste projeto uso Si7021 para temperatura do espelho (saída com baixo ruído). Endereço I2C fixo, então só pode usar um. Para temperatura ambiente uso DS18B20 (precisão não muito alta). Usei estes por estarem disponíveis.
Para montar Si7021 (ou qualquer sensor PCB) no espelho: coloque grande gota de pasta térmica não condutiva eletricamente no sensor. PCB também coberta com pasta para evitar condensação na eletrônica. Coloque 4 grandes gotas de cola quente nos cantos do PCB. Movimento rápido. Pressione sensor contra espelho no local onde condensação apareceu uniformemente. Certifique-se que sensor fique horizontal e pressione firmemente. Cola quente solidifica rápido ao tocar espelho. Se precisar reposicionar, raspe com estilete, remova cola e tente novamente. Se houver condensação no PCB, isole com cola quente ou spray plástico.
Ventoinha controlada por módulo MOSFET IRF520.
Sensor de luz: OPT101 (sensível, baixo ruído, fácil uso).
Fonte de luz: laser diodo baixa potência ou LED comum. Testados ambos — funcionam. Laser: melhor resposta, mais difícil alinhar. LED: resposta mais plana (mais luz espalhada), mais fácil alinhar. Se LED, use feixe focado.
Saída de luz do LED/laser provavelmente alta demais. PWM não é opção (causa interferência no sensor). Coloque resistor em série para reduzir saída.
Para montar LED/laser e OPT101, usei fio de cobre torcido em "locking wire" para rigidez. Fixado com cola quente. Bom para prova de conceito, mas frágil para uso fora de laboratório. Melhor: imprimir suporte 3D (também porque caixa 3D é obrigatória para bloquear luz externa).
Para controlar Peltier, uso driver motor BTS7960. Forma mais eficiente é variar corrente, não PWM. Controladores de Peltier não são tão disponíveis quanto BTS7960; para prova de conceito, consumo não é fator.
Montado, carregue código no Arduino e ajuste sensibilidade do OPT101 com potenciômetro. Resistência maior = tensão de saída maior para mesma luz. Consulte datasheet OPT101, Figura 3. Para debug: sopre no espelho para criar condensação, ou coloque objeto na frente do sensor. Se tem ar condicionado, ligue/desligue e espere — verá mudança de umidade.
No gráfico: temperatura (azul), leitura óptica (vermelho), ponto de orvalho medido (verde). Ponto de orvalho sobe ao desligar ar condicionado.
Segurança
Embora código não suporte, hardware pode aquecer espelho além de resfriar (inverter polaridade no Peltier). Aquecimento remove condensação rápido e melhora tempo de resposta. Evaporação rápida remove contaminantes. Porém, risco: superfície do espelho não tem dissipador. Se código travar aquecendo, no mínimo derrete cola do termômetro; pior, incêndio por fios derretidos causando curto.
Precisão
Como ponto de orvalho medido é valor absoluto, calibração não é tão crítica quanto higrômetro capacitivo/resistivo. Porém, haverá diferença de temperatura entre área do sensor de superfície e área de detecção de luz. Para verificar precisão, calibre com Higrômetro de Espelho Resfriado comercial calibrado.
Contaminação do espelho é problema parcial. Leitura de luz refletida não é absoluta, mas relativa ao início do ciclo de resfriamento. No início, espelho livre de condensação. Luz refletida medida como referência para detectar condensação. Se espelho contaminado e reflete menos luz, não deve afetar detecção. Porém, alguns contaminantes alteram temperatura de condensação — para melhor precisão, limpe espelho periodicamente.
Sensores de temperatura não precisam alta precisão calibrada, mas resolução alta. Ex: se real 24,0°C mas mede 24,5°C, ok desde que ambos (espelho e ambiente) meçam 24,5°C (normalizável) e jitter apenas uma decimal. Muitos termômetros têm jitter 0,2-0,3°C. Melhor usar TSYS01 para ambos (precisão 0,1°C igual a PRT).
Contato térmico bom entre sensor e espelho é imperativo — use pasta térmica não condutiva.
Não resfrie espelho mais rápido que tempo de resposta do termômetro, senão ponto de orvalho detectado será impreciso.
Sensor deve ser colocado onde condensação da área de detecção de luz aparece simultaneamente.
Montar sensor na superfície modifica distribuição de calor, reduzindo precisão. Termômetro infravermelho seria alternativa, mas espelho reflete radiação térmica, influenciando medição pelo entorno.
Teoricamente, leitura de umidade depende de pressão barométrica, mas efeito é minúsculo em ambientes. Mudanças de pressão por portas batendo, vento fora causando pressão diferencial em prédio causam mais problemas que valem.
Ar quente do dissipador do Peltier não deve ser aspirado sobre o espelho.
Queda lenta de temperatura dá leituras mais precisas, mas reduz tempo de resposta. Resposta pode ser melhorada oscilando temperatura próxima ao ponto de orvalho.
Código: Chilled Mirror Hygrometer
#include <math.h>
#include <avr/wdt.h> // Watchdog crash detection
#include "Si7021.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "timer.h"
#include "timerManager.h"
#define coolingPWM 6
#define heatingPWM 5
#define coolingEnable 13
#define heatingEnable 12
#define tecFan 7
#define opticalSensor 0 // Analog in
#define oneWireBus A3
#define COOLING 0
#define HEATING 1
#define OFF 2
Timer timerMainLoop;
Timer timerTecCooling;
Timer timerSampleNoise;
Si7021 si7021;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
float humidity = 0;
float ambientTemp = 0;
float opticalDewpoint = 0;
float mirrorTemp = 30;
float optical = 30;
float dewPoint = 15;
float relativeHumidity = 30;
int tecState = OFF;
bool cooling = false;
int intervalTecCooling = 200;
float opticalThreshold = 0.5f;
int pwmIncrement = 1;
int startPwm = 100;
int maxPwm = 255;
int intervalMainLoop = 200;
int tecPwm = 0;
int noiseSampleIndex = 0;
int noiseSampleAmount = 10;
float noiseSampleHighest = 0;
float noiseSampleLowest = 10000;
bool noiseSampling = false;
float calculateHumidity(float TD, float T) {
if (TD > T) TD = T;
float rh = 100 * (exp((17.625 * TD) / (243.04 + TD)) / exp((17.625 * T) / (243.04 + T)));
return rh;
}
void SetTEC(int state, int amount) {
tecState = state;
switch (state) {
case COOLING:
digitalWrite(heatingEnable, HIGH);
analogWrite(heatingPWM, 0);
digitalWrite(coolingEnable, HIGH);
analogWrite(coolingPWM, amount);
break;
case HEATING:
digitalWrite(coolingEnable, HIGH);
analogWrite(coolingPWM, 0);
digitalWrite(heatingEnable, HIGH);
analogWrite(heatingPWM, amount);
break;
case OFF:
digitalWrite(coolingEnable, LOW);
analogWrite(coolingPWM, 0);
digitalWrite(heatingEnable, LOW);
analogWrite(heatingPWM, 0);
break;
default:
digitalWrite(coolingEnable, LOW);
analogWrite(coolingPWM, 0);
digitalWrite(heatingEnable, LOW);
analogWrite(heatingPWM, 0);
}
}
void setup() {
wdt_enable(WDTO_2S);
Serial.begin(9600);
pinMode(coolingPWM, OUTPUT);
pinMode(heatingPWM, OUTPUT);
pinMode(coolingEnable, OUTPUT);
pinMode(heatingEnable, OUTPUT);
pinMode(tecFan, OUTPUT);
pinMode(opticalSensor, INPUT);
timerMainLoop.setInterval(intervalMainLoop);
timerMainLoop.setCallback(mainLoop);
timerMainLoop.start();
timerTecCooling.setInterval(intervalTecCooling);
timerTecCooling.setCallback(tecCoolingCallback);
timerSampleNoise.setInterval(intervalTecCooling);
timerSampleNoise.setCallback(sampleNoiseCallback);
si7021.begin();
uint64_t serialNumber = si7021.getSerialNumber();
sensors.begin();
startNoiseSampling();
}
float getOptical() {
int opt = analogRead(opticalSensor);
return (float)opt / 30.0f;
}
void tecCoolingCallback() {
digitalWrite(tecFan, HIGH);
tecPwm += pwmIncrement;
if (tecPwm > maxPwm) tecPwm = maxPwm;
SetTEC(COOLING, tecPwm);
if (optical <= (noiseSampleLowest - opticalThreshold)) {
dewPoint = mirrorTemp;
opticalDewpoint = optical;
stopTec();
}
}
void startNoiseSampling() {
noiseSampling = true;
noiseSampleHighest = 0;
noiseSampleLowest = 10000;
timerSampleNoise.start();
}
void sampleNoiseReset() {
timerSampleNoise.stop();
noiseSampleIndex = 0;
noiseSampling = false;
}
void sampleNoiseCallback() {
if (noiseSampleIndex > noiseSampleAmount) {
sampleNoiseReset();
startTecCooling();
} else {
if (optical > noiseSampleHighest) noiseSampleHighest = optical;
if (optical < noiseSampleLowest) noiseSampleLowest = optical;
}
noiseSampleIndex++;
}
void startTecCooling() {
cooling = true;
digitalWrite(tecFan, HIGH);
tecPwm = startPwm;
timerTecCooling.start();
}
void stopTec() {
cooling = false;
digitalWrite(tecFan, LOW);
timerTecCooling.stop();
SetTEC(OFF, 0);
}
void mainLoop() {
sensors.setResolution(10);
sensors.requestTemperatures();
ambientTemp = sensors.getTempCByIndex(0);
mirrorTemp = si7021.measureTemperature();
optical = getOptical();
relativeHumidity = calculateHumidity(dewPoint, ambientTemp);
Serial.print(mirrorTemp, 2); Serial.print(" ");
Serial.print(optical, 2); Serial.print(" ");
Serial.println(dewPoint, 2);
if (!cooling && !noiseSampling && (optical >= noiseSampleLowest)) {
startNoiseSampling();
}
}
void loop() {
wdt_reset();
TimerManager::instance().update();
}
Esquemáticos
Diagrama de conexões incluído no projeto original.
Processo de manufatura
- A Ciência e a Arte dos Espelhos Modernos
- Construa um Spybot Controlado por Bluetooth com Arduino
- FlickMote: Controle Remoto IR por Gestos para Casa Inteligente
- DIY Arduino TV B-Gone: Controle Remoto Universal para Todas as TVs
- Espelho Infinito Caleidoscópio DIY – Construa um Display de Luz LED Incrível
- Construa um Relógio Mestre LED Personalizado com Alarme – Visível a 12 Metros
- Find Me: Localizador Inteligente de Objetos com Arduino e Bluetooth
- Soluções de Energia Otimizadas para Projetos Arduino
- Jogo da Velha com Arduino, Matriz LED MAX7219 e Caixa de Papelão
- Construa um Robô Quadrúpede Inteligente com Arduino: Guia Passo a Passo