Maxim Integrated DS18B20 Programmable Resolution 1-Wire Digital Thermometer
×
1
SparkFun Humidity and Temperature Sensor Breakout - Si7021
×
1
Alat dan Mesin yang Diperlukan
Pistol Lem Panas (generik)
Aplikasi dan Layanan Online
Arduino IDE
Tentang Proyek Ini
Tentang
Mengukur kelembaban dapat dilakukan dengan berbagai cara. Metode paling populer adalah menggunakan sensor kelembaban kapasitif. Sayangnya sensor ini kehilangan akurasi dengan cepat saat dioperasikan secara berkelanjutan dalam lingkungan yang sangat lembap. Hygrometer Cermin Dingin tidak menderita masalah ini dan juga jauh lebih akurat, terutama dalam rentang kelembaban tinggi. Sayangnya hygrometer cermin dingin komersial beralih ribuan dolar. Operasi dasarnya cukup sederhana, jadi mungkin untuk membuatnya sendiri. Ini tidak akan memiliki akurasi 0,1 derajat seperti perangkat komersial, tetapi untuk sebagian besar tujuan ini akan cukup, dan tentu lebih akurat dari sensor kapasitif.
Proyek ini adalah bukti konsep dan tidak berarti siap produksi. Banyak perbaikan dapat dilakukan tetapi ini membuktikan fakta bahwa itu bekerja.
Cara Kerja
Hygrometer Cermin Dingin menggunakan Peltier (TEC) untuk mencekik permukaan refleksif hingga kondensasi muncul. Kondensasi terdeteksi dengan sumber cahaya dan sensor optik. Suhu permukaan cermin dicatat saat kondensasi muncul. Suhu ini setara dengan titik embun. Kelembaban Relatif kemudian dapat dihitung menggunakan titik embun dan suhu lingkungan.
Penyederhanaan
Ada beberapa perbedaan dengan Hygrometer Cermin Dingin DIY ini dibandingkan unit komersial.
Hygrometer Cermin Dingin komersial tidak menggunakan cermin konvensional karena itu tidak menghantarkan dan mendistribusikan panas dengan baik, yang menyebabkan pengurangan akurasi dan efisiensi. Perangkat ini sebagian besar menggunakan tembaga berlapis platinum atau rodium sebagai cermin. Karena itu tidak mudah diperoleh maupun hemat biaya, cermin reguler digunakan dalam Hygrometer Cermin Dingin DIY ini. Cermin persegi kecil akan lebih baik dari pada bulat tetapi saya tidak dapat menemukannya. Sebagai alternatif, lembaran stainless steel yang dipoles akan lebih baik.
Hygrometer Cermin Dingin komersial menggunakan Termometer Resistansi Platinum (PRT) yang tertanam di bawah cermin alih-alih thermometer SMD yang dipasang pada permukaan cermin. PRT membutuhkan elektronika tambahan dan memasangnya di antara Peltier dan cermin sambil sekaligus menyediakan konduktivitas termal yang baik adalah masalah. Kerugian memasang thermometer pada permukaan cermin adalah itu memodifikasi properti distribusi panas, mengurangi akurasi. Namun thermometer yang dipasang di permukaan jauh lebih mudah dibuat dan cukup akurat.
Hygrometer Cermin Dingin komersial menggunakan cermin yang jauh lebih kecil sekitar 5 mm alih-alih 4 cm. karena itu membutuhkan daya lebih sedikit dan memiliki bentuk yang lebih kecil. Namun, cermin kecil dan Peltier yang cocok tidak secepat tersedia seperti varian yang lebih besar. Selain itu, Peltier kecil membutuhkan tegangan sangat rendah, yang membutuhkan driver kustom. Juga lebih sulit untuk memasang thermometer SMD pada permukaan cermin kecil sambil meninggalkan cukup ruang untuk memantulkan cahaya.
Versi saat ini tidak memiliki penutup pemblokir cahaya. Ini dapat dengan mudah dicetak 3d dan sangat disarankan untuk memblokir gangguan dari sumber cahaya luar. Ini juga dapat digunakan untuk memegang sumber cahaya dan sensor cahaya di tempatnya. Jika Anda membuat penutup cetak 3d, pastikan terlalu ventilasi yang baik. Anda dapat menggunakan kipas Peltier untuk ventilasi, tetapi pastikan untuk menarik udara ke dalam penutup, bukan meniup ke dalamnya. Di dalamnya juga harus mudah diakses untuk membersihkan cermin.
Implementasi saat ini tidak dapat mengukur titik embun beku karena itu membutuhkan membedakan antara partikel es dan titik air, yang membutuhkan sensor optik kedua untuk mengukur cahaya yang tersebar.
Cara Membangun
Ambil Peltier, bersihkan kedua permukaan, dan letakkan lem konduktif termal di sisi panas. Pastikan merata. Jika Anda tidak memiliki lem konduktif termal, Anda dapat menggunakan pasta termal dengan beberapa titik lem super di dekat tepi. Ini bekerja sama baik. Bersihkan permukaan heat sink dan tekan heat sink dan Peltier bersama dan biarkan lem kering.
Setelah heat sink terpasang ke Peltier dan lem telah kering, pasang cermin dengan cara yang sama, pastikan membersihkan permukaan bawah terlebih dahulu. Penting agar pasta termal merata dan tidak ada celah udara, jika tidak distribusi panas pada cermin tidak merata.
Setelah semua lem kering, pasang kipas. Pastikan untuk menggunakan kipas yang cukup kuat untuk mendinginkan heat sink karena itu menjadi cukup panas. Cara memasang kipas ke heat sink tergantung pada jenis heat sink yang Anda gunakan. Saya hanya melem keduanya bersama menggunakan pistol lem panas.
Nyalakan kipas, kemudian Peltier untuk memeriksa apakah ada setidaknya dua area pada cermin tempat kondensasi muncul pada saat yang sama. Jangan memasang daya Peltier terlalu lama karena itu pasti akan menciptakan profil kondensasi yang merata. Anda ingin melihat tampilannya saat kondensasi baru mulai terlihat. Jika Anda tidak puas dengan hasilnya, coba lagi dengan Peltier, cermin, dan heat sink baru karena kemungkinan tidak dapat melepas bagian-bagian dan memulihkan permukaan halus.
Saya tidak mendistribusikan pasta termal secara merata sehingga profil kondensasi tidak teratur seperti yang dapat Anda lihat dalam foto di atas.
Penting untuk membuat foto atau menandai area tempat kondensasi muncul pada saat yang sama karena ini adalah area tempat Anda harus memasang sensor suhu permukaan cermin dan mengukur jumlah cahaya yang dipantulkan dari cermin.
Dalam proyek ini saya menggunakan Si7021 untuk mengukur suhu cermin karena memberikan output yang bernyaman. Sayangnya alamat I2C di-hard coded jadi Anda hanya dapat menggunakan satu sensor tersebut. Untuk suhu lingkungan saya menggunakan sensor suhu DS18B20 tetapi tidak memiliki akurasi yang sangat tinggi. Satu-satunya alasan saya menggunakan sensor tersebut adalah karena saya tinggal memilikinya.
Untuk memasang Si7021 (atau sensor suhu berbasis PCB apa pun) ke cermin, pertama letakkan tetes besar pasta termal yang tidak konduktif listrik pada sensor suhu. PCB harus ditutupi dengan pasta termal juga, untuk mencegah kondensasi pada elektronika. Kemudian letakkan 4 blobs lem panas besar di setiap sudut PCB. Anda harus bergerak cepat. Tekan sensor terhadap cermin di lokasi tempat kondensasi muncul secara merata. Pastikan meletakkan sensor secara horizontal dan menekan sensor dengan keras terhadap cermin. Lem panas akan membeku cepat setelah menyentuh cermin. Jika Anda perlu mengubah posisi sensor, Anda dapat dengan mudah menggosoknya dengan pisau cutter, mengupas lem, dan mencoba lagi. Jika Anda memiliki kondensasi pada PCB, insulasi dengan lem panas atau plastik spray.
Kipas dikendalikan oleh modul MOSFET IRF520.
Sensor cahaya yang digunakan adalah OPT101, yang sensitif, memiliki output yang bernyaman, dan mudah digunakan.
Untuk sumber cahaya Anda dapat menggunakan dioda laser daya rendah atau LED reguler. Saya mencoba keduanya dan keduanya bekerja dengan baik. Laser memiliki keuntungan respons yang lebih baik tetapi lebih sulit untuk disejajarkan. LED memiliki respons yang lebih datar karena lebih banyak cahaya yang tersebar, tetapi lebih mudah disejajarkan. Jika Anda menggunakan LED, pastikan mengeluarkan sinar cahaya yang fokus.
Output cahaya LED dan laser kemungkinan terlalu tinggi, dan menggunakan PWM untuk mengurangi output bukan opsi karena itu akan menyebabkan gangguan pada sensor cahaya. Sebaliknya, cukup letakkan resistor secara seri dengan LED atau laser untuk mengurangi output.
Untuk memasang LED atau laser dan sensor cahaya OPT101, saya menggunakan kabel tembaga yang diputar menjadi kabel pengunci untuk memberikan lebih banyak kekakuan. Keduanya diikat dengan lem panas. Ini baik untuk bukti konsep tetapi juga terlalu rapuh untuk digunakan di luar lingkungan laboratorium (atau kolam renang). Mudah untuk disejajarkan sensor dan sumber cahaya. Cara yang lebih baik adalah mencetak 3D pemegang untuk perangkat ini, juga karena penutup cetak 3D adalah keharusan untuk mencegah gangguan dari cahaya luar.
Untuk mengontrol Peltier, motor driver BTS7960 digunakan. Cara paling efisien untuk menggerakkan Peltier adalah mengubah arus, bukan menggunakan PWM. Namun, kontroler Peltier tidak secepat tersedia seperti motor driver BTS7960 dan untuk bukti konsep ini, konsumsi daya bukan faktor.
Setelah dirangkit, unggah kode ke Arduino dan sesuaikan rentang sensitivitas OPT101 dengan potensiometer. Resistansi yang lebih tinggi berarti output tegangan yang lebih tinggi untuk jumlah cahaya yang sama. Lihat datasheet OPT101, Gambar 3 - Responsivitas Tegangan vs Irradiansi. Untuk debugging, Anda dapat meniupkan cermin untuk membuat kondensasi, atau menempatkan objek di depan sensor. Jika Anda memiliki pendingin udara, coba nyalakan (atau matikan) dan tunggu. Anda akan dapat melihat perubahan kelembaban.
Dalam diagram di bawah Anda dapat melihat suhu (biru), pembacaan optik (merah), dan titik embun yang diukur (hijau). Anda dapat melihat titik embun naik karena saya baru saja mematikan pendingin udara.
Keamanan
Meskipun kode yang disediakan tidak mendukung ini, hardware dapat memanaskan cermin selain mendinginkannya. Ini dilakukan dengan hanya membalikkan polaritas pada Peltier. Pemanasan cermin dapat digunakan untuk dengan cepat menghilangkan kondensasi dan meningkatkan waktu respons. Selain itu, penguapan kondensasi secara cepat menghilangkan kontaminan kecil. Namun, ini juga menimbulkan risiko keamanan potensial karena permukaan cermin tidak memiliki heat sink. Jika kode macet memanaskan Peltier, sebaik-baiknya itu akan melelehkan lem panas yang memegang thermometer dan terburuknya itu akan memulai kebakaran karena kabel yang meleleh menyebabkan kortslit.
Akurasi
Karena suhu titik embun yang diukur adalah nilai mutlak, kalibrasi tidak penting seperti hygrometer kapasitif atau resistif. Namun, akan ada setidaknya beberapa perbedaan suhu antara area sensor suhu permukaan cermin dan area sensor cahaya. Jika Anda perlu memverifikasi akurasi bacaan, Anda dapat mengkalibrasi perangkat dengan Hygrometer Cermin Dingin komersial yang terkalibrasi.
Seperti yang diketahui, kontaminasi cermin hanya merupakan masalah sebagian. Bacaan cahaya yang dipantulkan tidak mutlak tetapi relatif terhadap awal siklus pendinginan. Saat siklus pendinginan dimulai, cermin bebas dari kondensasi. Jumlah cahaya yang dipantulkan diukur dan digunakan sebagai referensi untuk mendeteksi kondensasi. Jika cermin terkontaminasi dan kurang cahaya dipantulkan, itu seharusnya tidak mempengaruhi deteksi kondensasi. Namun, beberapa kontaminan baik menurunkan atau meningkatkan suhu tempat kondensasi terjadi, jadi untuk akurasi terbaik, bersihkan permukaan cermin dari waktu ke waktu.
Sensor suhu cermin dan lingkungan tidak perlu memiliki akurasi kalibrasi tinggi, tetapi resolusinya harus tinggi. Misalnya, jika suhu sebenarnya 24,0 derajat, tetapi mengukur 24,5 derajat, itu baik selama baik thermometer cermin maupun lingkungan juga mengukur 24,5 (dapat dinormalisasi) dan angka hanya bergetar dengan satu desimal. Banyak thermometer memiliki getaran 0,2 atau 0,3 derajat. Akan lebih baik menggunakan sensor suhu TSYS01 untuk pengukuran suhu permukaan cermin dan suhu lingkungan karena sensor ini menyediakan akurasi yang sama seperti Termometer Resistansi Platinum 0,1 derajat.
Penting agar sensor suhu memiliki kontak yang baik dengan permukaan cermin. Penggunaan pasta termal yang tidak konduktif listrik sangat penting.
Jangan mendinginkan cermin lebih cepat dari waktu respons thermometer, jika tidak titik embun yang terdeteksi akan tidak akurat.
Sensor suhu harus ditempatkan pada lokasi cermin tempat kondensasi area sensor cahaya muncul pada saat yang sama.
Memasang sensor suhu pada permukaan cermin memodifikasi distribusi panas, mengurangi akurasi. Mungkin menggoda untuk menggunakan unit termometer inframerah sebagai alternatif tetapi sayangnya cermin memantulkan sejumlah radiasi termal jadi pengukuran akan dipengaruhi oleh lingkungan sekitar.
Secara teknis, bacaan kelembaban juga bergantung pada tekanan barometrik tetapi efeknya sangat kecil di lingkungan sekitar. Perubahan tekanan apa pun yang disebabkan oleh menutup pintu dengan keras, dan angin luar yang bertiup menyebabkan tekanan diferensial di bangunan kemungkinan akan menyebabkan lebih banyak masalah daripada yang nilainya.
Udara panas dari heat sink Peltier tidak boleh ditarik melalui cermin.
Penurunan suhu yang lambat akan memberikan bacaan yang lebih akurat, tetapi juga menurunkan waktu respons. Waktu respons dapat ditingkatkan dengan mengosilasi suhu dekat titik embun.
Kode
Hygrometer Cermin Dingin
Hygrometer Cermin DinginC/C++
Arduino code
#include <math.h> #include <avr/wdt.h> //Watchdog crash detection //These are custom libraries. #include "Si7021.h" //humidity sensor with heater #include <OneWire.h> //DS18B20 temp sensor #include <DallasTemperature.h> //DS18B20 temp sensor //Timer library: https://github.com/brunocalou/Timer #include "timer.h" #include "timerManager.h" //Define the hardware pins on the Arduino board. #define coolingPWM 6 #define heatingPWM 5 #define coolingEnable 13 #define heatingEnable 12 #define tecFan 7 #define opticalSensor 0 //Analog in #define oneWireBus A3 //DS18B20 temp sensor //The state of the TEC. #define COOLING 0 #define HEATING 1 #define OFF 2 //Timers Timer timerMainLoop; Timer timerTecCooling; Timer timerSampleNoise; //Temperature sensor (humidity not used). Si7021 si7021; //DS18B20 temp sensor OneWire oneWire(oneWireBus); DallasTemperature sensors(&oneWire); float humidity = 0; float ambientTemp = 0; float opticalDewpoint = 0; //Set these to an initial higher value to get the Serial Plotter range correct. float mirrorTemp = 30; float optical = 30; float dewPoint = 15; //initial value must be lower than the mirror temp. float relativeHumidity = 30; int tecState = OFF; bool cooling = false; int intervalTecCooling = 200; //How often the TEC timer is updated in ms. float opticalThreshold = 0.5f; //0.5 //The amount of degrees C the optical reading has to drop below the reference in order to flag condensation detection. This must be a bigger number than the signal noise. 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){ //The dew point cannot be higher than the temperature. if(TD > T){ TD = T; } //August-Roche-Magnus approximation. float rh = 100*(exp((17.625*TD)/(243.04+TD))/exp((17.625*T)/(243.04+T))); return rh; } //Set the TEC to heating, cooling, or off. void SetTEC(int state, int amount){ tecState = state; //Note that for both heating and cooling, the heating AND cooling pin need to be set to high. Ask the PCB designer why. //Driver used to control the TEC: BTS7960 motor driver board. Note that PWM to drive a TEC is not efficient and it is better to use a variable current source. 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() { //Watchdog crash detection. This is for safety because you don't want the TEC to be stuck in heating mode. wdt_enable(WDTO_2S); //WDTO_500MS //WDTO_1S Serial.begin(9600); //9600 //57600 pinMode(coolingPWM, OUTPUT); pinMode(heatingPWM, OUTPUT); pinMode(coolingEnable, OUTPUT); pinMode(heatingEnable, OUTPUT); pinMode(tecFan, OUTPUT); pinMode(opticalSensor, INPUT); //Setup the timers timerMainLoop.setInterval(intervalMainLoop); timerMainLoop.setCallback(mainLoop); timerMainLoop.start(); timerTecCooling.setInterval(intervalTecCooling); timerTecCooling.setCallback(tecCoolingCallback); timerSampleNoise.setInterval(intervalTecCooling); timerSampleNoise.setCallback(sampleNoiseCallback); //si7021 temp sensor setup. uint64_t serialNumber = 0ULL; si7021.begin(); serialNumber = si7021.getSerialNumber(); //DS18B20 onewire temperature sensor sensors.begin(); //Disable the temp sensor debug logging in order to get the graph to work correctly. /* Serial.print("Si7021 serial number: "); Serial.print((uint32_t)(serialNumber >> 32), HEX); Serial.println((uint32_t)(serialNumber), HEX); //Firware version Serial.print("Si7021 firmware version: "); Serial.println(si7021.getFirmwareVersion(), HEX); */ startNoiseSampling(); } //Get the optical sensor reading. float getOptical(){ int opt = analogRead(opticalSensor); float optFactored = (float)opt / 30.0f; return optFactored; } //Timer callback. void tecCoolingCallback(){ digitalWrite(tecFan, HIGH); //Slowly increase the power of the TEC. tecPwm += pwmIncrement; //Clamp if(tecPwm > maxPwm){ tecPwm = maxPwm; } //Set the TEC cooling amount SetTEC(COOLING, tecPwm); //Is condensation detected? if(optical <= (noiseSampleLowest - opticalThreshold)){ //Log the dew point; 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; //Start the TEC counter callback. timerTecCooling.start(); } void stopTec(){ cooling = false; //Turn the TEC fan off. digitalWrite(tecFan, LOW); timerTecCooling.stop(); //No cooling, no heating SetTEC(OFF, 0); } //Non blocking timer. void mainLoop(){ //DS18B20 temp sensor for ambient temperature. sensors.setResolution(10); //has to be done before each temperature measurement. Note that a higher resolution is slower. sensors.requestTemperatures(); ambientTemp = sensors.getTempCByIndex(0); //si7021 temps sensor for mirror. mirrorTemp = si7021.measureTemperature(); //Get the optical sensor reading. optical = getOptical(); relativeHumidity = calculateHumidity(dewPoint, ambientTemp); /* //Readable format Serial.print("dewPoint: "); Serial.println(dewPoint, 2); Serial.print("mirrorTemp: "); Serial.println(mirrorTemp, 2); Serial.print("ambientTemp: "); Serial.println(ambientTemp, 2); Serial.print("relativeHumidity: "); Serial.println(relativeHumidity, 2); */ //For the Serial Plotter Serial.print(mirrorTemp, 2); Serial.print(" "); Serial.print(optical, 2); Serial.print(" "); Serial.println(dewPoint, 2); // Serial.print(" "); // Serial.println(relativeHumidity, 2); //Wait for the condensation to disappear if(!cooling && !noiseSampling && (optical >= noiseSampleLowest)){ startNoiseSampling(); } } void loop() { //Watchdog crash detection wdt_reset(); //Update all timers. TimerManager::instance().update(); }