Setting GPS Altitude Reference Point to compare Altitude Above Ground

I am working on a project to display my drone’s altitude above ground. After researching how GPS receivers determine and present their altitude readings (above sea level), it appears that I need to do some tweeking.

I am wondering how I might set my initial GPS altitude reading as a 0 reference point to then be able to compare all following altitude readings to this initial reference point (ground level).

Ultimately, I want to create an If statement in which if my drone goes at least 400 feet above the established reference point, I receive a warning on my remote LCD.

I am using a Arduino Uno R3, a SparkFun GPS Shield Kit (includes a SparkFun GPS Shield (https://www.sparkfun.com/products/10710) and a GPS Receiver - EM-506 (48 Channel) (GPS Receiver - EM-506 (48 Channel) - GPS-12751 - SparkFun Electronics) attached.

I already have the GPS on the drone comparing latitude and longitude coordinates and sending messages to an LCD screen attached to another Uno on my remote control if coordinates match a pre-set range. The two are communicating via two XBee Pro 60mW Wire Antenna - Series 1 (802.15.4) (https://www.sparkfun.com/products/8742).

Here is the “transmitter” code (Uno and GPS on drone) that I have working so far. The only altitude portion that I have so far is at the bottom (just displays current altitude):

#include <SoftwareSerial.h>
#include <TinyGPS.h>

//In this case, the GPS module's TX pin will connect to the Arduino's RXPIN which is pin 3.
#define RXPIN 2
#define TXPIN 3

// This is the serial rate for your terminal program.
// Set this value equal to the baud rate of your terminal program
#define TERMBAUD  9600

// Set this value equal to the baud rate of your GPS
#define GPSBAUD  4800

int flag=0;

// Create an instance of the TinyGPS object
TinyGPS gps;

// Initialize the SoftwareSerial library to the pins you defined above
SoftwareSerial uart_gps(RXPIN, TXPIN);

// This is where you declare prototypes for the functions that will be 
// using the TinyGPS library.
void getgps(TinyGPS &gps);

// In the setup function, need to initialize two serial ports; the 
// standard hardware serial port (Serial()) to communicate with the 
// terminal program an another serial port (SoftwareSerial()) for the 
// GPS.
void setup()
{
 
  // Sets baud rate of your terminal program
  Serial.begin(TERMBAUD);
  // Sets baud rate of your GPS
  uart_gps.begin(GPSBAUD);
  
  //Serial.println("");
  //Serial.println("GPS Shield QuickStart Example Sketch v12");
  //Serial.println("       ...waiting for lock...           ");
  //Serial.println("");
}

// This is the main loop of the code. All it does is check for data on 
// the RX pin of the Ardiuno, makes sure the data is valid NMEA sentences, 
// then jumps to the getgps() function.
void loop()
{
  while(uart_gps.available())     // While there is data on the RX pin...
  {
      int c = uart_gps.read();    // load the data into a variable...
      if(gps.encode(c))      // if there is a new valid sentence...
      {
        getgps(gps);        // then grab the data.
        delay(4000);        // delay in grabbing GPS data until to length of time required to display message
      }
  }
}

// The getgps function will get and print the values we want.
void getgps(TinyGPS &gps)
{  
  // Define the variables that will be used
  float latitude, longitude;
  // Then call this function
  gps.f_get_position(&latitude, &longitude);
  
  if (latitude >= 41.479133 && latitude <= 41.493510 && longitude >= -71.541359 && longitude <= -71.522058)
  {
    flag=1;
    Serial.write(flag);
  }
  else
  {
    flag=0;
    Serial.write(flag);
  }
   
  // Can print the altitude and course values directly since there is only one value for the function
  // Serial.print("Altitude (meters): "); Serial.println(gps.f_altitude());
}

Thank you very much! Your input is highly appreciated!

Ultimately, I want to create an If statement in which if my drone goes at least 400 feet above the established reference point, I receive a warning on my remote LCD.

How are you going to establish the reference point ? Will it be the altitude at startup ? If so, read the altitude at startup, save it in a variable then compare all subsequent altitudes to the initial one. If some other event it to trigger the establishment of the reference point then the same principle applies,

Grab it in setup() only.

Steve_P71: I am wondering how I might set my initial GPS altitude reading as a 0 reference point to then be able to compare all following altitude readings to this initial reference point (ground level).

You would probably set up a loop in setup() to wait until you get a stable altitude fix and save that altitude in a global variable before returning from setup(). Then in loop() you can subtract that global variable from the new GPS altitude to get altitude relative to your start point.

Hi Steve

Couple of things to try:

Add in some Serial.print() statements to see what value gps.f_altitude() returns at different points in your program - in setup when you assign the value to "a" and then also when you call it in getgps().

In loop(), you only call getgps() after gps.encode() returns true to indicate that a valid sentence has been received ...

  while(uart_gps.available())     // While there is data on the RX pin...
  {
      int c = uart_gps.read();    // load the data into a variable...
      if(gps.encode(c))      // if there is a new valid sentence...
      {
        getgps(gps);        // then grab the data.

But you don't do the same in setup() before calling getgps(), so I'm not sure that gps.f_altitude() will return a valid value.

Regards

Ray

@Steve_P71 gets a one day ban for excessive cross-posting. When he returns he will apologize for wasting the time of so many people. Or be permanently banned.