UltraV: Meter Indeks UV Portabel untuk Paparan Matahari yang Aman
Komponen dan Perlengkapan
Arduino Nano R3
×
1
Texas Instruments ML-8511
×
1
Layar OLED 128x64
×
1
Konverter DC-DC step-up MT3608
×
1
Baterai CR2 (3V)
×
1
Holder baterai CR2
×
1
Tentang Proyek Ini
Karena tidak dapat berjemur di bawah matahari akibat masalah kulit, saya menggunakan waktu yang biasanya dihabiskan di pantai untuk membangun meter sinar ultraviolet. UltraV.
Perangkat ini dibangun di atas Arduino Nano rev3, dengan sensor UV, konverter DC/DC untuk menaikkan tegangan baterai 3V, dan layar OLED kecil. Tujuan utama saya adalah menjaga agar tetap portabel, sehingga saya dapat dengan mudah mengetahui indeks UV kapan saja dan di mana saja.
Langkah 1: Bagian dan Komponen
Mikrokontroler Arduino Nano rev.3
Sensor UV ML8511
Layar OLED 128×64 (SSD1306)
MT3608 DC-DC step-up
Baterai CR2
Holder baterai CR2
Saklar
Kotak penutup
Langkah 2: Sensor
ML8511 (Lapis Semiconductors) adalah sensor UV yang cocok untuk mengukur intensitas UV di dalam ruangan atau di luar ruangan. ML8511 dilengkapi dengan penguat internal yang mengubah arus foto menjadi tegangan tergantung pada intensitas UV. Fitur unik ini menawarkan antarmuka yang mudah dengan rangkaian eksternal seperti ADC. Dalam mode power down, arus standby typikal adalah 0.1µA, sehingga memungkinkan umur baterai yang lebih lama.
Fitur:
Dioda foto sensitif terhadap UV-A dan UV-B
Operational amplifier terintegrasi
Keluaran tegangan analog
Arus suplai rendah (300µA typ.) dan arus standby rendah (0.1µA typ.)
Paket permukaan kecil dan tipis (4.0mm x 3.7mm x 0.73mm, 12-pin ceramic QFN)
Sayangnya, saya tidak mendapatkan kesempatan untuk menemukan materi transparan UV untuk melindungi sensor. Segala jenis penutup transparan yang saya coba (plastik, kaca, dll.) mengurangi pengukuran UV. Pilihan yang lebih baik sepertinya adalah kaca silika fused quartz, tetapi saya tidak menemukannya dengan harga yang wajar, jadi saya memutuskan untuk membiarkan sensor di luar kotak, di udara terbuka.
Langkah 3: Operasi
Untuk melakukan pengukuran, nyalakan perangkat dan arahkan ke matahari selama beberapa detik, sambil menjaga agar tetap sejajar dengan arah sinar matahari. Lihat layar: indeks di kiri selalu menampilkan pengukuran instan (satu setiap 200 ms), sementara bacaan di kanan adalah bacaan maksimum yang diambil selama sesi ini: itulah yang Anda butuhkan.
Di bagian bawah kiri layar juga dilaporkan nomenklatura setara WHO (LOW, MODERATE, HIGH, VERY HIGH, EXTREME) untuk indeks UK yang diukur.
Langkah 4: Tegangan Baterai dan Pembacaan
Saya memilih baterai CR2 karena ukuran dan kapasitasnya (800 mAh). Saya menggunakan UltraV selama musim panas dan baterai masih membaca 2.8 V, jadi saya cukup puas dengan pilihan ini. Saat beroperasi, rangkaian menguras sekitar 100 mA, tetapi pengukuran tidak memakan waktu lebih dari beberapa detik. Karena tegangan nominal baterai adalah 3V, saya menambahkan konverter DC-DC step up untuk menaikkan tegangan hingga 9 volt dan menghubungkannya ke pin Vin.
Agar indikasi tegangan baterai muncul di layar, saya menggunakan input analog (A2). Input analog Arduino dapat digunakan untuk mengukur tegangan DC antara 0 dan 5V, tetapi teknik ini memerlukan kalibrasi. Untuk melakukan kalibrasi, Anda memerlukan multimeter. Pertama, nyalakan rangkaian dengan baterai akhir Anda (CR2) dan jangan gunakan daya USB dari komputer; ukur 5V pada Arduino dari regulator (ditemukan pada pin 5V Arduino): tegangan ini digunakan sebagai referensi ADC Arduino secara default. Sekarang masukkan nilai yang diukur ke dalam skets sebagai berikut (asumsikan saya membaca 5.023):
voltage = ((long)sum / (long)NUM_SAMPLES * 5023) / 1024.0;
Dalam skets, saya mengambil pengukuran tegangan sebagai rata-rata dari 10 sampel.
Langkah 5: Skematik dan Koneksi
Langkah 6: Software
Untuk layar, saya menggunakan U8g2lib yang sangat fleksibel dan kuat untuk layar OLED jenis ini, yang memungkinkan pilihan font yang luas dan fungsi pemosisian yang baik.
Terkait pembacaan tegangan dari ML8511, saya menggunakan pin referensi 3.3V Arduino (akurat dalam 1%) sebagai basis untuk konverter ADC. Dengan melakukan konversi analog ke digital pada pin 3.3V (dengan menghubungkannya ke A1) dan kemudian membandingkan bacaan ini dengan bacaan dari sensor, kita dapat menghasilkan pembacaan yang akurat, terlepas dari VIN (asalkan di atas 3.4V).
int uvLevel = averageAnalogRead(UVOUT); int refLevel = averageAnalogRead(REF_3V3); float outputVoltage = 3.3 / refLevel * uvLevel;
Unduh kode lengkap dari tautan berikut.
UltraV_OLED.ino.zip
Langkah 7: Kotak Penutup
Setelah beberapa (buruk) tes pemotongan jendela layar persegi panjang pada kotak plastik komersial secara manual, saya memutuskan untuk mendesain kotak sendiri. Jadi, dengan aplikasi CAD saya mendesain kotak dan untuk menjaga agar semakin kecil, saya memasang baterai CR2 secara eksternal di bagian belakang (dengan holder baterai yang ditempel pada kotak itu sendiri).
Unduh file STL untuk kotak penutup, dari tautan berikut.
UltraV.stl.zip
Langkah 8: Peningkatan Masa Depan yang Mungkin
Gunakan spektrometer UV untuk mengukur nilai Indeks UV aktual secara real-time dalam berbagai kondisi (spektrometer UV sangat mahal);
Catat output ML8511 secara bersamaan dengan mikrokontroler Arduino;
Tulis algoritma untuk menghubungkan output ML8511 dengan nilai UVI aktual secara real-time dalam berbagai kondisi atmosfer.
Langkah 9: Galeri Gambar
Langkah 10: Kredit
Carlos Orts: https://create.arduino.cc/projecthub/McOrts/mobil...
Forum Arduino: https://forum.arduino.cc/index.php?topic=3922.0
/* Fabio Marzocca @ 2018 Analog to digital conversions rely completely on VCC. We assume this is 5V but if the board is powered from USB this may be as high as 5.25V or as low as 4.75V: https://en.wikipedia.org/wiki/USB#Power Because of this unknown window it makes the ADC fairly inaccurate in most cases. To fix this, we use the very accurate onboard 3.3V reference (accurate within 1%). So by doing an ADC on the 3.3V pin (A1) and then comparing this against the reading from the sensor we can extrapolate a true-to-life reading no matter what VIN is (as long as it's above 3.4V). v. 2.0.0 - July 2018 - moved from 16x2 LCD to OLED v. 2.0.1 - Sept 2018 - changed read battery function */ #include <Arduino.h> #include <U8g2lib.h> #include <Wire.h> U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display #define FIRST_ROW_Y 16 #define FIRST_ROW_X 16 #define BOX_H 38 //Hardware pin definitions const int UVOUT = A0; //Output from the sensor const int REF_3V3 = A1; //3.3V power on the Arduino board const int VBATT = A2; //Battery voltage float maxUV = 0; //Max UV index read void setup() { pinMode(UVOUT, INPUT); pinMode(REF_3V3, INPUT); pinMode(VBATT, INPUT); u8g2.begin(); } void loop() { u8g2.firstPage(); do { int uvLevel = averageAnalogRead(UVOUT); int refLevel = averageAnalogRead(REF_3V3); //Use the 3.3V power pin as a reference to get a very accurate output value from sensor float outputVoltage = 3.3 / refLevel * uvLevel; float uvIntensity = mapfloat(outputVoltage, 0.99, 2.6, 0.0, 15.0); //Convert the voltage to a UV intensity level readBattery(); if (maxUV < uvIntensity) { maxUV = uvIntensity; } u8g2.drawFrame(0,FIRST_ROW_Y+1,128,BOX_H); u8g2.setFont(u8g2_font_logisoso18_tf); //Instant UV u8g2.setCursor(10,40); u8g2.print(uvIntensity); //UV Max u8g2.setCursor(70,40); u8g2.print(maxUV); u8g2.setFont(u8g2_font_u8glib_4_tf); u8g2.setCursor(10,52); u8g2.print(F("INSTANT")); u8g2.setCursor(75,52); u8g2.print(F("MAXIMUM")); showUVCategory(); u8g2.setCursor(88,64); u8g2.print(F("F.Marzocca")); } while ( u8g2.nextPage() ); delay(200); } // Reads maxUV and prints the UV category void showUVCategory() { char strCat[12]; byte categ = (byte)(maxUV+0.5); //round up if ((categ >= 0) && (categ < 3)) { strcpy(strCat, "LOW"); } else if ((categ >= 3) && (categ < 6)) { strcpy(strCat, "MODERATE"); } else if ((categ >= 6) && (categ < 8)) { strcpy(strCat, "HIGH !"); } else if ((categ >= 8) && (categ < 10)) { strcpy(strCat, "VERY HIGH!"); } else if (categ >= 11) { strcpy(strCat, "EXTREME!"); } u8g2.setCursor(0,64); u8g2.print(strCat); } //Takes an average of readings on a given pin //Returns the average int averageAnalogRead(int pinToRead) { byte numberOfReadings = 16; unsigned int runningValue = 0; for(int x = 0 ; x < numberOfReadings ; x++) runningValue += analogRead(pinToRead); runningValue /= numberOfReadings; return(runningValue); } //The Arduino Map function but for floats //From: https://forum.arduino.cc/index.php?topic=3922.0 float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } void readBattery() { long battery = readBattVcc(); long VccMin = 2300; //Battery minimum voltage read on Vcc byte batteryBar; //Battery progress bar int barStep = 140; //step for battery progress bar (235) batteryBar = (battery - VccMin)/barStep; //battery icon u8g2.setFont(u8g2_font_open_iconic_embedded_2x_t); u8g2.drawGlyph(1, FIRST_ROW_Y, 73 ); // battery status cursor u8g2.setFont(u8g2_font_open_iconic_play_1x_t); for (byte i=1; i<=batteryBar; i++) { u8g2.drawGlyph( 128-9*i,FIRST_ROW_Y-4,75); } // battery voltage u8g2.setFont(u8g2_font_freedoomr10_tu); u8g2.setCursor(25, FIRST_ROW_Y); u8g2.print(float(battery)/1000, 3); } long readBattVcc() { int sum=0; int sample_count=0; long voltage= 0; #define NUM_SAMPLES 10 // take a number of analog samples and add them up while (sample_count < NUM_SAMPLES) { sum += analogRead(VBATT); sample_count++; delay(2); } // calculate the voltage // use 5000 for a 5.0V ADC reference voltage // 5020V is the calibrated reference voltage (in millivolts) for my project voltage = ((long)sum / (long)NUM_SAMPLES * 5020) / 1024.0; return voltage; //Vbattery in millivolts }