ADS-B Reception RTL vs Airspy Round 2

In my previous article I compared an older Elonics E4000 based dongle with an Airspy for ADS-B reception. Unsurprisingly the Airspy beat the performance of the RTL dongle in all areas. However a number of commenters here http://www.rtl-sdr.com/rtl-sdr-vs-airspy-on-ads-b-reception/ noted the performance of the E4000 dongles wasn’t great for ADS-B.

So I went out and bought an R820T2 dongle from Cozycave.I got the expensive one (£7.85!)

The test setup was exactly as before, the Airspy and RTL connected via the Minicircuits splitter. The Airspy providing power to the 1090Mhz preamp. Airspy was using ADSB Spy V1.0.0.14 and the RTL 820T2 was using ADSB# V1.0.11.1 (Both are now packaged with SDRSharp). Again the Airspy wasn’t correcting using FEC/CRC and was suppressing duplicates, the ADSB# was correcting and using CRC and allowing duplicates through.

The test was run on a week day for 24 hours from around 20:00 to 20:00.

The range results were very similar to the initial tests with the Airspy for most part having slightly greater range than the RTL, again in one specific direction over 50km more. But generally it was limited by geography with both radios exceeding 400km over the North Sea (Outer green ring is 400km).

46voHoz

The results from Virtual Radar showed in the 24 hour period the Airspy received over 31 million messages of which 31 were unusable and 111 had bad parity. Of these 2.2million were Airborne Position/Velocity.

In the same period the RTL820T2 recorded 22.3million messages of which 3 million were unusable, 5523 had bad parity. Of these 1.2million were Airborne position/Velocity.

So yes the commenters were correct the RTL820T2 does exhibit much better performance for ADS-B reception than its E4000 based counterparts. Unsurprisingly the Airspy does still exceed the performance of the RTL dongles by a significant amount but you have to draw attention to what an absolute bargain the RTL dongles are.

I am going to perform one final test where I compare the Airspy to the R820T2 again but this time using dump1090 with –no-fix to prevent the correction of data (duplicates will still happen). This should give a true like for like comparison. We already know what the results are but its worth demonstrating what the additional cost of the Airspy translates to in outright ADS-B performance.

UPDATE :

Youssef Touil kindly supplied a version of ADSB# with duplicates suppressed, with the equivalent of dump1090’s –no-fix and with no phase “enhancement” that produce CRC valid noise. This would provide a direct comparison with the Airspy. This is available here should you wish to try it: http://airspy.com/downloads/ADSBSharp-no-fix.zip

Just to remind this isn’t to make the RTL look bad, this is preferred by sites such as such as FR24 and PlanePlotter’s sharing network as the CRC is weak and it can result in erroneous data being uploaded to their servers.

The results over a 46 hour period were as follows :

Total Messages Received:
Airspy 65,150,313
RTL 32,973,049

Airborne Position:
Airspy 4,615,972
RTL 2,270,810

Unusable:
Airspy 533
RTL 635,549

So as near as makes no difference the Airspy is doing twice the number of messages compared to the RTL. Range was again limited by radio horizon/geography both radios exceeding the 400km range.

For the money you simply can’t beat the RTL however if you’re serious about ADS-B the Airspy is most certainly the way to go.

ADS-B Reception RTL vs Airspy

I’ve recently been playing with ADS-B reception to test new revisions of my 1090Mhz ADS-B Preamp. With my location 300 meters ASL and between two international airports I’m ideally placed for reception. I wanted to see what difference there was between the nice and cheap RTL dongles and the Airspy SDR.

I had previously installed an A3 ADS-B antenna from Jetvision.de in my loft:

2015-04-18 09.49.13

You can see the preamp on the left. The indoor location is far from ideal but I currently don’t have space on the mast outside to fit it and as you can see by the results below its still performing well. At some point it will move outside. The antenna is connected using Belden RG6 with some nice quality SMA connectors from Barenco.

The preamp is a HAB Supplies 1090Mhz preamp with SAW filter. Based around the Minicircuits PSA4-5043+ it provides approximately 14dB of gain at 1090Mhz and has a Golledge SAW filter to remove out of band inter-modulation.

habamp1090-500x500

To enable a side by side comparison of the two receivers the feed was connected into a Minicircuits ZAPD-2DC-S+ power splitter. The Airspy with its ability to provide power to the preamp via bias tee was connected to the DC pass through port. The RTL was connected to the other RF port:

2015-05-09 10.35.07

A quick word on the dongle, its an older Elonics E4000 based model the only modification is the Belling-Lee connect was removed and replaced with an SMA connector. Otherwise its stock.

SDRSharp’s ADSBSharp and ADSBSpy V1.0.0.11 (Link is latest V1.0.0.12) programs to drive the dongles these fed into Virtual Radar Server and ADSB Scope. To ensure no issues both dongles were on separate USB3 buses. After briefly adjusting the gain on both dongles to get the optimal reception I left them to run for about 28 hours on a week day.

