SMALL - espritmodel.com SMALL - Telemetry SMALL - Radio
Reply
Thread Tools
Old Sep 26, 2014, 10:51 AM
Registered User
Germany, HE, Griesheim
Joined May 2008
178 Posts
Careful that may not be what you want, apparently you can only drive the RFM69HW at full 20dBm with a 1% duty cycle.

Item -22-433 here with extra flash and clock may be a better option and they have a friendly shipping cost to Europe about 24$ total, shipped which is fine. If I ever build a second I would certainly use that and not the OrangeRX.

A lot has moved on in the year since I was making my last samples, any how here are all the voltages in 0.01 steps from 3 to 4.2 suitable for the audio module.
0300.wav to 0420.wav, fits nice with the Altitudes posted 1 year ago 0000.wav to 0199.wav in 10s, still plenty of space out of a possible 512 files for single words/phrases.

I did start by programmatically joining the samples together on the target but there was too much delay at the end of the playback of each sample so I created all the needed sample files again. Makes the playback SW simpler in any case.

... Simon
Simon Castle is offline Find More Posts by Simon Castle
Last edited by Simon Castle; Sep 26, 2014 at 11:35 AM.
Reply With Quote
Sign up now
to remove ads between posts
Old Oct 06, 2014, 09:24 PM
Ben
k4zep's Avatar
United States, FL, South Pasadena
Joined Jul 2004
24 Posts
Quote:
Originally Posted by florin View Post
Thank you Rolf, I just finished building mine, using your original drawing and code.

After reading your post, I ordered the pressure sensor and the Arduino board right away. Today I got them and built the vario. It works like a charm.

I didn't use any caps (33 or 3.3). What is the role of these caps?
There are already caps on the board. I didn't use them either, works perfectly.

Ben
k4zep is online now Find More Posts by k4zep
Reply With Quote
Old Oct 07, 2014, 01:39 PM
Registered User
Joined Aug 2013
116 Posts
Vario Switchable via spare RC channel, with Low voltage alarm

I, with my limited programming experience, have managed to modify the vario code so that it is now switchable via a spare RC Servo output. And it also includes a low voltage alarm with 3 stage warning.

Ive used the BMP180 along with the Videoking version of the code.

Pin outs are as described in my code,(currently setup for the UNO but will be used on a pro mini).

I had to change the sound out pin to digital 4, as digital 2 is an interrupt pin.
Both interrupt pins 2 and 3 are required for the RC input. They have to be both connected to the signal line of the switch channel.

Voltage sensing is done via a potential divider circuit, this comprises of 2M ohm in series with 1Mohm and then the sensing pin A1 is connected between the 2.

You may need to adjust the variable scaler to suit your input voltage. if you open serial monitor while connected to the arduino the voltage will be displayed.

included is a second sketch that will display the pwm on the serial monitor, you can use this to adjust your switch weights.

On my 9XR i use the 3 pos switch, with multiplex set as replace, Half, then 100%, 0%, and -100% for the weight.

vario code:

Code:

/*

TODO:
Fancy start up tone??

Rc sail plane vario, that is switchable via a RC servo input channel, Switch options are on (1700-2200), rising
one only(1350-1700), and off(900-1350).
Also includes a low voltage warning, so no osd required when flying.


Original base code for BMP085 sensor by: Jim Lindblom SparkFun Electronics date: 1/18/11
 license: CC BY-SA v3.0 - http://creativecommons.org/licenses/by-sa/3.0/
 All vario sound code by Rolf R Bakke, Oct 2012
 put together and ironed out by VideoKing @ RCGroups 14/10/2013 (vario only)
 
 RC switch, Voltage monitoring, Alarm tones by Benny_H88 @ RC groups 05/10/14

*/

//=============================================================================================================
//            GLOBAL VARIABLES
//=============================================================================================================

// Assign Pin names
int ledPin = 13; // make ledPin = pin 13
int voltagePin = A1;// our voltage divider is connected to pin A1
int rcPin = 2;  //make rcPin = pin 2 (hardware interrupt 0)
int rcPin2 = 3;  //make rcPin = pin 3 (hardware interrupt 1)
int tonePin = 4; //pin for output sound

/*
sda = A4
scl = A5
pulse width interrupt pins = D2 and D3 jumpered
sound out pin = D4
voltage measuring pin = A1
*/


