astro-fan
Published

GPS-accuracy with BN-280

Compare your Arduino with GPS-precision - use millis() and micros()

BeginnerFull instructions provided1,978
GPS-accuracy with BN-280

Things used in this project

Hardware components

Enclosure for Arduino Mega 2560
Enclosure for Arduino Mega 2560
×1

Hand tools and fabrication machines

Beitian BN-280 GPS-Receiver

Story

Read more

Custom parts and enclosures

GPS-accuracy with BN-280

Used GPS-Receiver

Schematics

2560

Tested board

Code

GPS-accuracy

Arduino
Measure the precision of your Arduino [GPS-time-stamp PPS -vs- measured time with micros() and millis()]
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//     demonstrate how to receive GPS-data character by character with an Beitian BN-280 and an Arduino Mega 2560
//
//     with the 2.nd and 3.rd listing you can test the accuracy of your Arduinos - the clock-rate is mostly not very precise
//
//
//                                    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//                                    x                            x
//                                    x          BN-280            x
//                                    x                            x
//                                    x                            x
//                                    x  ceramic-antenna upwards   x
//                                    x                            x
//                                    x                            x 
//                                    x           LED's (downside) x  blue LED flasches 1x per sec - 
//                                    x                            x  red LED flashes only if you receive valid data
//                                    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//                                           |  |  |  |  |  |
//                                   pin-nr. 6  5  4  3  2  1
//                                           |  |  |  |  |  |
//                                           |  |  |  |  |  1-- = PPS  (1 short pulse pes second if BN-280 received valid data)
//                                           |  |  |  |  2----- = GND  ( 0V from Arduino Mega)
//                                           |  |  |  3 ------- = TX   ( GPS-data to PC)
//                                           |  |  4----------- = RX   ( data from PC - mostly not needed)
//                                           |  5-------------- = VCC  ( +5V from Arduino Mega)
//                                           6----------------- = BOOT (NC) normally not used
//
//
//      wiring diagram BN-280 to Arduino Mega 2560:
//
//      BN-280     ---     Arduino Mega 2560
//      ------------------------------------ 
//      pin-1      ---                pin  2   (used in anothe program for Interrupt to test the accuracy of the Arduino)
//      pin-2      ---                   GND
//      pin-3      ---                pin 19   (used as Serial1 with 9600)
//      pin-4      ---     not used
//      pin-5      ---                   VCC
//      pin-6      ---     not used
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                 //
//  Listing 1 can be used for a High-Precision Clock, for a GPS-Tracker or someone else   -   Time is GPS-time     //
//                                                                                                                 //
//  With Listings 2 and 3 you can check the accuracy of your Arduino Mega (or other Arduini too)                   //
//  The PPS of your BN-280 has a very high accuracy (like GPS)                                                     //
//                                                                                                                 //
//  The internal 'clock' or 'timer' of an Arduino is not very precise                                              //
//                                                                                                                 //
//  My Mega 2560 works not like discribed with 16MHz                                                               //
//  It works with about 16,017MHZ                                                                                  //
//  This value is relatively constant, only with a small temperature-drift                                         //
//                                                                                                                 //
//  Program 2 and 3 counts the PPS-signal and read the time of your Arduino with micros() or nanos()               //
//                                                                                                                 //
//  Tis listing contains 3 programs - please choose only one at the same time                                      //
//                                                                                                                 //
//                                                                                                                 //
//  Response of Listing 1 is:    155230 = 15:52:30 ; lat ; 51.362358093261; lon ; 7.077597618103                   //
//                                                                                                                 //
//                                Time     h  m  s               Lat                   Lon                         //
//                                                                                                                 //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////





