Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

DIY зеркальный гигрометр на Arduino: точное измерение точки росы и влажности

Компоненты и материалы

Инструменты

Программное обеспечение

Принцип работы зеркального гигрометра

Пелтье охлаждает зеркало до появления конденсата. Оптический сенсор (OPT101) фиксирует падение отраженного света от светодиода/лазера. Температура зеркала в момент появления конденсата = точка росы. Относительная влажность рассчитывается по формуле Магнуса по точке росы и температуре воздуха.

Упрощения vs коммерческие приборы

Сборка

  1. Очистите ТЭК и радиатор. Нанесите термоклей на горячую сторону ТЭК, прижмите радиатор, дайте высохнуть.
  2. Точно так же приклейте зеркало на холодную сторону (термопаста + клей по краям). Равномерность слоя критична.
  3. Приклейте вентилятор на радиатор (дует через радиатор наружу).
  4. Подайте питание на вентилятор, кратковременно включите ТЭК — найдите зоны, где конденсат появляется одновременно. Запомните/промаркируйте.
  5. Приклейте Si7021 (температура зеркала) в эту зону: капля термопасты на сенсор, 4 капли горячего клея по углам PCB, прижмите к зеркалу. Изолируйте плату клеем от конденсата.
  6. Смонтируйте светодиод/лазер и OPT101 на жесткой медной проволоке (или 3D-держак), направьте луч на зеркало, приёмник — на отраженный луч.
  7. Управление ТЭК: BTS7960 (PWM на Pin 5/6, Enable на 12/13). Вентилятор — IRF520 на Pin 7.
  8. Настройте чувствительность OPT101 подстроечным резистором (см. даташит, Fig.3).

Безопасность

Код не поддерживает нагрев, но аппаратно возможно (смена полярности на BTS7960). Нагрев без радиатора на холодной стороне опасен: перегрев клея, пожар. Используйте WDT (см. проект 1010016401).

Точность и калибровка

Код (Chilled Mirror Hygrometer)

#include <math.h>
#include <avr/wdt.h>
#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 A0
#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, ambientTemp = 0, opticalDewpoint = 0;
float mirrorTemp = 30, optical = 30, dewPoint = 15, relativeHumidity = 30;
int tecState = OFF;
bool cooling = false;
int intervalTecCooling = 200;
float opticalThreshold = 0.5;
int pwmIncrement = 1, startPwm = 100, maxPwm = 255;
int intervalMainLoop = 200;
int tecPwm = 0, noiseSampleIndex = 0, noiseSampleAmount = 10;
float noiseSampleHighest = 0, noiseSampleLowest = 10000;
bool noiseSampling = false;

float calculateHumidity(float TD, float T) {
  if (TD > T) TD = T;
  return 100 * exp((17.625*TD)/(243.04+TD)) / exp((17.625*T)/(243.04+T));
}

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;
  }
}

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(); sensors.begin();
  startNoiseSampling();
}

float getOptical() { return analogRead(opticalSensor) / 30.0; }

void tecCoolingCallback() {
  digitalWrite(tecFan, HIGH);
  tecPwm = min(tecPwm + pwmIncrement, 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 Plotter: mirrorTemp optical dewPoint
  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();
}

Схемы

Схема подключения всех модулей (фото в оригинале).

Производственный процесс

  1. Наука и мастерство современных зеркал: от полированного металла к diéлектрическим покрытиям
  2. Сборка Bluetooth-робота-шпиона на Arduino с управлением с телефона
  3. FlickMote: жестовое IR-пульт для умного дома на Arduino 101 и ультразвуковом датчике
  4. DIY Arduino TV-B-Gone: универсальный пульт для выключения любого телевизора
  5. DIY Калейдоскоп-бесконечное зеркало: потрясающий LED-дисплей
  6. Создание пользовательских LED-часов с будильником — видно с 12 метров
  7. Find Me: Умный поисковик вещей на Arduino и Bluetooth
  8. Оптимизированные решения питания для проектов на Arduino
  9. Крестики-нолики на Arduino с матрицей MAX7219 и картонным корпусом
  10. Пошаговое руководство: сборка умного четырёхногого робота на Arduino