//low voltage alarm level
float alarmLevel = 10.8;
float scaler = 3.17; //scaling factor to make input voltage a real voltage
float voltage;

//Create global variable in which to store our measured pulse width
int pulseWidth;  //And initialize the variable with the value 1500

//declare unsigned long variables in which to store rising and falling micros, for us to do math with later.
unsigned long risingMicros;  
unsigned long fallingMicros;

boolean fullTone = true;    // variable for switching between full tone and rising tone only
boolean state = true;        //used to flash LED when rising tone only is selected

// vario variables-------------------------------------------------------------------------------------------

  /* BMP085 Model Aircraft Vario
 Original base code for BMP085 sensor by: Jim Lindblom SparkFun Electronics date: 1/18/11
 license: CC BY-SA v3.0 - http://creativecommons.org/licenses/by-sa/3.0/
 All sound code by Rolf R Bakke, Oct 2012
 put together and ironed out by VideoKing @ RCGroups 14/10/2013

 */

#include <Wire.h>
unsigned long time = 0;
float toneFreq, toneFreqLowpass, lowpassFast, lowpassSlow ;
#define BMP085_ADDRESS 0x77  // I2C address of BMP085
// Calibration values for BMP085 module
const unsigned char OSS = 0;  // Oversampling Setting for BMP085 Module
int ac1;
int ac2; 
int ac3; 
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1; 
int b2;
int mb;
int mc;
int md;

// b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5; 
short temperature;
long pressure;
int ddsAcc;

//=============================================================================================================
//            INTERRUPT SERVICE ROUTINES (ISR)
//=============================================================================================================

void pinRising ()
{
  // handle pin rising here
  //if(rcPin == HIGH){
    risingMicros = micros();// if rc pin is HIGH then store the time since the program started in risingMicros
  //}
}  // end of pinRising routine

void pinFalling ()
{
  // handle pin falling here
  //if(rcPin == LOW){
    fallingMicros = micros();// if rc pin is LOW then store the time since the program started in fallingMicros
  //}
}  // end of pinFalling routine


//=============================================================================================================
//            SETUP SECTION
//=============================================================================================================

void setup()
{
  
   //status led 
   pinMode(ledPin, OUTPUT);     //sets ledPin as an output
   pinMode(tonePin, OUTPUT);    // sets tonePin as output
   //voltage divider pin
   pinMode(voltagePin, INPUT);  //sets voltagePin as an input
   //interrupt pins
   pinMode(rcPin, INPUT);       //sets rcPin as an input
   pinMode(rcPin2, INPUT);      //sets rcPin2 as an input
   
   
   
   attachInterrupt (0, pinRising, RISING);  // attach interrupt handler rising edge
   attachInterrupt (1, pinFalling, FALLING);  // attach interrupt handler falling edge
   
   Wire.begin();              // Open serial port
   Serial.begin(115200);  //open up a serial port for debugging and messages
      Serial.println("Vario Project");  //warm up serial port

   bmp085Calibration();             // run BMP085 calibration values read
   lowpassFast = lowpassSlow = pressure;
}


//=============================================================================================================
//            MAIN PROGRAM LOOP
//=============================================================================================================

void loop()
{
  pulseCalc();  // Call the pulse width calculation routine
  Serial.println(pulseWidth);
  
    if(pulseWidth >=1701 && pulseWidth <2200){
      //digitalWrite(ledPin, HIGH);            //turn on the LED
      Serial.println("Vario On");
      fullTone = true;
      vario(); // call vario routine
    
    } 
      
    if(pulseWidth >= 1351 && pulseWidth <1700){
      //digitalWrite(ledPin, state);
      //!state;       //change state of the LED with each pass (flashing)
      Serial.println("Rising Tone Only");
      fullTone = false;
      vario(); // call vario routine
    }  
    
      
    if(pulseWidth >= 900 && pulseWidth <1350){
      //digitalWrite(ledPin, LOW);            //turn off the LED
      Serial.println("Vario Off!");
      varioOff(); // call vario off routine
    }
  
  
  voltsAlarm(); // Call the volts Alarm routine
} // end of loop


//=============================================================================================================
//            ROUTINE SECTION
//=============================================================================================================