/*
///////////////////////////////////////////////////// Begin Program 1 ///////////////////////////////////////////////
//                                                                                                                 //
const byte interruptPin =  2;                                                                                      //
char vergleich='$';                    // new line start with "$"                                                  //
char zeichen;                                                                                                      //
char teil0[20];                                                                                                    //
char teil1[20];                                                                                                    //
char teil2[20];                                                                                                    //
String zeichenkette, gesamttext,text1, text2, text3, text4, text5, text6;;                                         //
int pos=1;                                                                                                         //
double latoriginal;      // lat = 52,...                                                                           //
double lonoriginal;      // lon =  7,...                                                                           //
double Zeit,Puffer,stunde,minute,sekunde;;                                                                         //
//-----------------------------------------------------------------------------------------------------------------//
void setup()                                                                                                       //
{                                                                                                                  //
 Serial.begin(115200);                             // speed to computer                                            //
 Serial1.begin(9600);                              // speed from BN-280                                            //
 pinMode(interruptPin, INPUT_PULLUP);                                        // Important: INPUT_PULLUP !!!        //
 zeichenkette=" ";                                                                                                 //
}                                                                                                                  //
//-----------------------------------------------------------------------------------------------------------------//
void loop()                                                                                                        //
 {                                                                                                                 //
  if(zeichenkette=="$")                            // a new line starts with "$"                                   //
   {                                                                                                               //
    do                                                                                                             //
     {                                                                                                             //
      zeichen=Serial1.read();                                                                                      //
      if((zeichen>36)&&(zeichen<91))               // valid character from ASCII 36 to ASCII 91                    //
       {                                                                                                           //
        if (zeichen!=',')                          // data are separated by ","                                    //
         {                                                                                                         //
          zeichenkette = zeichenkette + zeichen;   // add each character to a string                               //
         }                                                                                                         //
        else                                                                                                       //
         {                                                                                                         //
          if (pos==6)                                                                                              //
           {                                                                                                       //
            text6=zeichenkette;                                                                                    //
            zeichenkette="";                                                                                       //
            pos++;                                                                                                 //
           }                                                                                                       //
          if (pos==5)                                                                                              //
           {                                                                                                       //
            text5=zeichenkette;                                                                                    //
            zeichenkette="";                                                                                       //
            pos++;                                                                                                 //
           }                                                                                                       //
          if (pos==4)                                                                                              //
           {                                                                                                       //
            text4=zeichenkette;                                                                                    //
            zeichenkette="";                                                                                       //
            pos++;                                                                                                 //
           }                                                                                                       //
          if (pos==3)                                                                                              //
           {                                                                                                       //
            text3=zeichenkette;                                                                                    //
            zeichenkette="";                                                                                       //
            pos++;                                                                                                 //
           }                                                                                                       //
          if (pos==2)                                                                                              //
           {                                                                                                       //
            text2=zeichenkette;                                                                                    //
            zeichenkette="";                                                                                       //
            pos++;                                                                                                 //
           }                                                                                                       //
          if (pos==1)                                                                                              //
           {                                                                                                       //
            zeichenkette="";                                                                                       //
            pos++;                                                                                                 //
           }                                                                                                       //
         }                                                                                                         //
       }                                                                                                           //
     }                                                                                                             //
    while(zeichen!=vergleich );                                                                                    //
   }                                                                                                               //
  else                                                                                                             //
   {                                                                                                               //
    if (text3=="A")                          // Ist die ein gltiger Datensatz ?    //    valid data?              //
     {                                       //                                                                    //
      text2.toCharArray(teil0,20);           //                                                                    //
      Zeit=strtod(teil0,NULL);               // convert time(text) to time(number)                                 //
                                             //                                                                    //
      text4.toCharArray(teil1,20);           //                                                                    //
      latoriginal=strtod(teil1,NULL);        // convert lat(text) to lat(number)                                   //
      latoriginal=latoriginal/100;           //                                                                    //
                                             //                                                                    //
      text6.toCharArray(teil2,20);           //                                                                    //
      lonoriginal=strtod(teil2,NULL);        // convert lon(text) to lon(number)                                   //
      lonoriginal=lonoriginal/100;           //                                                                    //
                                             //                                                                    //
      stunde=int(Zeit/10000.0);              // separate time in:                                                  //
      Puffer=Zeit-stunde*10000;              // hours                                                              //
      minute=int(Puffer/100.0);              // minutes                                                            //
      sekunde=Zeit-stunde*10000-minute*100;  // seconds                                                            //
                                                                                                                   //
      ////////////////////////////////////////////////////////////////////////     Output only with valid data     //
                                             //                                                                    //
      Serial.print(Zeit,0);                  // print received time                                                //
      Serial.print(" = ");                   //                                                                    //
      Serial.print(stunde,0);                // print hours                                                        //
      Serial.print(":");                     //                                                                    //
      Serial.print(minute,0);                // print minutes                                                      //
      Serial.print(":");                     //                                                                    //
      Serial.print(sekunde,0);               // print seconds                                                      //
                                             //                                                                    //
      Serial.print(" ; lat ; ");             //                                                                    //
      Serial.print(latoriginal,12);          // print lat                                                          //
      Serial.print("; lon ; ");              //                                                                    //
      Serial.println(lonoriginal,12);        // print lon                                                          //
     }                                                                                                             //
    zeichenkette = vergleich;                                                                                      //
    pos=1;                                                                                                         //
   }                                                                                                               //
 }                                                                                                                 //
///////////////////////////////////////////////////////// End Program 1 /////////////////////////////////////////////
*/




