Ultragevoelige Akoestische Variometer: Een Precisiebarometer voor Piloten
Onderdelen en Benodigdheden
| Onderdeel | Aantal |
|---|---|
| SparkFun Arduino Pro Mini 328 - 3.3V/8MHz | 1 |
| GY-63 (MS5611) barometrische druksensor 3.3V | 1 |
| DIP-schakelaar 8-polig | 1 |
| Buzzer (actief met interne oscillator) | 1 |
| Multiplexer 8x1 4051 3.3V | 1 |
| LiPo accu 1s 3.7V 350mAh + draden en connectors | 1 |
| Voltage step-up module + USB LiPo lader TP5400 | 1 |
| Weerstanden (4.7k netwerk, 220Ω, 2x10k) en condensators (47µF, 470µF) | 1 set |
| Herstelbare zekering 0.5A | 1 |
| Kleine ABS zwarte behuizing 78x39x22 mm | 1 |
| Schuifschakelaar aan/uit | 1 |
| 6-pins female header (voor FTDI) | 1 |
| Diverse pinheaders mannelijk | 1 set |
| 4-pins mannelijk 90° voor druksensor | 1 |
| 30 cm stijfdraad geïsoleerd | 1 |
| Groene bevestigingskoord | 1 |
Over dit project
Inleiding
Deze variometer is een instrument dat piloten tijdens de vlucht gebruiken (zeilvliegtuigen, paragliders, hanggliders, ballonnen, enz.) om de kern van thermieken te lokaliseren en efficiënter te klimmen.
Korte beschrijving
Het is een extreem gevoelige barometer die geluidssignalen afgeeft bij stijgen en zakken. Bij stijging produceert het eenvoudige beep-klanken: één per seconde, twee per seconde of meer, afhankelijk van de stijsnelheid (hogere stijsnelheid = hogere frequentie). De gevoeligheid is zo hoog dat het al reageert op enkele centimeters per seconde – je kunt het testen door de variometer langzaam omhoog te tillen. Bij zakking van -1 m/s of meer geeft het een continue lange toon.
Componentenlijst
- Arduino Pro Mini 3.3V 8 MHz als microcontroller
- GY-63 (MS5611) barometrische druksensor 3.3V
- DIP-schakelaar 8-polig
- Buzzer (actief met interne oscillator)
- Multiplexer 8x1 4051 3.3V
- LiPo accu 1s 3.7V 350mAh met draden en connectors
- Voltage step-up module + USB LiPo lader TP5400 (AZDelivery)
- Weerstanden: 8x4.7k netwerk, 220Ω, 2x10k; condensators: 47µF, 470µF
- Herstelbare zekering 0.5A
- Kleine ABS zwarte behuizing 78x39x22 mm
- Schuifschakelaar aan/uit
- 6-pins female header (voor FTDI programmer)
- Verschillende mannelijke pinheaders
- 4-pins mannelijk 90° voor druksensorcircuit
- 30 cm stijfdraad geïsoleerd voor jumpers en verbindingen
- Groene koord voor bevestiging
Let op: De bruine "keramische condensator" net onder de zwarte schakelaar is in werkelijkheid de herstelbare zekering (in Fritzing niet beschikbaar). De 8 weerstanden zijn gecombineerd in één weerstandsnetwerk (het zwarte onderdeel boven de blauwe DIP-schakelaar met 9 pinnen: 1 gemeenschappelijke en 8 voor de weerstanden). Het Fritzing-bestand is beschikbaar voor download.
Betekenis van de DIP-schakelaar
De blauwe 8-polige DIP-schakelaar stelt de parameters in voor de werking van de variometer:
- Pin 1: Niet gebruikt (stand on/off maakt niet uit)
- Pin 2: Volume laag/hoog – kortsluit de serieweerstand van de buzzer voor hogere volume
- Pin 3 & 4: Zakinstallingsniveau (m/s): -999 (uit), -1, -2, -3 (binaire codering: 00, 01, 10, 11)
- Pin 5 & 6: Beepfrequentie (Hz): +1, +1.5, +2, +3 Hz (binaire codering)
- Pin 7 & 8: Gevoeligheid (m/s): +0.0 (max), +0.1, +0.2, +0.5 (binaire codering)
De pins 1 en 3-8 worden analog gelezen via de multiplexer 4051; de software bepaalt de stand (waarde >512 = aan). De MCU selecteert de poort via 3 uitgangsbits (000 tot 111). Zie de functie readDIPswitch() in de code.
Let op de accu
De twee 10k-weerstanden met de 47µF-condensator vormen een spanningsdeler voor accu-monitoring. LiPo-accus mogen niet onder de 3.3V komen. Elke 10 seconden (BATTinterval) roept checkBATT() de spanning op; bij lage spanning geef de buzzer 6 korte pieptjes per seconde. Zet de variometer dan direct uit en laad op!
Belangrijk: Maak minimaal één gat in de behuizing voor luchtdoorslag naar de sensor. Ik maakte twee gaten: één voor de buzzer, één voor de laad-LED. Met gaten is de behuizing niet meer waterdicht. De groene koord dient als veiligheidsbevestiging.
De PCB
Een eenzijdige PCB met enkele draadbruggen (stippellijnen) voor routing. Bestanden voor componenten- en solderzijde (gespiegeld) zijn beschikbaar voor laserprinter op geel/blauw transferpapier (1200 dpi, geen tonerspaarmodus). Het USB step-up circuit zit omgekeerd; vastzetten met twee sterke pennen naast de USB-connector. 3 draden verbinden GND-, BAT+ en OUT+.
Ongebruikte Arduino-pinnen hoeven niet gesoldeerd te worden. Plaats de 6-pins female header bovenop de Pro Mini voor toekomstige FTDI-updates.
De barometrische sensor
De GY-63 (MS5611) communiceert via I2C. Het programma roept readPSensor() aan (kern van de software). De functie meet veelvuldig per seconde en verzamelt in PrexTotal. Elke halve seconde (PrexInterval) wordt de gemiddelde hoogteverandering berekend en worden geluidssignalen gegenereerd op basis van de DIP-instellingen. Deze eenvoudige filtering volstaat; Kalman, Madgwick en Mahony filters leverden geen verbetering.
Updates / Tips
Dat is alles. Ik heb er enorm veel plezier aan beleefd – doe het zelf ook! :-)
Marco Zonca
Code
Acoustic Variometer code (Arduino)
/* Variometer voor paragliding, Marco Zonca 2020
Arduino MiniPro 3.3V, GY-63 (MS5611), 8x DIP-schakelaar, buzzer, Mux 4051, LiPo 1s 3.7V 350mAh, 3.7V->5V step-up + USB lader
DIP: 1=onbruikbaar 2=volume 3/4=zakalarm 5/6=frequentie 7/8=gevoeligheid */
#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, n2=0, SensorVBatt=0;
double referencePressure = 0;
unsigned long prevPrexMillis = 0, currPrexMillis = 0;
double realPressure = 0;
float absoluteAltitude = 0, relativeAltitude = 0;
float avgAltitude = 0, avgPrevAltitude = 0;
long PrexCounter = 0;
float PrexTotal = 0, PrexVario = 0;
boolean isFirstCalc = true;
MS5611 psensor;
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) Serial.println("Vario is on");
NewTone(buzzerPin, 4);
delay(750);
noNewTone();
}
void loop() {
readPSensor();
if ((prevDIPSWmillis + DIPSWinterval) < millis()) {
readDIPswitch();
prevDIPSWmillis = millis();
}
if ((prevBATTmillis + BATTinterval) < millis()) {
checkBATT();
prevBATTmillis = millis();
}
}
void readPSensor() {
realPressure = psensor.readPressure();
absoluteAltitude = psensor.getAltitude(realPressure);
relativeAltitude = psensor.getAltitude(realPressure, referencePressure);
PrexCounter++;
PrexTotal += relativeAltitude;
currPrexMillis = millis();
if (currPrexMillis - prevPrexMillis >= PrexInterval) {
avgAltitude = PrexTotal / PrexCounter;
if (isFirstCalc) {
avgPrevAltitude = avgAltitude;
isFirstCalc = false;
}
PrexVario = (avgAltitude - avgPrevAltitude) * (1000.0 / PrexInterval); // m/s
if ((PrexVario <= sensibility[4]) && (PrexVario >= sinkalarm[4])) {
noNewTone();
}
if (PrexVario > sensibility[4]) {
NewTone(buzzerPin, (int)(PrexVario + frequency[4]));
}
if (PrexVario < sinkalarm[4]) {
NewTone(buzzerPin, 0.1);
}
avgPrevAltitude = avgAltitude;
prevPrexMillis = currPrexMillis;
PrexTotal = 0;
PrexCounter = 0;
if (isDebug) {
Serial.print("Vario=");
Serial.println(PrexVario);
}
}
}
void readDIPswitch() {
int s = 0;
for (n = 1; n < 9; n++) {
dips = "0000" + String(n-1, BIN);
dips = dips.substring(dips.length()-3);
digitalWrite(muxbit0, dips.substring(2,3) == "0" ? LOW : HIGH);
digitalWrite(muxbit1, dips.substring(1,2) == "0" ? LOW : HIGH);
digitalWrite(muxbit2, dips.substring(0,1) == "0" ? LOW : HIGH);
dipswitch[n] = (analogRead(muxIOpin) <= 512);
if (isDebug) Serial.print(dipswitch[n] ? "1" : "0");
}
if (isDebug) Serial.println();
s = 0;
if (dipswitch[7]) s += 2;
if (dipswitch[8]) s += 1;
sensibility[4] = sensibility[s];
if (isDebug) { Serial.print("Sensibility="); Serial.println(sensibility[4]); }
s = 0;
if (dipswitch[5]) s += 2;
if (dipswitch[6]) s += 1;
frequency[4] = frequency[s];
if (isDebug) { Serial.print("Frequency="); Serial.println(frequency[4]); }
s = 0;
if (dipswitch[3]) s += 2;
if (dipswitch[4]) s += 1;
sinkalarm[4] = sinkalarm[s];
if (isDebug) { Serial.print("SinkAlarm="); Serial.println(sinkalarm[4]); }
}
void checkBATT() {
n1 = analogRead(vbattPin);
n2 = (6.60 * n1) / 1023.0;
SensorVBatt = n2 + ((n2 * 0.0) / 100);
if (SensorVBatt <= 3.4) {
NewTone(buzzerPin, 6, 1000);
}
if (isDebug) {
Serial.print("VBatt=");
Serial.println(SensorVBatt);
}
}
Schema's
Downloadbaar Fritzing-bestand: vario_R1XzPifiX4.fzz
Productieproces
- Aneroïde barometer: ontwerp, geschiedenis en toekomst van drukmeting
- Gevoelige spanningdetector: Bouw een high-sensitivity audio signaal detector
- Geavanceerde detectietechniek localiseert transistor defecten met ongekende gevoeligheid
- Revolutionaire ultra-dunne MXene-streksensoren verbeteren robotarmprecisie en -veiligheid
- Geavanceerde optische ontvangers voor ruimtecommunicatie
- Gevoelige Data Veilig Opslaan En Beheren Met Google Cloud Secret Manager
- Amstrong® Ultra 650MC – Hoogsterk, laagkoolstofstaal voor superieure lasbaarheid
- Amstrong® Ultra 650MCT – Hoogsterk, laagkoolstofstaal met verbeterde koude zwaarte
- Amstrong® Ultra 700MC – Hoogsterk, Fijngranulair Staal met Superieure Lasbaarheid
- Amstrong® Ultra 700MCT – Ultra-Hoge Strekkracht Staal met Lage Koolstof en Fijne Korrel voor Superieure Lasbaarheid
- Ultra-Hoge Zuiverheid Chroom (UHP Cr) – 99,95%+ Kwaliteit voor Kritieke Toepassingen