At this point its worth noting, ADSBSpy suppresses duplicate frames and it doesn’t try to correct frames with bad CRC. This is preferred by sites such as such as FR24 and PlanePlotter’s sharing network as the CRC is weak and it can result in erroneous data being uploaded to their servers. ADSBSharp does correct frames with bad CRC and doesn’t do any duplicate detection so I would expect more frames and position reports from ADSBSharp.

So the results. Firstly range :

ezgif.com-gif-maker

As you can see the overall range is generally limited by geography from my location and in certain directions both radios are getting pretty close to the radio horizon.The outer ring is 400km of which both radios managed to exceed reception. However fairly consistently the Airspy exceeded the range of the RTL in some areas by over 50km.

In the 28 hour period the RTL returned the following stats :

TotalMessages Recieved : 2,910,780
AirbornePosition : 1,345,245
AirborneVelocity : 1,342,768

The Airspy :

TotalMessages Recieved : 10,307,631
AirbornePosition : 4,836,796
AirborneVelocity : 4,410,924

The numbers speak for themselves really, the other interesting number is the number of unusable frames with the RTL was 3.4million with the Airspy it was 305!

When you consider the results from the Airspy contained no duplication or corrected CRC the results are even more impressive. So in conclusion if you are serious about ADS-B reception the Airspy with a preamp is the way to go. I suspect it will give the hardware based ADS-B receivers a run for their money too whilst being significantly cheaper (If anyone wants to supply me one I’m happy to do a head to head!)

Getting Started with Ublox Part 4 – Basic NMEA Parser

Credits : Thanks to Dave Akerman who’s NMEA Parser code these examples are based on.

Ok so now we have the GPS talking to the Arduino and you have some method of debugging its time to read that NMEA from the GPS and turn it into something we can use within our code.

The basic principle of an NMEA parser is to locate the NMEA sentences we are interested in , usually GPGGA and GPRMC. These two sentences contain most of the information you need for navigation, GPGGA is the main one used. This example will show how to parse the information from GPGGA.

Side note on the Ublox 8 series GPGGA is replaced by GNGGA by default to indicate the navigation information is from multiple GNSS sources (I.e American GPS and Russian GLONASS normally). So for this example we will look for $$GNGGA sentences. GGA sentences contain essential fix data which provide a 3D location.

An example of this is :

$GNGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

Where :

     GGA          Global Positioning System Fix Data
     123519       Fix taken at 12:35:19 UTC
     4807.038,N   Latitude 48 deg 07.038' N
     01131.000,E  Longitude 11 deg 31.000' E
     1            Fix quality: 0 = invalid
                               1 = GPS fix (SPS)
                               2 = DGPS fix
                               3 = PPS fix
             4 = Real Time Kinematic
             5 = Float RTK
                               6 = estimated (dead reckoning) (2.3 feature)
             7 = Manual input mode
             8 = Simulation mode
     08           Number of satellites being tracked
     0.9          Horizontal dilution of position
     545.4,M      Altitude, Meters, above mean sea level
     46.9,M       Height of geoid (mean sea level) above WGS84
                      ellipsoid
     (empty field) time in seconds since last DGPS update
     (empty field) DGPS station ID number
     *47          the checksum data, always begins with *

So we need to read the incoming data from the GPS module, look for a $ to indicate the start of a sentence, when the full sentence is read in go see if it is a GNGGA line. Building on the previous code we add a new procedure to read data in and transmit to the debug when a sentence is detected (or not).


#include <SoftwareSerial.h>

#define GPSENABLE 2
SoftwareSerial mySerial(4, 3); // RX, TX
byte GPSBuffer[82];
byte GPSIndex=0;
void setup()
{
  pinMode(GPSENABLE, OUTPUT);
  digitalWrite(GPSENABLE, HIGH);
  Serial.begin(9600);
  mySerial.begin(9600);
  mySerial.println("Test Program");
}

void loop()
{
  CheckGPS();
}

void CheckGPS()
{
  int inByte;
  while (Serial.available() > 0)
  {
    inByte = Serial.read();

    if ((inByte =='$') || (GPSIndex >= 80))
    {
      GPSIndex = 0;
    }

    if (inByte != '\r')
    {
      GPSBuffer[GPSIndex++] = inByte;
    }

    if (inByte == '\n')
    {
      ProcessGPSLine();
      GPSIndex = 0;
    }
  }
}
void ProcessGPSLine()
{
  if ((GPSBuffer[1] == 'G') && (GPSBuffer[2] == 'N') && (GPSBuffer[3] == 'G') && (GPSBuffer[4] == 'G') && (GPSBuffer[5] == 'A'))
  {
    mySerial.println("GNGGA Detected!");
  }
  else
  {
    mySerial.println("It was something else!");
  }
}


Now from your software serial monitor you should see :

GNGGA Detected!
It was something else!
It was something else!
It was something else!
It was something else!
It was something else!
It was something else!
It was something else!
GNGGA Detected!

As you can see we are now detecting when we have a $GNGGA sentence and ignoring the others. So lets start extracting some data from that $GNGGA string.

We know the structure of the sentence, it starts with a $ all the fields are delimited by a comma. Firstly lets up the debug speed to 19200 as we are likely to be outputting data fairly quickly. Amend the connection speed in PuTTY to 19200 and note the change in the code below.Comment out line 31 to stop the NMEA from the GPS appearing.

