Ultra-empfindliches akustisches Variometer: Präzisions-Barometer für Piloten
Komponenten und Materialien
| SparkFun Arduino Pro Mini 328 - 3,3V/8MHz | × | 1 |
| GY-63 (MS5611) Barometrischer Drucksensor 3,3V | × | 1 |
| DIP-Schalter 8-fach | × | 1 |
| Summer (aktiv mit internem Oszillator) | × | 1 |
| Multiplexer 8x1 4051 3,3V | × | 1 |
| LiPo-Akku 1S 3,7V 350mAh + Kabel und Stecker | × | 1 |
| Step-Up-Modul + USB LiPo-Lader TP5400 (AZDelivery) | × | 1 |
| Widerstände (4,7k Netzwerk, 220Ω, 2×10k), Kondensatoren (47µF, 470µF) | × | 1 |
| Selbstzurücksetzende Sicherung 0,5A | × | 1 |
| Kleines ABS-Schwarzes Gehäuse (78×39×22 mm) | × | 1 |
| Schiebe-Ein/Aus-Schalter | × | 1 |
| 6-poliger Female-Header (für FTDI) | × | 1 |
| Verschiedene Male-Header und Kabel | × | 1 |
| Grüne Sicherungsschnur | × | 1 |
Über dieses Projekt
Einführung
Dieses Instrument wird von Piloten während des Fluges (Segelflugzeug, Gleitschirm, Hängegleiter, Ballon usw.) verwendet, um den Kern von Thermiken zu finden und besser im Steigwind zu kreisen.
Kurzbeschreibung
Es handelt sich um ein äußerst empfindliches Barometer, das Töne ausgibt, wenn das Gerät steigt oder sinkt. Die Töne sind einfache Pieptöne: alle eine oder zwei Sekunden beim Steigen (höhere Steigrate = höhere Piep-Frequenz). Die Empfindlichkeit ist so hoch, dass das Gerät bereits bei wenigen Zentimetern pro Sekunde Vertikalgeschwindigkeit zu piepen beginnt – man kann es testen, indem man den Arm langsam hebt. Bei Sinkflug ab -1 m/s ertönt ein durchgehender langer Piepton.
Bauteile-Liste
- Arduino Pro Mini 3,3V 8 MHz als Mikrocontroller
- GY-63 (MS5611) barometrischer Drucksensor 3,3V
- DIP-Schalter 8-fach
- Summer (aktiv mit internem Oszillator)
- Multiplexer 8x1 4051 3,3V
- LiPo-Akku 1S 3,7V 350mAh + 10 cm rot/schwarzes Kabel mit Steckern
- Step-Up-Modul + USB LiPo-Lader TP5400 von AZDelivery
- Einige Widerstände, 8×4,7k Widerstandsnetzwerk, 220Ω, 2×10k, Kondensatoren 47µF, 470µF
- Selbstzurücksetzende Sicherung 0,5A
- Kleines schwarzes ABS-Gehäuse, 78×39×22 mm
- Schiebe-Ein/Aus-Schalter
- 6-poliger Female-Header (für FTDI)
- 17-polige Male-Header (verschiedene Konfigurationen)
- 4-poliger Male-Header 90° für Drucksensor-Schaltung
- 30 cm steifer isolierter Draht für Brücken und Verbindungen
- Grüne Schnur
Bedeutung des DIP-Schalters
Der blaue 8-fach DIP-Schalter dient zur Konfiguration der Variometer-Parameter:
- Pin 1: Nicht verwendet (beliebige Stellung)
- Pin 2: Lautstärke niedrig/hoch – kurzschließt bei „On“ den Vorwiderstand des Summers für höhere Lautstärke
- Pins 3 & 4: Sinkalarm-Schwelle (m/s): -999 (aus), -1, -2, -3 (binär kodiert: 00, 01, 10, 11)
- Pins 5 & 6: Piep-Frequenz beim Steigen (Hz): +1, +1,5, +2, +3 (binär kodiert)
- Pins 7 & 8: Empfindlichkeit beim Steigen (m/s): +0,0 (max.), +0,1, +0,2, +0,5 (binär kodiert)
Die Pins 1 und 3–8 werden über den Multiplexer 4051 analog eingelesen; die Software entscheidet anhand des Schwellenwerts 512 über Ein/Aus. Die Auswahl des jeweiligen Schalters erfolgt über 3 Ausgabe-Bits des Arduino (000 bis 111). Details siehe Funktion readDIPswitch() im Code.
Akkumanagement
Zwei 10k-Widerstände und ein 47µF-Kondensator bilden einen Spannungsteiler zur Akku-Überwachung. LiPo-Akkus sollten nicht unter 3,3V entladen werden. Alle 10 Sekunden (BATTinterval) prüft checkBATT() die Spannung; bei Unterschreitung warnt der Summer mit 6 kurzen Pieptönen pro Sekunde. Das Gerät sollte dann umgehend ausgeschaltet und aufgeladen werden.
WICHTIG: Im Gehäuse muss mindestens ein Loch für den Luftdruckausgleich zum Sensor gebohrt werden. Auf den Bildern sind zwei Löcher zu sehen: eines für den Summer-Schall, eines für die Lade-LED. Mit Löchern ist das Variometer nicht mehr wasserdicht.
Die grüne Schnur dient zur sicheren Befestigung im Cockpit – das Gerät darf nicht verloren gehen!
Die Platine (PCB)
Es wird ein einseitiges PCB verwendet, weshalb einige Drahtbrücken (gestrichelte Linien) nötig sind. Die Dateien für Bestückungs- und Lötseite (gespiegelt) stehen zum Download bereit – zum Druck per Laserdrucker auf „gelbe“ oder „blaue“ Transferfolie (1200 dpi, ohne Tonersparmodus). Der Tonertransfer erfolgt mit einem heißen Bügeleisen.
Es werden ca. ein Dutzend Arduino-Pins genutzt; ungenutzte Pins müssen nicht verlötet werden. Der 6-polige Female-Header wird auf der Oberseite des Pro Mini montiert, um spätere FTDI-Programmierung zu ermöglichen.
Das USB-Step-Up-Modul wird kopfüber montiert und mit zwei stabilen Pins (ohne Kunststoffhalter) neben dem USB-Anschluss („Power USB“) verlötet. Drei Kabel verbinden GND-, BATT+ und OUT+ mit dieser Schaltung.
Der barometrische Sensor
Der GY-63 (MS5611) wird per I²C angesprochen. Das Programm ruft die Kernfunktion readPSensor() auf: Sie liest den Drucksensor mehrmals pro Sekunde, summiert die relativen Höhenänderungen in PrexTotal und berechnet alle 500 ms (PrexInterval) den Mittelwert der Höhenänderung. Daraus wird die Steig-/Sinkrate (PrexVario) ermittelt und entsprechend der DIP-Schalter-Einstellungen gepiept. Einfaches Mittelwertfiltern genügt; Kalman- oder Madgwick-Filter brachten keine nennenswerten Vorteile.
Updates / Tipps
Das war’s. Ich hatte viel Freude an diesem Projekt – viel Spaß beim Nachbauen! :-)
Marco Zonca
Code
Akustisches Variometer – Arduino
/* 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();
}
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 = PrexCounter + 1;
PrexTotal = PrexTotal + relativeAltitude;
currPrexMillis = millis();
if (currPrexMillis - prevPrexMillis >= PrexInterval) {
avgAltitude = PrexTotal / PrexCounter;
if (isFirstCalc == true) {
avgPrevAltitude=avgAltitude;
isFirstCalc=false;
}
PrexVario=(avgAltitude-avgPrevAltitude) * (1000/PrexInterval); // vario m/s
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);
}
}
}
void readDIPswitch() {
int s=0;
for (n=1; n<9; n++) {
dips="0000"+String(n-1, BIN);
dips=(dips.substring(dips.length()-3,dips.length()));
if (dips.substring(2,3) == "0") digitalWrite(muxbit0, LOW);
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;
else dipswitch[n]=true;
if (isDebug == true) {
if (dipswitch[n]==false) Serial.print("0");
else Serial.print("1");
}
}
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]);
}
}
void checkBATT() {
n1 = analogRead(vbattPin);
n2=(((6.60 * n1) / 1023.00));
SensorVBatt=(n2 + ((n2 * 0.0) /100));
if (SensorVBatt <= 3.4) {
NewTone (buzzerPin,6,1000);
}
if (isDebug == true) {
Serial.print("VBatt=");
Serial.println(SensorVBatt);
}
}
Individuelle Teile & Gehäuse
Schaltpläne
Datei: vario_R1XzPifiX4.fzz (Fritzing)
Herstellungsprozess
- Sensible Daten sicher speichern & verwalten mit Google Cloud Secret Manager
- Aneroid-Barometer: Design, Geschichte und Zukunft der Druckmessung
- Fortgeschrittene Detektionstechnik identifiziert Transistordefekte mit beispielloser Sensitivität
- Revolutionäre ultradünne MXene-Dehnungssensoren verbessern Roboterarm-Präzision und -Sicherheit
- Fortgeschrittene optische Empfänger für Weltraumkommunikation
- Amstrong® Ultra 650MC – Hochfester, kohlenstoffarmer Stahl für optimale Schweißbarkeit
- Amstrong® Ultra 650MCT – Hochfester Stahl mit verbesserter Tieftemperaturzähigkeit
- Amstrong® Ultra 700MC – Hochfester Feinkornstahl mit exzellenter Schweißbarkeit
- Amstrong® Ultra 700MCT – Ultra-hochfester Feinkornstahl mit verbesserter Tieftemperaturzähigkeit
- Ultrahochreines Chrom (UHP Cr) – 99,95 %+ Qualität für kritische Anwendungen