//////////////////////////////////////////////////////// Begin Program 2 ////////////////////////////////////////////
//                                                                                                                 //
//                                      This program show the difference between GPS-precision und Arduino         //
//                                      This Program uses micros()                                                 //
//                                                                                                                 //
//                                      Arduino is triggerd vis interrupt from BN-280                              //
//                                      The PPS-signal has GPS-accuracy                                            //
//                                                                                                                 //
//                                      PPS has the highest precision you get free if your board has a pps-output  //
//                                                                                                                 //
//                                      At the beginning you have a countdown                                      //
//                                      On 0 the time is reset to 0                                                //
//                                      Then every sec you get a new response like:                                //
//                                      -2   8188288                                                               //
//                                      -1   9189348                                                               //
//                                       0   0                                                                     //
//                                       1   1001064                                                               //
//                                       2   2002124                                                               //
//                                       3   3003188                                                               //
//                                      and so on                                                                  //
//                                                                                                                 //
//                                      The example values of my Arduino shows, that every sec the internal        //
//                                      counter - called by micros() - added not exactly 1000000microsecons        //
//                                                                                                                 //
//                                      Here the difference is 1064microsec in the first sec                       //
//                                      After 2sec the differece is 2124microsec                                   //
//                                                                                                                 //
//                                      My Arduino is to fast. In 3sec it counts 3188microsec to much              //
//                                      In 12 hours the different was 46,119484sec                                 //
//                                                                                                                 //
//                                      That's nothing for high precision                                          //
//                                      But it's good enogh for many experiments                                   //
//                                                                                                                 //
//                                      You can copy the values from the monitor-program into Win-Editor           //
//                                      Save the file to test.txt                                                  //
//                                      Open the file with Excel, separated by " " (blank)                         //
//                                      Then show an x-y plot                                                      //
//                                                                                                                 //
//-----------------------------------------------------------------------------------------------------------------//
//                                                                                                                 //
const byte interruptPin =  2;                                                                                      //
const byte ausgang1     =  5;                                                                                      //
const byte ausgang2     =  7;                                                                                      //
const byte ledPin       = 13;                                                                                      //
double Ausgabe,Zeitpunkt,microsPrevious, microsNow1,microsDelta1;                                                  //
int identifier;                                                                                                    //
int messwerte;                                                                                                     //
int messpos = 0;                                                                                                   //
int idlevel = 0;                                                                                                   //
int gesendet = 0;                                                                                                  //
//-----------------------------------------------------------------------                                          //
void setup()                                                                                                       //
 {                                                                                                                 //
  Serial.begin(115200);                                                                                            //
  pinMode(ledPin,       OUTPUT);                                                                                   //
  pinMode(ausgang1,     OUTPUT);                                                                                   //
  pinMode(ausgang2,     OUTPUT);                                                                                   //
  pinMode(interruptPin, INPUT_PULLUP);                                   // Important: INPUT_PULLUP !!!            //
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);                                             //
  Zeitpunkt=-10;                                                                                                   //
  microsPrevious = micros();                                                                                       //
 }                                                                                                                 //
//-----------------------------------------------------------------------------------------------------------------//
void loop()                                                                                                        //
 {                                                                                                                 //
  // nothing to do - Program run through the Interrupt                                                             //
 }                                                                                                                 //
//-----------------------------------------------------------------------------------------------------------------//
void blink()                                                                                                       //
 {                                                                                                                 //
  microsNow1 = micros();                                                                                           //
  microsDelta1=microsNow1-microsPrevious;                                                                          //
  microsPrevious=microsNow1;                                                                                       //
  if(Zeitpunkt==0)                                                                                                 //
   {                                                                                                               //
    Ausgabe=0;                                                                                                     //
   }                                                                                                               //
  else                                                                                                             //
   {                                                                                                               //
    Ausgabe=Ausgabe+microsDelta1;                                                                                  //
   }                                                                                                               //
  Serial.print(Zeitpunkt,0); // , 0);                                                                              //
  Serial.print("   ");                                                                                             //
  Serial.println(Ausgabe,0); // , 0);                                                                              //
  Zeitpunkt++;                                                                                                     //
 }                                                                                                                 //
//-----------------------------------------------------------------------------------------------------------------//
//////////////////////////////////////////////////////// End Program 2 //////////////////////////////////////////////