//Pulse width calculation routine
int pulseCalc(){
  
     // work out the puslewidth at the end of each loop of the code
     // fallingMcros and risingMicros are constantly being updated by the Interupt Service Routine
  noInterrupts();// turn off interrupts while we do math
  pulseWidth = fallingMicros - risingMicros;
  interrupts();// turn  interrupts back on now math has been done
  
  Serial.print(fallingMicros);
   Serial.print(" - ");
   Serial.print(risingMicros);
   Serial.print(" = ");
   Serial.println(pulseWidth); //Print out values for debugging purposes
  
  
  // ERROR CHECK, If the calculated values were updated before the math was completed, then the value would
  // be read wrong, to avoid this we test the result, if it is outside of expected range, we throw an error on the 
  //serial port, and then do the math again. this is repeated until the statement becomes true
  
  while(pulseWidth < 800 || pulseWidth > 2200){
    
    Serial.print("ERROR: PulseWidth Outside expected range (");
   
    noInterrupts();// interrupts off while doing math
    pulseWidth = fallingMicros - risingMicros;// do math again
    interrupts();//interrupts back on once math is done
  }
  return pulseWidth;
}//end of Pulse calc routine



//Vario routine----------------------------------------------------------------------------------------------------
void vario()
{
  pressure = bmp085GetPressure(bmp085ReadUP());
  lowpassFast = lowpassFast + (pressure - lowpassFast) * 0.1;
  lowpassSlow = lowpassSlow + (pressure - lowpassSlow) * 0.05;
  toneFreq = (lowpassSlow - lowpassFast) * 50;
  toneFreqLowpass = toneFreqLowpass + (toneFreq - toneFreqLowpass) * 0.1;
  toneFreq = constrain(toneFreqLowpass, -500, 500);
  ddsAcc += toneFreq * 100 + 2000;
  //Serial.println(temperature);
  //Serial.println(pressure);
  if (fullTone == true){
    if (toneFreq < 0 || ddsAcc > 0){
        tone(tonePin, toneFreq + 510);  
    }else{
        noTone(tonePin);
    }
  }
  else{
    if (toneFreq > 0 && ddsAcc > 0){
        tone(tonePin, toneFreq + 510);  
    }else{
        noTone(tonePin);
    }  
  }
}



// Calculate temperature given ut.
// Value returned will be in units of 0.1 deg C
short bmp085GetTemperature(unsigned int ut)
{
  long x1, x2;

  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  x2 = ((long)mc << 11)/(x1 + md);
  b5 = x1 + x2;

  return ((b5 + 8)>>4);  
}

// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp085GetPressure(unsigned long up)
{
  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;

  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

  // Calculate B4
  x1 = (ac3 * b6)>>13;
  x2 = (b1 * ((b6 * b6)>>12))>>16;
  x3 = ((x1 + x2) + 2)>>2;
  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

  b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
  else
    p = (b7/b4)<<1;

  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
  p += (x1 + x2 + 3791)>>4;

  return p;
}

// Read 1 byte from the BMP085 at 'address'
char bmp085Read(unsigned char address)
{
  unsigned char data;

  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();

  Wire.requestFrom(BMP085_ADDRESS, 1);
  while(!Wire.available())
    ;

  return Wire.read();
}

// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp085ReadInt(unsigned char address)
{
  unsigned char msb, lsb;

  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();

  Wire.requestFrom(BMP085_ADDRESS, 2);
  while(Wire.available()<2)
    ;
  msb = Wire.read();
  lsb = Wire.read();

  return (int) msb<<8 | lsb;
}

// Read the uncompensated temperature value
unsigned int bmp085ReadUT()
{
  unsigned int ut;

  // Write 0x2E into Register 0xF4
  // This requests a temperature reading
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x2E);
  Wire.endTransmission();

  // Wait at least 50ms
  delay(50);     // up'ed from 5ms to see if accuracy increased

  // Read two bytes from registers 0xF6 and 0xF7
  ut = bmp085ReadInt(0xF6);
  return ut;
}

// Read the uncompensated pressure value
unsigned long bmp085ReadUP()
{
  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;

  // Write 0x34+(OSS<<6) into register 0xF4
  // Request a pressure reading w/ oversampling setting
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x34 + (OSS<<6));
  Wire.endTransmission();

  // Wait for conversion, delay time dependent on OSS
  delay(25 + (3<<OSS));    //was 2 up'ed to see if accuracy improved

  // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF6);
  Wire.endTransmission();
  Wire.requestFrom(BMP085_ADDRESS, 3);

  // Wait for data to become available
  while(Wire.available() < 3)
    ;
  msb = Wire.read();
  lsb = Wire.read();
  xlsb = Wire.read();

  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);

  return up;
}//end of vario on routine


