Implementing GPS in a radiosonde design - Embedded.com

Implementing GPS in a radiosonde design

In the previous article, I have explained how often are radiosondes launched using wireless RF module AX5042?

This article covers the most exciting part of the High Altitude Weather balloon. I'll describe how to implement GPS for RadioSonde design and load GPS time into a Real Time Clock (DS3231). Moreover, I'll show how to write a code for the working of GPS.

Most of you are aware of the Global Positioning System (GPS) used in smartphones, but an interesting thing is it is often used in medical and environmental embedded systems.

More details in a moment.  

To achieve the timing signal from satellite I have selected Max7c GPS from the Ublox.

To get the accurate time stamp, RTC with ±2ppm is preferred. In this case, I have used DS3231 interface with 8051.

Block Diagram   


Source: Kumar B

Algorithm for GPS  

  1. Search for 1PPS signal.

  2. Send the GPS commands

  3. Wait for GPS to sync with the satellite.

  4. Get the data from the GPS.

Interfacing GPS with Microcontroller

To power up the GPS module, a 3.3V power supply is built.

Due to its adjustable output, this can be used in various applications.


Source: Codrey Electronics


Source: Kumar B


Source: Codrey Electronics

Embedded C code for GPS

This code explains how to got date and time from the satellite using a GPS interface with a microcontroller.

#include <REG52.H>                      #include <at892051.h#include <stdio.h>#define GPS_Poweron   1                   /*to enable the GPS */#define GPS_Receive     P3_0             /*to receive GPS data*/         #define GPS_Transmit    P3_1           /*to transmit data*/                #define GPS_Poweroff 0                     /*to disable GPS */#define gps_enable    P3_4                 /*to enable GPS */#define ONE_PPS P1_2                   /*input pin for 1PPS */gps_enable=0;                                    /*Configured as output */ char initial_sync=1;                            /*to sync for first time */volatile int gps_interrupt_flag;             /*flag for detecting the rising input*/GPS_Receive=1;                              /*Configured as input*/GPS_Transmit=0;                           /*Configured as output*/char gps_timer_flag, rtc_flag_change;void RTC_Configuration ( );void gps_interrupt_1PPS ( );void Gps_Init( );void GPS_Write (const unsigned char *str);   void GPS_Write_SendByte (unsigned char data);void SYNC_GPS( );void Baudrate_9600 ( );void Baudrate_4800 ( );void Convert_Int_To_String(u32 intvalue, u8 *inttoascii );u8 Get_leapsecond ();u8 GetDataFromGPS( );

 Here are the UBLOX GPS Commands for Initializing the MAX7C module. 