/*
//////////////////////////////////////////////////////// Begin Program 3 ////////////////////////////////////////////
//                                                                                                                 //
//                                      Show the difference between GPS-precision und Arduino                      //
//                                      This Program uses millis()                                                 //
//                                                                                                                 //
//                                      Arduino is triggerd vis interrupt from BN-280                              //
//                                      The PPS-signal has GPS-accuracy                                            //
//                                                                                                                 //
//                                      PPS has the highest precision you get free if your board has a pps-output  //
//                                                                                                                 //
//                                      At the beginning you have a countdown                                      //
//                                      On 0 the time is reset to 0                                                //
//                                      Then every sec you get a new response like:                                //
//                                      -3   7133                                                                  //
//                                      -2   8134                                                                  //
//                                      -1   9135                                                                  //
//                                       0   0                                                                     //
//                                       1   1002                                                                  //
//                                       2   2002                                                                  //
//                                       3   3003                                                                  //
//                                      and so on                                                                  //
//                                                                                                                 //
//                                      The example values of my Arduino shows, that every sec the internal        //
//                                      counter - called by millis() - added not exactly 1000msec                  //
//                                                                                                                 //
//                                      Here the difference is about 2msec in the first sec                        //
//                                      After 2sec the differece show 2msec too                                    //
//                                      But it's rounded, so sometimes it shows the same difference                //
//                                                                                                                 //
//                                      My Arduino is to fast - the same like with micros()                        //
//                                      A short test shows:                                                        //
//                                      598   598638                                                               //
//                                      599   599638                                                               //
//                                 ---> 600   600640 <---                                                          //
//                                      601   601641                                                               //
//                                      602   602641                                                               //
//                                                                                                                 //
//                                      In 10min the difference was 640msec - see marking above  -->  <--          //
//                                      In 938sec the difference was about 1sec                                    //
//                                      That's the same like the test's with micros()                              //
//                                                                                                                 //
//                                      That's nothing for high precision                                          //
//                                      But it's good enogh for many experiments                                   //
//                                                                                                                 //
//                                      You can copy the values from the monitor-program into Win-Editor           //
//                                      Save the file to test.txt                                                  //
//                                      Open the file with Excel, separated by " " (blank)                         //
//                                      Then show an x-y plot                                                      //
//                                                                                                                 //
//                                      left: time in sec (GPS)   right: counts called by millis()                 //
//                                                                                                                 //
//                                      at the beginning you have a countdown to compare the time with a clock     //
//                                                                                                                 //
//                                      if you run the program for 1000sec and Arduino is perfect then             //
//                                      you get "1000   1000000"                                                   //
//                                      (in 1000sec you get 1000000msec)                                           //
//                                                                                                                 //
//                                      With my Arduino I get "1000   1001069"                                     //
//                                      (That's very bad for long-time experiments)                                //
//                                      (For short-time-use it's o.K)                                              //
//                                                                                                                 //
//-----------------------------------------------------------------------------------------------------------------//
//                                                                                                                 //
const byte interruptPin =  2;                                                                                      //
double Zeitpunkt,Ausgabe,millisPrevious,millisDelta,millisNow;                                                     //
//-----------------------------------------------------------------------                                          //
void setup()                                                                                                       //
 {                                                                                                                 //
  Serial.begin(115200);                                                                                            //
  pinMode(interruptPin, INPUT_PULLUP);                                                                             //
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);                                             //
  Zeitpunkt=-10;                                                                                                   //
  Ausgabe=0;                                                                                                       //
  millisPrevious = millis();                                                                                       //
 }                                                                                                                 //
//-----------------------------------------------------------------------------------------------------------------//
void loop()                                                                                                        //
 {                                                                                                                 //
  // nothing to do - Program run through the Interrupt                                                             //
 }                                                                                                                 //
//-----------------------------------------------------------------------------------------------------------------//
void blink()                                                                                                       //
 {                                                                                                                 //
  millisNow = millis();                                                                                            //
  millisDelta=millisNow-millisPrevious;                                                                            //
  millisPrevious=millisNow;                                                                                        //
  if(Zeitpunkt==0)                                                                                                 //
   {                                                                                                               //
    Ausgabe=0;                                                                                                     //
   }                                                                                                               //
  else                                                                                                             //
   {                                                                                                               //
    Ausgabe=Ausgabe+millisDelta;                                                                                   //
   }                                                                                                               //
  //messwerte=microsDelta1;                                                                                        //
  //Serial.println(messwerte, 0);                                                                                  //
  Serial.print(Zeitpunkt,0); // , 0);                                                                              //
  Serial.print("   ");                                                                                             //
  Serial.println(Ausgabe,0); // , 0);                                                                              //
  Zeitpunkt++;                                                                                                     //
 }                                                                                                                 //
//-----------------------------------------------------------------------------------------------------------------//
//////////////////////////////////////////////////////// End Progam 3 ///////////////////////////////////////////////
*/

Credits

astro-fan

astro-fan

0 projects • 0 followers

Comments