#include <SoftwareSerial.h>

#define GPSENABLE 2
SoftwareSerial mySerial(4, 3); // RX, TX
byte GPSBuffer[82];
byte GPSIndex=0;
unsigned int GPS_Satellites=0;
unsigned int GPS_Altitude=0;

void setup()
{
  pinMode(GPSENABLE, OUTPUT);
  digitalWrite(GPSENABLE, HIGH);
  Serial.begin(9600);
  mySerial.begin(19200);
  mySerial.println("Test Program");
}

void loop()
{
  CheckGPS();
}

void CheckGPS()
{
  int inByte;
  while (Serial.available() > 0)
  {
    inByte = Serial.read();

    mySerial.write(inByte); // Output exactly what we read from the GPS to debug

    if ((inByte =='$') || (GPSIndex >= 80))
    {
      GPSIndex = 0;
    }

    if (inByte != '\r')
    {
      GPSBuffer[GPSIndex++] = inByte;
    }

    if (inByte == '\n')
    {
      ProcessGPSLine();
      GPSIndex = 0;
    }
  }
}
void ProcessGPSLine()
{
  if ((GPSBuffer[1] == 'G') && (GPSBuffer[2] == 'N') && (GPSBuffer[3] == 'G') && (GPSBuffer[4] == 'G') && (GPSBuffer[5] == 'A'))
  {
    mySerial.println("GNGGA Detected!");
    ProcessGNGGACommand();
    mySerial.print("Altitude :");
    mySerial.println(GPS_Altitude);
    mySerial.print("Satellites :");
    mySerial.println(GPS_Satellites);
  }
}
void ProcessGNGGACommand()
{
  int i, j, k, IntegerPart;
  unsigned int Altitude;

  // $GNGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
  //                                               =====  <-- altitude in field 8

  IntegerPart = 1;
  GPS_Satellites = 0;
  Altitude = 0;

  for (i=7, j=0, k=0; (i<GPSIndex) && (j<9); i++) // We start at 7 so we ignore the '$GNGGA,'
  {
    if (GPSBuffer[i] == ',')
    {
      j++;    // Segment index
      k=0;    // Index into target variable
      IntegerPart = 1;
    }
    else
    {
      if (j == 6)
      {
        // Satellite Count
        if ((GPSBuffer[i] >= '0') && (GPSBuffer[i] <= '9'))
        {
          GPS_Satellites = GPS_Satellites * 10;
          GPS_Satellites += (unsigned int)(GPSBuffer[i] - '0');
        }
      }
      else if (j == 8)
      {
        // Altitude
        if ((GPSBuffer[i] >= '0') && (GPSBuffer[i] <= '9') && IntegerPart)
        {
          Altitude = Altitude * 10;
          Altitude += (unsigned int)(GPSBuffer[i] - '0');
        }
        else
        {
          IntegerPart = 0;
        }
      }
    }
    GPS_Altitude = Altitude;
  }
}

Why not the rest ? Exercise left for reader :)

Getting Started with Ublox Part 3 – Setting Up Software Serial for Debugging

So one of the first stumbling blocks you’ll run into is how do you diagnose and debug code on the Arduino when you’re using the only serial port for the GPS ?

The ATMega328P based Arduinos like the Uno and the Duemilanove only have one hardware UART or serial port. This is a dedicated piece of hardware on the chip to do the nitty gritty of serial communications timing and the like. You can emulate this in software but it does use considerably more memory up also it can cause timing issues with other parts of your code as it uses interrupts.

It is advised you should use the hardware UART for the GPS on any tracker to avoid timing, communication issues etc. However there is nothing stopping you using Software Serial for GPS debugging purposes (just be aware it could mess with timing on stuff like radio transmission).

So you need some method of observing the serial data back on your PC, the easy way is to add a USB to Serial module such as the UM232R by FTDI or the Sparkfun/Adafruit ones such as this https://www.sparkfun.com/products/12731. I’ll refer to whatever you’re using as “UM232R”.

So wiring it up as follows (Wiring from previous example still in place) :

arduino-ft232r

 

Arduino GND to UM232R GND (Grey wire in image above)
Arduino 3 to UM232R DB1/RXD (Blue Wire)
Arduino 4 to UM232R DB0/TXD (Purple Wire)

Plug in the Arduino and note the serial port it appears as in your computer. Now plug in the UM232R and check in Device Manager what COM port its allocated (In my case COM21)

devicesNextly you’ll need some sort of terminal program so you can see the data on this COM port. I strongly suggest you grab a copy of the excellent PuTTY from here: http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe

Open it and check Serial, enter the COM port as ascertained above and click Open
putty

 

 

 

 

 

You’ll get a black screen doing nothing. This is expected.

Ok now load the following code up on your Arduino :


#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, 3); // RX, TX

void setup()
{
 mySerial.begin(9600);
 mySerial.println("Hello, world?");
}

void loop()
{
}

Ok once done press reset on your Arduino and you should see :

