Variometer Akustik Sensitif Tinggi: Barometer Presisi untuk Pilot
Tentang Proyek Ini
Ini adalah instrumen yang digunakan pilot selama penerbangan (layang-layang, payung layang, gantung layang, balon, dan sebagainya) untuk membantu menemukan inti termik dan mendorong pesawat naik ke udara dengan lebih baik serta lebih banyak.
Deskripsi Singkat
Ini adalah barometer sangat sensitif yang menghasilkan suara saat naik (mengangkat) dan juga saat turun (menurun). Suara yang dihasilkan adalah bip-bip sederhana, setiap detik, atau dua kali per detik atau lebih saat naik (semakin tinggi laju kenaikan, frekuensi bip semakin tinggi): alat ini begitu sensitif sehingga mulai berbip setelah hanya beberapa sentimeter (!) per detik; Anda bisa mencoba mengangkat lengan perlahan sambil memegang Variometer di tangan untuk mendapatkan suara. Dalam hal laju penurunan, alat menghasilkan bip panjang (berkelanjutan) beeeeeeeep pada -1 m/detik atau lebih.
Daftar Komponen
- Arduino Pro Mini 3.3v 8 Mhz sebagai mikrokontroler
- Sensor tekanan barometrik GY-63 (MS5611) 3.3v
- Dipswitch 8
- Buzzer (aktif dengan osilator internal)
- Multiplexer 8x1 4051 3.3v
- Baterai LiPo 1s 3.7v 350mAh + kabel merah/hitam 10cm dan konektor M+F
- Modul step-up + charger LiPo USB, TP5400 dari AZDelivery;
- Beberapa resistor, jaringan resistor 8x4.7k, 220, 2x10k, dan kapasitor 47uF, 470uF
- Fuse dapat direset 0.5A
- Kotak plastik ABS hitam kecil, ukuran 78x39x22 mm
- Interlocker geser on/off
- Konektor header female 6 pin (untuk FTDI)
- Pin male 17 pin (2x, 2x, 2x, 2x, 2x, 4x, 1x, 1x dan 1x)
- Pin male 4 pin 90° untuk rangkaian sensor tekanan
- 30 cm kabel kaku dilapis plastik, untuk jumper dan koneksi
- Tali hijau
Skema Fritzing di atas menunjukkan semua yang Anda butuhkan untuk membangun rangkaian. Perhatikan kapasitor keramik cokelat tepat di bawah interlocker hitam, sebenarnya adalah fuse dapat direset (saya tidak menemukan desain yang tepat untuknya). Sebagai gantinya 8 resistor, saya menggunakan satu komponen, jaringan resistor, yang mencakup 8 resistor 4.7K ohm, semuanya di dalamnya; lihat gambar berikut untuk menemukannya, sulit ditemukan, ini yang hitam di bagian atas dipswitch biru, memiliki sembilan pin, satu umum, yang lain delapan untuk resistor. Berkas skema Fritzing untuk diunduh tersedia di bawah.
Arti Dipswitch
Saya suka menggunakan dipswitch biru, 8 interlocker on/off sangat kecil dalam satu kotak berwarna, untuk memilih dan mengubah parameter kerja Variometer. Tabel untuk parameter ini ditampilkan di atas dan dijelaskan sebagai berikut:
- 1 - tidak digunakan
- 2 - volume rendah atau tinggi
- 3 dan 4 - alarm penurunan m/detik: -999 -1 -2 -3
- 5 dan 6 - frekuensi bip Hz: +1 +1.5 +2 +3
- 7 dan 8 - sensitivitas m/detik: +0.0 +0.1 +0.2 +0.5
Pin 1 tidak digunakan, posisi apa pun, on atau off, tidak mengubah apa pun.
Pin 2 mengubah tingkat volume buzzer; bekerja secara listrik: saat pin on, itu memendekkan rangkaian resistor yang berurutan dengan buzzer dan membiarkan lebih banyak arus melewati untuk menghasilkan bip dengan volume lebih tinggi.
Pin 3 dan 4 menetapkan tingkat penurunan (menurun) di bawahnya Variometer akan memutar beeeeeeeep; pin digunakan sebagai kode biner, dua bit, 4 pengaturan: 00=0, 01=1, 10=2 11=3; Anda dapat mengatur alarm penurunan pada -999 m/detik (artinya tidak ada batas, tidak akan pernah berbip) dengan pin 3=off dan pin 4=off (biner 00); Anda dapat mengatur nilai lain menjadi -1, -2 atau -3 m/detik masing-masing dengan pin 3=off/4=on, 3=on/4=off dan 3=on/4=on. Misalnya pada posisi 2 Variometer akan beeeeeeeeeep hanya pada laju penurunan lebih dari -2 m/detik. Untuk pengujian, Anda bisa mencoba menggunakan lift... turun dari lantai 3 ke lantai 0, atau berlari cepat tangga...
Pin 5 dan 6 menetapkan frekuensi bip, mereka bekerja bersama sebagai kode biner seperti dijelaskan di atas untuk pasangan pin lain; pada kecepatan kenaikan yang sama, diatur pada +2Hz akan berbip-bip lebih cepat daripada pada +1Hz. Beberapa orang suka memiliki bip yang lebih lambat dan lebih sedikit "stres" :-)
Pin 7 dan 8 menetapkan sensitivitas instrumen: +0.0 berarti sensitivitas maksimum saat gerak naik, membutuhkan kurang dari 10cm/detik kecepatan untuk berbip-bip; pada posisi ini terkadang instrumen berbip, bahkan saat diam, menangkap perubahan tekanan udara yang sangat kecil (misalnya menutup pintu di ruangan dapat meningkatkan tekanan udara sedikit); menangkap juga "kebisingan" listrik normal tetapi cukup stabil dan berguna. Pada posisi ke-4 kita memiliki sensitivitas +0.5 m/detik, jauh lebih sensitif terhadap perubahan tekanan udara, Anda butuh "banyak" lebih banyak kecepatan naik untuk naik ketinggian agar mendapatkan bip-bip. Untuk pengujian, Anda bisa mencoba menggunakan lift... dari lantai 0 ke lantai 3...
Dari sudut pandang rangkaian elektronik, pin 1 dan 3-8 dibaca secara analog melalui chip multiplexer 4051, kemudian perangkat lunak memutuskan apakah on atau off, nilai > 512 atau tidak: memiliki 8 input ke 1 port umum yang terhubung ke Arduino sebagai input. Untuk memilih salah satu dari 8 port untuk membaca posisi on/off Dipswitch, MCU (Arduino) mengatur 3 bit output yang sudah Anda ketahui bagaimana cara kerjanya: 000, 001, 010, 011, 100, 101, 110, 111 (0, 1, 2, 3, 4, 5, 6, 7 = 8 port = 8 interlocker on/off). Lihat kode fungsi "readDIPswitch()".
Perhatikan Baterai
Dua resistor 10k bersama dengan kapasitor 47uF bekerja sebagai pembagi tegangan untuk menguji tegangan baterai. LiPo dikenal kritis saat diurai di bawah 3.3v karena itu setiap 10 detik (BATTinterval) fungsi "checkBATT()" dipanggil dan dalam hal tegangan rendah, buzzer akan memberi tahu Anda dengan 6 bip pendek dalam satu detik. Jangan terlalu lama untuk mematikan, dan segera isi ulang!
Sangat PENTING untuk diingat membuat setidaknya satu LUBANG di kotak untuk membiarkan udara melewati untuk perubahan tekanan sensor. Saya membuat dua lubang seperti yang Anda lihat dalam gambar: satu untuk mendengarkan bip buzzer dan satu untuk melihat status LED pengisian saat terhubung ke kabel micro USB dan charger. Ah ya, ada lubang lain untuk micro USB juga. Dengan lubang, Variometer tidak lagi tahan air...
Tali hijau untuk mengaitkannya dengan aman di papan: Anda tidak ingin kehilangannya, sekali-kali tidak!
PCB
Digunakan PCB satu sisi karena itu saya harus menambahkan beberapa kabel jumper (yang titik-titik) untuk menyelesaikan jalur seluruh rangkaian. Berikut adalah sisi komponen tetapi di bawah Anda memiliki kedua berkas, sisi komponen dan solder, tercermin, untuk diunduh dan dicetak melalui printer laser pada lembar "kuning" atau "biru". Saya menggunakan yang kuning tetapi mereka mengatakan yang biru lebih baik (harganya lebih tinggi). Saat mencetak, ingatlah untuk menonaktifkan pengaturan hemat toner, gunakan resolusi 1200 dpi untuk hasil hitam yang benar-benar dalam. Proses transfer toner dari lembar ajaib ke PCB dilakukan dengan menggunakan setrika panas... Mencetak kedua sisi PCB membuat proyek ini "profesional".
Digunakan selang pin Arduino. Men solder pin yang tidak digunakan tidak perlu dan tidak diperlukan: biarkan bebas. Letakkan header female 6 pin di sisi atas Mini Pro untuk, jika perlu di masa depan, antarmuka FTDI dapat terhubung untuk pembaruan perangkat lunak lebih lanjut.
Rangkaian daya step-up USB ditempatkan terbalik. Untuk memegangnya di tempat gunakan dua pin kuat, pin male biasa untuk Arduino tetapi tanpa pelindung plastik, di samping konektor USB yang tertulis "Power USB": gunakan solder untuk menyatukan semuanya, dua pin dan konektor USB. 3 kabel menghubungkan terminal Gnd-, Batt+ dan Out+ ke rangkaian ini.
Sensor Barometrik
Sensor tekanan barometrik GY-63 (MS5611), P-Sensor di PCB, tertutup dalam papan sirkuit kecil dan Arduino berkomunikasi dengannya melalui bus i2c. Penggunaannya sederhana, termasuk juga sensor suhu yang tidak saya gunakan.
Program memanggil fungsi "readPSensor()" yang merupakan inti perangkat lunak. Yang kita butuhkan adalah perubahan relatif dari ketinggian, fungsi membaca banyak kali per detik dan mengumpulkan dalam PrexTotal; setiap setengah detik (PrexInterval) menghitung perubahan rata-rata ketinggian dan melanjutkan dengan bip-bip atau bip beeeeeeep panjang mengingat pengaturan dipswitch. Cara sederhana untuk menyaring data ini cukup baik; saya mencoba cara penyaringan Kalman yang menarik, dan juga algoritma penyaringan Madgwick dan Mahony yang rumit tanpa manfaat yang signifikan untuk tujuan proyek ini.
Pembaruan / Tips
Itu saja. Saya sangat menikmati proyek ini! Lakukan juga! :-)
Marco Zonca
Kode
/* This sketch act as Variometer for paragliding, by Marco Zonca, 2020 Arduino MiniPro 3.3 as CPU, GY-63 (MS5611) barometric pressure sensor, 8 x dipswitch, buzzer, Mux 4051, lipo 1s 3.7v 350mA, 3.7v -> 5v voltage stepup + lipo usb charger; DipSwitch: 1= not used 2= hw low/high buzzer volume 3= \ sink alarm: OFF -1.0 -2.0 -3.0 m/sec 4= / 5= \ frequency beeps: +1.0 +1.5 +2.0 +3.0 Hz 6= / 7= \ sensibility: +0.0 +0.1 +0.2 +0.5 m/sec 8= / */ #include <MS5611.h> #include <NewTone.h> const int muxIOpin = 15; const int vbattPin = 14; const int muxbit0 = 4; const int muxbit1 = 5; const int muxbit2 = 6; const int buzzerPin = 7; const int DIPSWinterval = 5000; const int BATTinterval = 10000; const int PrexInterval = 500; const boolean isDebug = false; float sensibility[5]; float frequency[5]; float sinkalarm[5]; long n=0; boolean dipswitch[9]; String dips; unsigned long prevDIPSWmillis = 0; unsigned long prevBATTmillis = 0; float n1=0; float n2=0; float SensorVBatt=0; double referencePressure = 0; unsigned long prevPrexMillis = 0; unsigned long currPrexMillis = 0; double realPressure = 0; float absoluteAltitude = 0; float relativeAltitude = 0; float avgAltitude = 0; float avgPrevAltitude = 0; long PrexCounter = 0; float PrexTotal = 0; float PrexVario = 0; boolean isFirstCalc = true; MS5611 psensor; // pressure sensor void setup() { Serial.begin(9600); pinMode(muxbit0, OUTPUT); pinMode(muxbit1, OUTPUT); pinMode(muxbit2, OUTPUT); pinMode(buzzerPin, OUTPUT); sensibility[4]=0; sensibility[3]=0.5; sensibility[2]=0.2; sensibility[1]=0.1; sensibility[0]=0.0; frequency[4]=0; frequency[3]=3.0; frequency[2]=2.0; frequency[1]=1.5; frequency[0]=1.0; sinkalarm[4]=0; sinkalarm[3]=-3.0; sinkalarm[2]=-2.0; sinkalarm[1]=-1.0; sinkalarm[0]=-999.9; readDIPswitch(); psensor.begin(); referencePressure = psensor.readPressure(); if (isDebug == true) Serial.println("Vario is on"); NewTone (buzzerPin,4); delay(750); noNewTone(); } // end setup() void loop() { readPSensor(); if ((prevDIPSWmillis+DIPSWinterval) < millis()) { readDIPswitch(); prevDIPSWmillis=millis(); } if ((prevBATTmillis+BATTinterval) < millis()) { checkBATT(); prevBATTmillis=millis(); } } // end loop() void readPSensor() { // read Pressure Sensor // Calculate average altitude and vario realPressure = psensor.readPressure(); absoluteAltitude = psensor.getAltitude(realPressure); relativeAltitude = psensor.getAltitude(realPressure, referencePressure); PrexCounter = PrexCounter + 1; PrexTotal = PrexTotal + relativeAltitude; currPrexMillis = millis(); if (currPrexMillis - prevPrexMillis >= PrexInterval) { avgAltitude = PrexTotal / PrexCounter; // average if (isFirstCalc == true) { avgPrevAltitude=avgAltitude; isFirstCalc=false; } PrexVario=(avgAltitude-avgPrevAltitude) * (1000/PrexInterval); // vario mSec if ((PrexVario <= sensibility[4]) && (PrexVario >= sinkalarm[4])) { noNewTone(); } if ((PrexVario > sensibility[4])) { // lift beep beep + NewTone (buzzerPin,((int)(PrexVario+frequency[4]))); } if ((PrexVario < sinkalarm[4])) { // sink beeeeeep - NewTone (buzzerPin,0.1); } avgPrevAltitude=avgAltitude; prevPrexMillis = currPrexMillis; PrexTotal=0; PrexCounter=0; if (isDebug == true) { Serial.print("Vario="); Serial.println(PrexVario); } } } // end readPSensor() void readDIPswitch() { // read dipswitch 1-8 for settings int s=0; for (n=1; n<9; n++) { dips="0000"+String(n-1, BIN); //leading zeros at left, compose 3 bits selection dips=(dips.substring(dips.length()-3,dips.length())); if (dips.substring(2,3) == "0") digitalWrite(muxbit0, LOW); // port selection (1-8) else digitalWrite(muxbit0, HIGH); if (dips.substring(1,2) == "0") digitalWrite(muxbit1, LOW); else digitalWrite(muxbit1, HIGH); if (dips.substring(0,1) == "0") digitalWrite(muxbit2, LOW); else digitalWrite(muxbit2, HIGH); if (analogRead(muxIOpin) > 512) dipswitch[n]=false; // read selected port else dipswitch[n]=true; if (isDebug == true) { if (dipswitch[n]==false) Serial.print("0"); else Serial.print("1"); } } // end for if (isDebug == true) Serial.println(""); s=0; if (dipswitch[7]==true) s = s + 2; if (dipswitch[8]==true) s = s + 1; sensibility[4]=sensibility[s]; if (isDebug == true) { Serial.print("Sensibility="); Serial.println(sensibility[4]); } s=0; if (dipswitch[5]==true) s = s + 2; if (dipswitch[6]==true) s = s + 1; frequency[4]=frequency[s]; if (isDebug == true) { Serial.print("Frequency="); Serial.println(frequency[4]); } s=0; if (dipswitch[3]==true) s = s + 2; if (dipswitch[4]==true) s = s + 1; sinkalarm[4]=sinkalarm[s]; if (isDebug == true) { Serial.print("SinkAlarm="); Serial.println(sinkalarm[4]); } } // end readDIPswitch() void checkBATT() { // check lipo/liion battery voltage n1 = analogRead(vbattPin); n2=(((6.60 * n1) / 1023.00)); SensorVBatt=(n2 + ((n2 * 0.0) /100)); // arbitrary correction (not active = 0.0%) if (SensorVBatt <= 3.4) { NewTone (buzzerPin,6,1000); } if (isDebug == true) { Serial.print("VBatt="); Serial.println(SensorVBatt); } } // end checkBATT()