//**********************************
//* BMP280 version *
//**********************************
// This is the Poor Mans Vario code for the BMP280 sensor by BOSCH Sensortec
// connect BMP280 to .........
// Servo signal input, connect to Arduino pin D3
// Audio output to transmitter on pin D2
// V1 Hans Meijdam, April 2016:
//
// ****** This is a customizable variable that acts as a switch *****
// choose "1" if you also want to hear the altitude in meters if you fly below 100 meters.
// choose "0" if you only want to hear the 10 meters rounded altitude at all times.
// Default is 0.
const byte altitude_per_meter = 0; // only altitude in 10 meters
// const byte altitude_per_meter = 1; // altitude in whole meters if below 100 meters
// ****** This is a customizable variable (0 - 500 range) that defines how large the dead band is ******
// A dead band of "0" (= default) means that the vario will beep constantly, even with no climb or sink at all.
// A small dead band (e.g. value 25 - 50) means that with a small amount of climb or sink the vario will start beeping
// A medium dead band (e.g. value 50 - 100) means that the vario will be silent, unless it observes a medium rate of climb or medium rate of sink.
// A high dead band (> 100) makes the vario only active at high rates of sink or climb.
int deadband = 0; // no deadband or deadband defined by potmeter
// int deadband = 25; // small deadband
// int deadband = 75; // medium deadband
// int deadband = 150; // large deadband
// ****** Alternatively the deadband can be dynamically set by connecting a 10K potmeter over pins 12, A1 (rocker) and A2 ******
// const byte deadbandpotmeter = 0; // no deadband potmeter present
const char deadbandpotmeter = 1; // deadband potmeter is present (10K potmeter over pins 12, A1 (rocker) and A2)
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#define BMP_SCK 6 // SCK/SCL on BMP280
#define BMP_MISO 9 // SDO on BMP280
#define BMP_MOSI 7 // SDA/SDI on BMP280
#define BMP_CS 8 // CSB on BMP280
#define BMP_GND 5 // GND on BMP280
#define BMP_VCC 4 // VCC on BMP280
//Adafruit_BMP280 bme; // I2C
//Adafruit_BMP280 bme(BMP_CS); // hardware SPI
Adafruit_BMP280 bme(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);
const byte led = 13; // define pin that has a led connected to it
const byte audiopin = 3; // define the pin the audio signal is provided to
const byte servopin = 2; // define the pin the servo signal is connected to
unsigned long time = 0;
float toneFreq, toneFreqLowpass, flpressure, lowpassFast, lowpassSlow ;
float p0; // this will be used to store the airfield elevation pressure
int altitude;
int ch1; // Here's where we'll keep our channel values
int ddsAcc;
int analogpin1 = 0;
void setup()
{
// Wire.begin();
pinMode(BMP_GND, OUTPUT);
pinMode(BMP_VCC, OUTPUT);
digitalWrite(BMP_GND, LOW); //Provide GND to BMP280
digitalWrite(BMP_VCC, HIGH); //Provide 3,3v to BMP280
delay (100);
pinMode(servopin, INPUT_PULLUP); // Set servopin input enabling altitude command input from receiver
pinMode(audiopin, OUTPUT); // set audiopin as output
pinMode(A2, OUTPUT); // Prepare for high end of potmeter
pinMode(12, OUTPUT); // Prepare for low end of potmeter
pinMode(A1, INPUT_PULLUP); // Prepare for potmeter input
digitalWrite(A2, HIGH); // High end potmeter to 5 volt
digitalWrite(12, LOW); //Low end potmeter to 0 volt
Serial.begin(9600); // start serial for output
analogpin1 = analogRead(1); // read the input pin A1 potmeter value
Serial.print("Analog pin A1 value: ");
Serial.println(analogpin1);
Serial.println("Setting up BMP280");
if (!bme.begin()) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}
delay(250);
flpressure =(bme.readPressure());// get field pressure and move into float type
p0 = lowpassFast = lowpassSlow = flpressure;
Serial.print(" p0 = ");
Serial.println(p0);
}
void loop()
{
flpressure = (bme.readPressure());// move long type pressure into float type flpressure
altitude = (float)44330 * (1 - pow(((float) flpressure/p0), 0.190295));
altitude = abs(altitude); // if flying from hills negative altitude becomes indicated as positive
lowpassFast = lowpassFast + (flpressure - lowpassFast) * 0.2;
lowpassSlow = lowpassSlow + (flpressure - lowpassSlow) * 0.1;
toneFreq = (lowpassSlow - lowpassFast) * 50;
toneFreqLowpass = toneFreqLowpass + (toneFreq - toneFreqLowpass) * 0.1;
toneFreq = constrain(toneFreqLowpass, -500, 500);
ddsAcc += toneFreq * 100 + 2000;
if (deadbandpotmeter == 1)
{
analogpin1 = analogRead(1); // read the input pin A1 potmeter value
deadband = map(analogpin1, 0, 1024, 500, 0); // map potmeter value to deadband range from 500 - 0
}
if (toneFreq < 0 || ddsAcc > 0)
{
if (abs(toneFreq)>deadband)
{
tone(audiopin, toneFreq + 550);
ledOn(); // the Arduino led will blink if the Vario plays a tone, so you can test without having audio connected
}
}
else
{
noTone(audiopin);
ledOff();
}
int ones = altitude%10;
int tens = (altitude/10)%10;
int hundreds = (altitude/100)%10;
int thousands = (altitude/1000)%10;
ch1 = pulseIn(servopin, HIGH, 25000); // Read the pulse width of servo signal connected to pin D3
if((map(ch1, 1000,2000,-500,500)) > 0) // interpret the servo channel pulse, if the Vario should beep altitude or send vario sound
{
noTone(audiopin); // create 750 ms of silence, or you won't hear the first altitude beep
ledOff();
delay(750);
if(hundreds == 0)
{
tone(audiopin,900); //long duration tone if the number is zero
ledOn();
delay(600);
noTone(audiopin);
ledOff();
}
else
for(char a = 0; a < hundreds; a++) //this loop makes a beep for each hundred meters altitude
{
tone(audiopin,900); // 900 Hz tone frequency for the hundreds
ledOn();
delay(200);
noTone(audiopin);
ledOff();
delay(200);
}
delay(750); //longer delay between hundreds and tens
if(tens == 0)
{
tone(audiopin,1100); //long pulse if the number is zero
ledOn();
delay(600);
noTone(audiopin);
ledOff();
}
else
for(char a = 0; a < tens; a++) //this loop makes a beep for each ten meters altitude
{
tone(audiopin,1100); //1100 Hz tone frequency for the tens
ledOn();
delay(200);
noTone(audiopin);
ledOff();
delay(200);
}
if (altitude_per_meter == 1 && hundreds == 0)
{
delay(750); //longer delay between tens and ones
if(ones == 0)
{
tone(audiopin,1300); //long pulse if the number is zero
ledOn();
delay(600);
noTone(audiopin);
ledOff();
}
else
for(char a = 0; a < ones; a++) //this loop makes a beep for each meter altitude
{
tone(audiopin,1300); //1300 Hz tone frequency for the ones
ledOn();
delay(200);
noTone(audiopin);
ledOff();
delay(200);
}
}
}
}
void ledOn()
{
digitalWrite(led,1);
}
void ledOff()
{
digitalWrite(led,0);
}