/*max7c UBLOX commands*/#define GSVON                             "$PUBX, 40,GSV,0,1,0,0,0,0*58"#define GSVOFF                           "$PUBX,40,GSV,0,0,0,0,0,0*59"#define GGAON                           "$PUBX,40,GGA,0,1,0,0,0,0*5b"#define GGAOFF                          "$PUBX,40,GGA,0,0,0,0,0,0*5a"#define GLLON                             "$PUBX,40,GLL,0,1,0,0,0,0*5d"#define GLLOFF                            "$PUBX,40,GLL,0,0,0,0,0,0*5c"       #define RMCON                            "$PUBX,40,RMC,0,1,0,0,0,0*46"     #define RMCOFF                           "$PUBX,40,RMC,0,0,0,0,0,0*47"#define ZDAON                              "$PUBX,40,ZDA,0,1,0,0,0,0*45"     #define ZDAOFF                             "$PUBX,40,ZDA,0,0,0,0,0,0*44"#define GSAON                               "$PUBX,40,GSA,0,1,0,0,0,0*4f"#define GSAOFF                              "$PUBX,40,GSA,0,0,0,0,0,0*4e"#define VTGON                                "$PUBX,40,VTG,0,1,0,0,0,0*5f"#define VTGOFF                               "$PUBX,40,VTG,0,0,0,0,0,0*5e"#define LEAP_SECOND_COMMAND                    "$PUBX,04*37"#define BAUD_4800                          "$PUBX, 41, 1, 0007, 0003, 4800,0*13"  #define BAUD_9600                          "$PUBX,41,1,0007,0003,9600,0*10"  void ex1_isr (void) interrupt 1{     P3_3 = 1;/*User code............*/}/*The application code starts from here*/void main( ){gps_proper = 0;            //Valid GPSGps_Catch = 0;GPS_insert = 0;Gps_hour=0;Gps_min=0;Gps_sec=0;initial_sync=1;Baudrate_4800 ( );                                      external_RTC_init ( );RTC_Configuration ( );SYNC_GPS ( );                            Alarm_Interrupt_RTC ( );clear_alarm1 ( );}/*Function to configure RTC as falling edge*/void RTC_Configuration ( ){EA=1                 //Enable Global interruptsIE=0x84;           //Enable interrupt 1 for RTCIT1= 1;              //Set Falling edge interrupt}/*Function to get 1PPS signal from the satellite*/void gps_interrupt_1PPS ( ){ONE_PPS =1;                                    /*1PPS Configured as input*/while(1)    {      if(!ONE_PPS)          {                                 gps_interrupt_flag=1;       /*interrupt flag set when input 1PPS is high */    if(gps_interrupt_flag && ONE_PPS )      /*Detecting low to high pulse  */        {            GPS_insert = 1;                       /*Load the GPS*/                       gps_interrupt_flag=0;                 /*Clear the interrupt flag */        }      } }/*Function to initialize the GPS module*/void Gps_Init( ){   gps_enable=GPS_Poweron;             /*Enable GPS*/     getTime( );   t0 = ( RTC_hour * 3600L ) + ( RTC_min * 60 ) + RTC_sec ;}/* A function to send a string to GPS module */void GPS_Write (const unsigned char *str) {    while(1)   {       if(*str == '’) break;      GPS_Write_SendByte (*str++);        }}   /*function to send a byte */ void GPS_Write_SendByte (unsigned char data)     {         SBUF=data;         // Put byte in SBUF to send to GPS        while(TI==0);      //wait until the byte trasmission        TI=0;                  //clear TI to send next byte.                       }/*Function to sync the GPS module with the satellite*/void SYNC_GPS( ){        unsigned char temp, firsttime_gps, buff1[4];        u32 index, i, j, k;        timeout = 0;        gpsvalid = 0;       Gps_= 0;       GPS_insert= 0;        EX1 = 0;                                 //Disable External Interrupt        external_RTC_init ( );        Gps_Init( );          msdelay(100);                                Baudrate_9600 ( );                 //start the timer        for(k=0; k<2; k++)         {                    GPS_Write(GSVOFF);                 msdelay(100);          GPS_Write(GLLOFF);                 msdelay(100);          GPS_Write(VTGOFF);                   msdelay(100);          GPS_Write(ZDAOFF);                   msdelay(100);          GPS_Write(GSAOFF);                   msdelay(100);          GPS_Write (RMCOFF);                  msdelay(100);             GPS_Write(GGAOFF);                   msdelay(100);        }     for(k=0; k<2; k++)     {             GPS_Write (BAUD_4800);                      msdelay(100);         }       Baudrate_4800 ( );      for(k=0; k<2;k++)     {                  GPS_Write (GSVOFF);     msdelay(100);          GPS_Write (GLLOFF);       msdelay(100);          GPS_Write (VTGOFF);       msdelay(100);                 GPS_Write (ZDAOFF);          msdelay(100);          GPS_Write (GSAOFF);         msdelay(100);          GPS_Write (RMCOFF);         msdelay(100);             GPS_Write (GGAOFF);         msdelay(100);        }     gps_interrupt_1PPS ( );      /*enable only ex-interrupts 1PPS*/                            if(initial_sync)            {                /*getting 1PPS signal from the satellite*/            }     while (1)        {               if(GetDataFromGPS( )==5)                   {                    break;                   }           }              else                   break;                      if (GPS_status_Fix)                      break;                       }              if(initial_sync && rtc_flag_change)        {           /*RTC updated with GPS time*/            msdelay(3000);           initial_sync=0;           rtc_flag_change =0;        }      /*Condition for checking the Gps time out*/        if(timeout &&  Gps_Catch && initial_sync)        {            msdelay(3000);             firsttime_gps=0;        }         TR1=0;                              //stop the timer        Alarm_Interrupt_RTC ( );                IE=0x84;                           //enable all ex-interrupts except 1PPS        clear_alarm1 ( );}/*Function to set 9600 baud rate*/void Baudrate_9600 ( ){        /*--------------------------------------     Set serial port for 9600 baud at     11.0592 MHz.  Note that we use Timer 1     For the baud rate generator.     --------------------------------------*/     SCON = 0x50;     TMOD |= 0x20;     TH1   = 0xFD;     TR1   = 1;     RI    = 1;     TI    = 1;     PCON |= 0x80;      }/*Function to set 4800 baud rate*/void Baudrate_4800 ( ){        /*--------------------------------------     Set serial port for 4800 baud at     11.0592 MHz.  Note that we use Timer 1     for the baud rate generator.     --------------------------------------*/     SCON  = 0x50;     TMOD |= 0x20;     TH1   = 0xFA;     TR1   = 1;}void Convert_Int_To_String(u32 intvalue, u8 *inttoascii ){u8 i=0, k=0, finalstring[10], j;  unsigned char g1=0, g2=0; do       {            finalstring[i] = (intvalue%10) + 0x30;            intvalue = intvalue/10;            i++;          }while(intvalue!=0);  for (g1 = i-1; g1 >= 0; g1--)     {          inttoascii [g2] = finalstring [g1];     g2++;        if (g1 == 0)          break;     }     inttoascii [g2] = '';}u8 Get_leapsecond(){unsigned char arr_index,gpsinfo[100] ,seperate,leap=0,tempbit,len;unsigned long i,p,temptime;u16 temp;u32 in,g=0,k;GPS_insert=0;                 /*Load the GPS*/     while( 1)     {  /*Syncing GPS*/ while (GPS_insert)  {     GPS_Write(LEAP_SECOND_COMMAND);                 g=0;        do        {         TR1=0;         while(GPS_Receive);    //looking for the start bit         TR1=1;                 //Start timer           TF1= 0;             //Clear the timer flag         timerstatus=TF1;         TR1=0;                 //Stop the timer      for (arr_index = 0, temp = 0; arr_index <10; arr_index ++)              {               while(!TF1);                 TF1=0;                if(GPS_Receive))      //looking for start bit               {                 tempbit=1;               }                else                  {                    tempbit=0;                }                temp |=(tempbit<< arr_index);                }                           temp >>= 1;                  gpgga[g++]= temp & 0xff;            }  while(gpgga[g - 1] != '');               if(gpgga[arr_

1 thought on “Implementing GPS in a radiosonde design

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.