helloIndicating everything is wired correctly and working.

Ok now amend the slightly as follows (assumes you’re still wired up as previous posts)


#include <SoftwareSerial.h>
#define GPSENABLE 2
SoftwareSerial mySerial(4, 3); // RX, TX

void setup()
{
pinMode(GPSENABLE, OUTPUT);
digitalWrite(GPSENABLE, HIGH);
Serial.begin(9600);
mySerial.begin(9600);
mySerial.println("Hello, world?");
}

void loop()
{
if (Serial.available())
mySerial.write(Serial.read());
}

Now you should see Hello, World? followed by the NMEA from the GPS module. Basically the code is reading from the hardware serial port and then echoing this back to your software serial port. From this point you can start to do your own code and output information to the software serial port to help you debug.

 

Getting started with Ublox Part 2 – Setting Airborne Dynamic Model

Ok firstly we need to switch the RX&TX connections over on the board as we were passing through to the in board Serial to USB chip. This is important, don’t do this and nothing will work

So amend the wiring as follows :

Arduino 5V to GPS Board 5V
Arduino GND to GPS Board GND
Arduino Pin 0 (RX) to GPS Board TX
Arduino Pin 1 (TX) to GPS Board RX
Arduino Pin 2 to GPS Board EN

Load the following code up on your Arduino (close down U-Center at this point as it will be hanging on to the serial port).  This code is derived from Jon Sowman and Joey flight computer CUSF https://github.com/cuspaceflight/joey-m/tree/master/firmware

This code opens the serial port, send the binary command to set the dynamic model, waits for confirmation this has been acknowledged by the GPS. Once done it just drops to the main loop where it just blinks the Status LED once a second to indicate success.

#include <util/delay.h>

#define GPSENABLE 2
#define STATUSLED 13

void setup() {
 pinMode(GPSENABLE, OUTPUT);
 pinMode(STATUSLED, OUTPUT);
 Serial.begin(9600);
 _delay_ms(500);
 digitalWrite(GPSENABLE, HIGH);
 _delay_ms(500);
 setGPS_DynamicModel6();
}
void loop() {
 digitalWrite(STATUSLED,!digitalRead(STATUSLED));
 _delay_ms(1000);
}
void setGPS_DynamicModel6()
{
 int gps_set_sucess=0;
 uint8_t setdm6[] = {
 0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06,
 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00,
 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C,
 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC };
 while(!gps_set_sucess)
 {
 sendUBX(setdm6, sizeof(setdm6)/sizeof(uint8_t));
 gps_set_sucess=getUBX_ACK(setdm6);
 }
}
void sendUBX(uint8_t *MSG, uint8_t len) {
 Serial.flush();
 Serial.write(0xFF);
 _delay_ms(500);
 for(int i=0; i<len; i++) {
 Serial.write(MSG[i]);
 }
}
boolean getUBX_ACK(uint8_t *MSG) {
 uint8_t b;
 uint8_t ackByteID = 0;
 uint8_t ackPacket[10];
 unsigned long startTime = millis();

// Construct the expected ACK packet
 ackPacket[0] = 0xB5; // header
 ackPacket[1] = 0x62; // header
 ackPacket[2] = 0x05; // class
 ackPacket[3] = 0x01; // id
 ackPacket[4] = 0x02; // length
 ackPacket[5] = 0x00;
 ackPacket[6] = MSG[2]; // ACK class
 ackPacket[7] = MSG[3]; // ACK id
 ackPacket[8] = 0; // CK_A
 ackPacket[9] = 0; // CK_B

// Calculate the checksums
 for (uint8_t ubxi=2; ubxi<8; ubxi++) {
 ackPacket[8] = ackPacket[8] + ackPacket[ubxi];
 ackPacket[9] = ackPacket[9] + ackPacket[8];
 }

while (1) {

// Test for success
 if (ackByteID > 9) {
 // All packets in order!
 return true;
 }

// Timeout if no valid response in 3 seconds
 if (millis() - startTime > 3000) {
 return false;
 }

// Make sure data is available to read
 if (Serial.available()) {
 b = Serial.read();

// Check that bytes arrive in sequence as per expected ACK packet
 if (b == ackPacket[ackByteID]) {
 ackByteID++;
 }
 else {
 ackByteID = 0; // Reset and look again, invalid order
 }
 }
 }
}

So there you go that’s the module in Dynamic Model 6 – Airborne < 1g which is generally the one you want for High Altitude ballooning. If your application is rocketry there is mode 8 – Airborne < 4g. Its quite viable to drop back to mode 3 – Pedestrian when below 9km in altitude. The airborne modes have large positional deviation, whereas the pedestrian modes have small deviation. Airborne modes are still perfectly accurate enough to locate a payload.

Ok so what next ? You have a choice at this point you can write a parser to read NMEA GNGGA strings to obtain your location information, you can use a prebuilt library that does this such as TinyGPS or finally you can use the UBX protocol to poll the module for information. I’ll discuss using UBX in the next article.

Getting started with Ublox Part 1 – Basic Operation of the Breakout Board

