Marco Zonca
Published © GPL3+

Acoustic Variometer (Ultra Sensitive Barometer)

As a free flying paragliding pilot, I have finally built my own simple but effective instrument that plays beep-beep during climb and so on.

IntermediateFull instructions provided9,789
Acoustic Variometer (Ultra Sensitive Barometer)

Things used in this project

Story

Read more

Custom parts and enclosures

Components face PCB

Solder face PCB

Schematics

Fritzing schematic

Gerber PCB file

Code

Acoustic Variometer code

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();
}  // 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()

Credits

Marco Zonca

Marco Zonca

12 projects • 41 followers
"From an early age I learned to not use pointers"

Comments