//Vario Off routine---------------------------------------------------------------------------------------------------
void varioOff(){
  delay(500); // waste time (maybe find something useful to do here at a later date)
  
}//end of vario off routine


//Low voltage alarm routine-------------------------------------------------------------------------------------------
void voltsAlarm(){
  
  voltageRead();
  Serial.println(voltage);
 
  while(voltage <= alarmLevel && voltage >= (alarmLevel - 0.5)){ //while the voltage measured is less than the threshold,
    lowVoltTone(); // play warning tone
    Serial.println("Low Voltage");
    delay(20000);
    voltageRead();
  }
  
  while(voltage <= alarmLevel && voltage >= (alarmLevel - 1)){ //while the voltage measured is less than the threshold,
    lowVoltTone(); // play warning tone
    Serial.println("Very low Voltage");
    delay(10000);
    voltageRead();
  }

  while(voltage < (alarmLevel - 1)){ //while the voltage measured is less than the threshold,
    lowVoltTone(); // play warning tone
    Serial.println("Land Immediately");
    delay(3000);
    voltageRead();
  }
}//end of low voltage alarm routine


// Low voltage alarm tone routine----------------------------------------------------------------------------------------
   
void lowVoltTone(){
  Serial.println("tone playing");
    tone(tonePin, 247, 1500);
    tone(tonePin, 208, 1000);
    //noTone(tonePin);
    
    
    Serial.println("low voltage tone pt 1");
    delay(1000);
    
    tone(tonePin, 247, 1500);
    tone(tonePin, 208, 1000);
    //noTone(tonePin);
    
    Serial.println("low voltage tone pt 2");
    delay(1000);
    
    tone(tonePin, 247, 1500);
    tone(tonePin, 208, 1000);
    //noTone(tonePin);
    
    Serial.println("low voltage tone pt 3");
    delay(1000);
    
    tone(tonePin, 247, 1500);
    tone(tonePin, 208, 1000);
    delay(1000);
    noTone(tonePin);
    
    Serial.println("low voltage tone pt 4");
    return;
 }// end of low volt tone routine

 // voltage level routine-------------------------------------------------------------------------------------------------
 float voltageRead(){
    int voltLevel = analogRead(voltagePin);
    float actIn = voltLevel * (5.0 / 1023.0);
    // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
    voltage = actIn * (scaler);
    Serial.print("voltage level inside voltageRead function = ");
    Serial.println(voltage);
  return voltage;
}//end of voltage read routine


// bmp085 calibration routine-----------------------------------------------------------------------------------------
// Stores all of the bmp085's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
void bmp085Calibration()
{
  ac1 = bmp085ReadInt(0xAA);
  ac2 = bmp085ReadInt(0xAC);
  ac3 = bmp085ReadInt(0xAE);
  ac4 = bmp085ReadInt(0xB0);
  ac5 = bmp085ReadInt(0xB2);
  ac6 = bmp085ReadInt(0xB4);
  b1 = bmp085ReadInt(0xB6);
  b2 = bmp085ReadInt(0xB8);
  mb = bmp085ReadInt(0xBA);
  mc = bmp085ReadInt(0xBC);
  md = bmp085ReadInt(0xBE);
}

PWM measuring code:

Code:
/*

PWM Display, By Benny_H88 @ RC Groups

When there is a rising edge on rcPin, pin 2, the ISR stores the time since the program started running in
the variable risingMicros.

Then, when a falling edge is detected on rcPin2, pin 3, the ISR stores the time since program started running in the
Variable fallingMicros.

To find the pulseWidth the program subtracts rising time from falling time. While this math is done we prevent
the values changing by turning interrupts off.

PulseWidth is then printed to the serial port (9600 baud)
*/


// Assign Pin names
int rcPin = 2;  //make rcPin = pin 2 (hardware interrupt 0)
int rcPin2 = 3;  //make rcPin = pin 3 (hardware interrupt 1)

//Create global variable in which to store our measured pulse width
int pulseWidth = 0;  //And initialize the variable with the value 1500

//declare unsigned long variables in which to store rising and falling micros, for us to do math with later.
unsigned long risingMicros;  
unsigned long fallingMicros;