Ublox GPS modules are used heavily in HAB due to their high performance, altitude limit and power usage. They are extremely well documented. By default they output NMEA strings at 9600 baud but with a max altitude limit of 12km . There are a number of ways to communicate with the module NMEA, PUBX or the binary UBX protocol.

For these examples we are going to use a HAB Supplies uBLOX MAX-M8Q Breakout With Quad-V Antenna for Arduino linking to an Arduino Duemilanove.

Basic Operation Test
arduino_exampleConnect as follows :

Arduino 5V to GPS Board 5V
Arduino GND to GPS Board GND
Arduino Pin 0 (RX) to GPS Board RX
Arduino Pin 1 (TX) to GPS Board TX
Arduino Pin 2 to GPS Board EN

Load the following sketch. All this does is turn the level convertor on the GPS Board so data from the GPS module is passed through to the Arduinos USB to Serial port.


#define GPSENABLE 2

void setup() {
 pinMode(GPSENABLE, OUTPUT);
 digitalWrite(GPSENABLE, HIGH);
}

void loop() {
}

Once loaded press the serial monitor button in Arduino and you should see NMEA strings being output :

arduino_example2If you stick the module in a window or outside you should start to see a clock and then actual location information. At this point if you’re a Windows user you can go download the Ublox U-Center. All the commands referenced in the following examples were obtained via U-Center. Close Arduino down, open U-Center and point it at the Arduino’s COM port :

ucenter

Note the GLONASS Satellite (Russian flag). Ok so how do we use this to ascertain the commands we want to send to the GPS module to put it in high altitude mode.

In Ucenter click View -> Messages.

Click the + next to NMEA to collapse it and then click the + next to UBX to expand it. Click + next to CFG to expand. UBX-CFG is where most of the configuration commands for the Ublox modules are located. All these commands are covered in extreme detail in the Ublox Receiver Description Including Protocol Specification.

However I’ll advise the setting to enable operation above 12km is down UBX-CFG-NAV5. Click NAV5. If you drop the dynamic model box down from the default 0 – Portable mode to 6 – Airborne < 1g you will notice the table at the bottom kindly gives the binary string you need to send to the module to enable this mode :


0000 B5 62 06 24 24 00 FF FF 06 03 µb$$ÿÿ
000A 00 00 00 00 10 27 00 00 05 00 '
0014 FA 00 FA 00 64 00 2C 01 00 3C úúd,<
001E 00 00 00 00 C8 00 00 00 00 00 È
0028 00 00 1A 28

So basically we need to send this to the GPS module and check it acknowledges it. This is discussed in Part 2 of this article.

 

Not quite 5 minute guide to making an NTP Server

Revision history at the bottom.

I’ve had a number of requests to update a previous article I wrote a 5 minute guide on making an NTP server with the GPS Board from HAB Supplies. The version of NTP and the Pi kernel were very old on the image I linked. With the new Pi Plus board I decided to revisit these instructions.

HAB Supplies Raspberry Pi+ GPS Expansion Board

HAB Supplies Raspberry Pi+ GPS Expansion Board

Ideally rather than supplying a premade image I would have a set of concise instructions on making your own install from scratch so you could use the latest versions of the software. With assistance from David Taylor who did lots of background work on this here I present the following instructions on making a cheap PPS disciplined NTP Time server using one of the Raspberry Pi GPS boards I sell on HAB Supplies.

The guide assumes you have a cursory knowledge of Linux, enough to install Raspbian and login should do.

You will need a Raspberry Pi B+, HAB Supplies Raspberry Pi+ GPS Expansion Board and a suitable GPS antenna. This guide is assuming you’re using Raspbian installed from 2015-05-05-raspbian-wheezy.img . Download and write this to an SD card (See http://www.raspberrypi.org/documentation/installation/installing-images/README.md)

Attach the HAB Supplies Raspberry Pi+ GPS Expansion Board to the Pi, insert the SD card, connect the antenna and network cable and boot the Pi up. Either connect locally or via SSH to the Pi.

Text in italics is what you type.
Text in red indicates editing inside a file.

Prerequisite Settings

sudo raspi-config
1. Expand Filesystem
2. Advanced Options -> Disable Serial Shell (optional)
Reboot

sudo apt-get update
sudo apt-get dist-upgrade
sudo rpi-update
sudo reboot
sudo apt-get install pps-tools
sudo apt-get install libcap-dev
sudo nano /boot/cmdline.txt –
Add bcm2708.pps_gpio_pin=18 at the end of the line. Save and close
(If you have previously followed these instructions remove this line above)
sudo nano /boot/config.txt – Add dtoverlay=pps-gpio,gpiopin=18 on a line.
sudo nano /etc/modulesAdd pps-gpio on a new line. Save and close & Reboot

sudo reboot

Verifying PPS Is Working

Ensure the GPS has a lock and the Green PPS LED on the HAB Supplies Raspberry Pi+ GPS Expansion Board is blinking once a second.

dmesg | grep pps

Output should be similar to :

 [    0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2708.boardrev=0x10 bcm2708.serial=0x1a25ea38 smsc95xx.macaddr=B8:27:EB:25:EA:38 bcm2708_fb.fbswap=1 bcm2708.disk_led_gpio=47 bcm2708.disk_led_active_low=0 sdhci-bcm2708.emmc_clock_freq=250000000 vc_mem.mem_base=0x1ec00000 vc_mem.mem_size=0x20000000  dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait bcm2708.pps_gpio_pin=18
 [    0.029423] bcm2708: GPIO 18 setup as pps-gpio device
 [   10.159940] pps_core: LinuxPPS API ver. 1 registered
 [   10.161448] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti &lt;<a href="mailto:giometti@linux.it">giometti@linux.it</a>&gt;
 [   10.172015] pps pps0: new PPS source pps-gpio.18
 [   10.173557] pps pps0: Registered IRQ 188 as PPS source

sudo ppstest /dev/pps0

Output should be similar to:

 trying PPS source "/dev/pps0"
 found PPS source "/dev/pps0"
 ok, found 1 source(s), now start fetching data...
 source 0 - assert 1418933982.998042450, sequence: 970 - clear  0.000000000, sequence: 0
 source 0 - assert 1418933983.998045441, sequence: 971 - clear  0.000000000, sequence: 0

(Press CTRL+C to quit). This indicates the PPS Module is loaded (top example) and is working (bottom).

GPS board mounted in Geaux Robot Dog Bone Case for Raspberry Pi B+ also available from HAB Supplies

GPS board mounted in Geaux Robot Dog Bone Case for Raspberry Pi B+ also available from HAB Supplies

Enabling PPS/ATOM Support in NTPD

The supplied version of NTPD on the Raspberry Pi doesn’t support PPS so we need to recompile it (Please note that some of these steps may take up to 30 minutes).

wget http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-4.2.8p3.tar.gz
tar zxvf ntp-4.2.8p3.tar.gz
cd ntp-4.2.8p3/
./configure -enable-linuxcaps
make
sudo make install
sudo service ntp stop
sudo cp /usr/local/bin/ntp* /usr/bin/  && sudo cp /usr/local/sbin/ntp* /usr/sbin/
sudo nano /etc/ntp.conf

Add
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0  flag3 1  refid PPS

Amend

server 0.debian.pool.ntp.org iburst prefer

Note You MUST add a preferred server or PPS doesn’t work.
Save and close nano.

sudo service ntp restart

After a few minutes run

ntpq –p

if you get oPPS(0) this indicates source selected, Pulse Per Second (PPS) used and everything is working.

If you aren’t seeing the settings its possible the NTP server is picking up the NTP information via DHCP which is over riding your settings above. Do this :

rm /etc/dhcp/dhclient-exit-hooks.d/ntp
rm /var/lib/ntp/ntp.conf.dhcp

Then reboot.

Further Reading

David Taylor’s website here http://satsignal.eu/ntp/Raspberry-Pi-NTP.html goes into much further detail about the process above and covers graphing, remote access monitoring etc and I highly recommend you read it.

Hope this helps, let me know how you get on with these instructions and I’ll try keep them up to date.

Thanks to:

David Taylor
Chris Stenton for the new kernel fix.
Tris Mabbs for the DHCP issue heads up.
Michiel Kanis for testing DHCP fix.

Updated : 03/07/15 NTP version and location amended – Thx Greg!
Checked : 13/06/15 Works with 2015-05-05-raspbian-wheezy.img
Updated : 13/04/15 ntp-4.2.8p2.tar.gz links updated.
Updated : 23/02/15 Verified these instructions are good with 2015-02-16-raspbian-wheezy.img as a base
Updated : 20/02/15 ntp-4.2.8p1.tar.gz links updated.
Updated : 28/01/15 DHCP Client can pick up NTP from DHCP server and override all your good work. See below.
Updated : 27/01/15 New kernel breaks previous instructions. Updated.
Updated : 26/12/14 Updated NTP to 4.2.8 and tested with Raspbian 2014-12-14

pAVA R9 takes a trip to Russia!

Although the new pAVA R9 board flew successfully on our glider record attempt (Here : http://ava.upuaut.net/?p=650) I decided it would be best to actually launch it under a balloon. With quite a bit of help (i.e he re-wrote it) from Phil Heron the code for the DominoEX was modified to transmit THOR16 (DominoEX extension with FEC, by Dave W1HKJ). I believe this is the first balloon to use it.

Error corrected telemetry plus the extremely stable radio should make for an easy payload to track. The weather hasn’t been exactly pico friendly recently but the winds looked great, fast and taking a swing by Poland (later turned out not to be the case). So I soldered some antennas on, a battery and wrapped the lot in “space insulation” (foam bag, Kitkat wrapper foil and Kapton tape) :

IMG_1589

I left the battery disconnected until just before launch. The tracker came in at 12.4g all in which is my lightest by far :

09 - aCwFImBThe weather on Saturday was very changeable. Initially I called the launch off but around lunch time the clouds cleared although the wind didn’t subside.The predicted path looked too good to waste so I took chance. With 1.5g of free lift the 36″ Qualatex balloon didn’t look inflated at all.

The battery was soldered on and attached to the balloon, the lot was thrown in the car and I drove up to my launch location close to home. It was extremely windy up there and the balloon was getting whacked about, rather than hold on to it I decided to just let it go and hope for the best.

Initially it rose up but then seemed to hold at an altitude, shortly afterwards I lost it visually jumped back in the car and drove home.

It was only when I got home I noticed just after launch it had dropped back down, possibly landed in a field, taken off again and missed the electricity pylons by meters :

10 - xoZe7U8I seem to be getting quite good at the “unintentionally sketchy launch”. The balloons ascent was interesting to say the least but up was up even if it did contain small amounts of down on the way.

And off it went climbing up to about 7km where it entered a lovely float, the speed peaked at 175kmph (just over 100mph) as it sped towards Europe. Floating through the night over Germany I woke up on Sunday morning to find it had been tracked almost continuously through the night and was in Romania. Fortunately we managed to muster enough trackers to follow it all the way to the Ukraine where it was tracked by UR6ISU and UY0LL and as it entered southern Russia. Finally around 14:59UTC on Sunday the battery finally died at 7.5km just after entering Russia reporting a final battery voltage of 776mV, 8 satellites and situation normal. I have no reason to believe the balloon didn’t carry on through the night.

So covering an impressive greater circle distance of 2900km (3rd in the records) and averaging over 100kmph in 26 hours one could call this a successful test!

pava-12012014-3Battery data, speed and attitude over the flight (Thanks to x-f for this)
pava-12012014-1

As ever a huge thank you to all the regulars who take the time to track and  to the amateurs who responded to our calls for help on various forums and took the time to help out. It really is a great community.

New tracker pAVA R9

With the end of life notification for the RFM22B I have been working on a replacement for the pAVA R7 Tracker for a while now. I decided to get away from the RFM22B style modules as they didn’t offer very much flexibility and the quality can be dubious. I wanted to fit the RF chip with a TCXO to prevent drift at colder temperatures.

My initial stab at it pAVA R8 was fitted with a step up and had a number of faults with it :

IMG_1939It tested a few new ideas I had. Firstly the AVR Crystal, I’ve not found very small crystals in 4Mhz or below so I fitted an extremely small 16Mhz crystal and set the fuses to DIV/8 so the AVR runs at 2Mhz and therefore within the specs for running at 1.8V. This worked, however the SI4060 circuit I’d missed a few critical wires off, the board was also a total pig to solder. In total I made two by hand. Fixes were applied using Kynar wire to fix the missing SI4060 connections.

With some assistance from Arko using some code KT5TK developed for the SI4464 the tracker code was re-written to work with the SI4060 radio. This turned out to be a great success. The tracker supplied a solid and stable RTTY. On the 10th of November I strapped it to the bottom of a 36″ foil and launched it. The tracker performed flawlessly, sadly the balloon didn’t and at 6km altitude the balloon burst and dropped the tracker near Ridington. Leo Bodnar drove up in the dark but the landing site was inaccessible, he got a few positions from the tracker which looked like it was in a tree. See the KML for flight path.

Taking what I’d learnt and some inspiration from Leo Bodnar, I redesigned the board. The 16Mhz crystal with the DIV/8 worked so that was kept. The SI4060 circuit worked, however I wanted to open up the more interesting data modes like DominoEX. Leo suggested even though it was totally out of spec a 16.369Mhz crystal would give a minimum step size on the SI4060 of (FCrystal/2^21) = 7.805Hz. The step size for DominoEX16 is 15.625Hz so 2 x step = 15.61Hz which is close enough (Thx to SP3OSJ for maths lesson!)

The bane of my life the ICSP programming header, after an off the cuff comment from Mark Jessop about snapping it off I came up with a design for a snap off ICSP header allowing easy programming with a standard header and then the ability to snap it off before launch.

With Leo’s successful launches using solar I wanted to also give the board flexible power options, retaining my tried and tested LTC3526 step up but also having an option for solar + lipo power. Rather than sticking all this on one board I decided to mezzanine the power board onto the tracker board. So you can pick which power source the tracker uses.

Finally I took the opportunity to try some new (to me) production techniques. Firstly I acquired a Stencil8 clone peg board from Arachnid Labs :

P1010379_clipped_rev_1.jpeg.743x418_q85_crop-smart_upscale

So I didn’t have to get three separate PCB’s made up I did my first “framed” board in Eagle with mouse bites to snap the individual boards out :

Untitled

On the right is the tracker board, on the left bottom is the step up and left top is the Lipo + Solar board. Note snap off ICSP header. I ordered these from Hackvana.com along with a stencil which duly arrived :

2 - 1J6Bgql

5 - p3dsUx5 6 - Knz2Jwp 7 - RVsJ6Nc

The finished result after spending 7 mins in a T962A Oven and snapped out :

01 - v3sg93U

02 - TBlz9Qc 03 - 0Vk3yAv

And with the step up power board installed on top.

After a few initial false starts (solder had leaked down the snap of ICSP connector and shorted GND and VCC out, also I’d mounted the µC crystal incorrectly) the board was soon transmitting RTTY using the code developed on the R8 board.

Power consumption via the LTC3526 was quite impressive too. Using the MAX7C and 2Mhz AVR the board was, with the existing power saving code, using 30% less power than the previous board.  With a guitar string antenna and an AAA soldered in place I hung the board out in my back garden for a run test.

Weathering out a fairly nasty storm the board transmitted its new DominoEX16 code continuously for 28.5 hours before the battery gave out. This equates to over 70 hours from an AA. This is without any real power saving improvements over the code developed for the R7 board here : http://ava.upuaut.net/?p=437

Quite a big jump from 45 hours!

A new world record … possibly?

Edit : Daves write up here : http://www.daveakerman.com/?p=1469

Its been an interesting weekend in HABing, a huge number of flights over Europe. SP9UOB’s SEBA flight continues over the furthest reaches of Russia as I type this. Together with Dave Akerman we came up with a plan to do something a little interesting. There is a world record for the highest altitude paper plane by a certain Mr Haines of The Register. Lester has always been a fan of the balloon stuff and his existing record of 27km always seemed a little low to us High Altitude Ballooners.

So after a brief conversation one evening we decided to have a pop at it. The tracker for the plane was my new pico board the PAVA R9. Featuring a ATMega328P-MU running at 2Mhz and a TCXO equipped SI4060 RF chip the tracker weighs in at a paltry 2g with antennas. Running from a step up board to 1.8V in theory it should run for 24 hours from an AAA battery :

Umh9OY9

So the plan was simple make a paper plane, after some very brief bit of testing I opted for a a flying wing style plane which met my criteria of :
a) It sort of flies
b) no pointy bits
c) Somewhere to put the tracker