// Interrupt Service Routine (ISR)
void pinRising ()
{
  // handle pin rising here
    risingMicros = micros();// if rc pin is HIGH then store the time since the program started in risingMicros
}  // end of pinRising routine

void pinFalling ()
{
  // handle pin falling here
    fallingMicros = micros();// if rc pin is LOW then store the time since the program started in fallingMicros
}  // end of pinFalling routine



void setup()
{
  
   pinMode(rcPin, INPUT);  //sets rcPin as an input
   pinMode(rcPin2, INPUT);  //sets rcPin2 as an input
   
   attachInterrupt (0, pinRising, RISING);  // attach interrupt handler rising edge
   attachInterrupt (1, pinFalling, FALLING);  // attach interrupt handler falling edge
   
   Serial.begin(9600);  //open up a serial port for debugging and messages
      delay(1000);
      Serial.println("RC Pulse-Width");  //warm up serial port
      delay(1000);
}



void loop(){   
 
   noInterrupts();// interrupts off while doing math
   
   pulseWidth = fallingMicros - risingMicros;// do math again
   interrupts();//interrupts back on once math is done
   
    
  // ERROR CHECK, If the calculated values were updated before the math was completed, then the value would
  // be read wrong, to avoid this we test the result, if it is outside of expected range, we throw an error on the 
  //serial port, and then do the math again. this is repeated until the statement becomes true
  
  while(pulseWidth < 800 || pulseWidth > 2200){
    
    Serial.println("ERROR");
    noInterrupts();// interrupts off while doing math
    pulseWidth = fallingMicros - risingMicros;// do math again
    interrupts();//interrupts back on once math is done
    delay(10);
  }
  
  Serial.println(pulseWidth); 
  delay(1000);  
}
Benny_h88 is offline Find More Posts by Benny_h88
Last edited by Benny_h88; Oct 07, 2014 at 01:42 PM. Reason: added credit to pwm display code
Reply With Quote
Old Oct 11, 2014, 07:26 AM
Registered User
Germany, HE, Griesheim
Joined May 2008
178 Posts
Voltage Announcement

Here is a quick demo of my voltage indication.

I have a single channel from the RX to the Vario with 2 mixes stacked on it, one is Press to Talk for the Battery Cell Voltage and the Other is the sink offset.
Its set up to work with a 3S pack with a 10 and 33K resistor divider to get the voltage into the right range for the OpenLRS RX board.
I did try to put it in an air tight box and suck the air out for an altitude demo but it was too much messing with the box, see an earlier post for that.

.... Simon

Vario With Voltage (2 min 32 sec)
Simon Castle is offline Find More Posts by Simon Castle
Last edited by Simon Castle; Oct 11, 2014 at 08:17 AM.
Reply With Quote
Old Oct 25, 2014, 10:40 PM
Registered User
Joined Oct 2014
1 Posts
Trade this vario for CNC machined case?

I love this vario and would like to get one for hang gliding. If someone in the US can do a real nice professional job, I would trade a nice professional CNC'd case for yours or whatever .......



Please email me as I am not on this forum often, just signed up when I saw this vario project. zcases@hotmail.com
cumulous is offline Find More Posts by cumulous
Reply With Quote
Old Oct 28, 2014, 04:18 AM
Registered User
Kambalunga's Avatar
Deutschland, Hessen, LA
Joined Jan 2009
1,208 Posts
Vario/altimeter with MS5611 for Spektrum DX9 and upwards.
For the needed WireMW http://www.rcgroups.com/forums/showp...&postcount=433
Kambalunga is offline Find More Posts by Kambalunga
Last edited by Kambalunga; Oct 28, 2014 at 07:27 AM.
Reply With Quote
Reply


Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Discussion Arduino based IR tag module for combat sh4nce Electric Combat 37 Sep 25, 2014 10:44 AM
Mini-HowTo DIY arduino twin video receiver diversity controller. Updates allways in post #1 Richard_s FPV Equipment 144 Jul 13, 2014 12:27 PM
New Product DIY OpenPilot based FlightControl (F4) lilvinz Multirotor Electronics 267 Feb 16, 2014 04:43 AM
Idea DIY Video Diversity with Arduino - Please Review! MayMayDay FPV Talk 2 Sep 23, 2012 01:36 PM
Help! Engineering student and first arduino based build? cad2blender UAV - Unmanned Aerial Vehicles 3 May 17, 2012 08:59 AM