Dave kindly supplied some pink A1 Card which we cut into 2 A2 pieces to construct the plane. Liveries were added and trackers installed in the “nose cone” :

IMG_0144

IMG_1558

The tracker was sealed in with some obligatory pink gaffer tape and an cord attachment was put on the rear.

Mean while Dave made a Pi up in a box with some carbon fibre runners and resistive cut downs. The glider would rest on the runners and be held in place with a cord to be severed by the Pi at a predetermined altitude and location. As its technically not permitted to drop stuff over the UK without a parachute we opted for dropping the plane over the North Sea.

Originally we were going to fly two gliders but with the ground winds picking up we decided to leave one on the ground. Dave’s Pi was called CLOUDY and the plane was called SNOW. Additionally a 3rd tracker called WANNAB1 was attached above the Pi, however this tracker appeared to have a damaged antenna and didn’t work for the flight.

With the wind gusting judging the neck lift of the 1600g H2 filled balloon was sketchy at best. We aimed for 2m/s which we seemed to get on launch, more though luck than judgement. Climbing up into the sky other receivers around the UK and Europe started to receive the transmissions from both CLOUD and SNOW. CLOUD was transmitting SSDV images back, however the weight of the paper plane had pulled the payload downwards so we got some nice ground images :

2013-12-28--13-33-08-CLOUDY-7E42013-12-28--16-11-33-CLOUDY-807

As the sun started to set Dave’s CLOUDY returned this wonderful image showing Venus above the sun setting below the horizon :

2013-12-28--16-44-33-CLOUDY-810

Both CLOUDY and SNOW continued climbing and entered the extremely fast winds at times touching 300kmph the balloon moved out of UK Airspace and towards Europe. At 16:14:21 as the balloon crossed longitude 4 and at 31849 meters altitude the Pi activated the FET that heated up the resistor and severed the connection between the paper plane and the balloon.

flight-6

SNOW began its initially rapid decent back towards Earth. It was obviously from the decent rate it was stalling, gliding, stalling but followed a fairly straight path down towards the Netherlands.

flight-4

flight-2

As its passed through the cold zone on the way down the GPS, which was not insulated particularly well probably dropped well below -50’C and stopped working. The radio continued transmitting however. The GPS did briefly pick up and returned some valid data around 3km altitude. Stations monitored it pretty much to the ground but it was just transmitting 0’s for location information. PD5DJ immediately went out to location it but was unable to pick up any signal. At this time the paper plane remains missing.

Edit : Wonderful 360′ of the flight path from Geoff Mather  : http://360.g8dhe.net/HAB_Flights/2013_Flights/Snow_20131228/Cloudy_and_Snow.html

CLOUDY continued onwards rebooting twice as it attempted to cut the non existent second plane and finally itself from the balloon. Probably due to cold causing a lack of volts the cut down over Poland of the Pi didn’t work and CLOUDY continued onwards to the Ukraine before its batteries gave out still in the air.

With a maximum altitude of 31849m this beats the previous world record of 27307m by a considerable amount. On behalf of Dave and I it will be submitted to the Guiness Book of World Records in the new year. Additionally as a side note the current paper plane distance record is about 260 feet, SNOW covered 63km in a straight line howwever I suspect we won’t be eligible for this record. Its certainly more than James May’s 26 miles attempt.

Thanks to all the trackers who help with this record attempt and to Dave, Leo and Julie. Cheers to Ara for assistance with the code. Raw data here :

CLOUDY CSV
SNOW CSV