Wrong time and coordinate return from A9G Module

i am a newbie with A9G GPS,GPRS module, i use A9G to do a project that track my realtime movement (running), but i have some problems:

  • the coordinates value is returned from module is wrong, first i am at point A and the module still on, after that i turn off the module and move to point B about 60km to the west, at point B, i turn on the A9G and it return the coordinate of point A,
  • the date value is returned from the module is wrong, when i reset the module, the date start at day 6, month 1, year 80 and this is the result that is decoded from GNGGA raw value, ít take too much time to set correct date (2~30min, correct date come frome correct GNGGA value). what happen with A9G module and how can i completely solve this problem,thank you for reading.

i try to check more by print the raw GNGGA and handly decode but the GGA value exacly of point A, then i use demo code but the same problems.

here is full code in demo_gps (code in demo folder, gps):

#include <string.h>
#include <stdio.h>
#include <api_os.h>
#include <api_gps.h>
#include <api_event.h>
#include <api_hal_uart.h>
#include <api_debug.h>
#include "buffer.h"
#include "gps_parse.h"
#include "math.h"
#include "gps.h"

#define MAIN_TASK_STACK_SIZE    (2048 * 2)
#define MAIN_TASK_PRIORITY      0
#define MAIN_TASK_NAME          "GPS Test Task"

static HANDLE gpsTaskHandle = NULL;
bool flag = false;


// const uint8_t nmea[]="$GNGGA,000021.263,2228.7216,N,11345.5625,E,0,0,,153.3,M,-3.3,M,,*4E\r\n$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r\n$BDGSA,A,1,,,,,,,,,,,,,,,*0F\r\n$GPGSV,1,1,00*79\r\n$BDGSV,1,1,00*68\r\n$GNRMC,000021.263,V,2228.7216,N,11345.5625,E,0.000,0.00,060180,,,N*5D\r\n$GNVTG,0.00,T,,M,0.000,N,0.000,K,N*2C\r\n";

void EventDispatch(API_Event_t* pEvent)
{
    switch(pEvent->id)
    {
        case API_EVENT_ID_NETWORK_REGISTERED_HOME:
        case API_EVENT_ID_NETWORK_REGISTERED_ROAMING:
            Trace(1,"gprs register complete");
            flag = true;
            break;
        case API_EVENT_ID_GPS_UART_RECEIVED:
            // Trace(1,"received GPS data,length:%d, data:%s,flag:%d",pEvent->param1,pEvent->pParam1,flag);
            GPS_Update(pEvent->pParam1,pEvent->param1);
            break;
        case API_EVENT_ID_UART_RECEIVED:
            if(pEvent->param1 == UART1)
            {
                uint8_t data[pEvent->param2+1];
                data[pEvent->param2] = 0;
                memcpy(data,pEvent->pParam1,pEvent->param2);
                Trace(1,"uart received data,length:%d,data:%s",pEvent->param2,data);
                if(strcmp(data,"close") == 0)
                {
                    Trace(1,"close gps");
                    GPS_Close();
                }
                else if(strcmp(data,"open") == 0)
                {
                    Trace(1,"open gps");
                    GPS_Open(NULL);
                }
            }
            break;
        default:
            break;
    }
}

void gps_testTask(void *pData)
{
    GPS_Info_t* gpsInfo = Gps_GetInfo();
    uint8_t buffer[150];
    char buff1[15],buff2[15];

    //wait for gprs register complete
    //The process of GPRS registration network may cause the power supply voltage of GPS to drop,
    //which resulting in GPS restart.
    while(!flag)
    {
        Trace(1,"wait for gprs regiter complete");
        OS_Sleep(2000);
    }

    //open GPS hardware(UART2 open either)
    GPS_Init();
    GPS_Open(NULL);

    //wait for gps start up, or gps will not response command
    while(gpsInfo->rmc.latitude.value == 0)
        OS_Sleep(1000);
    

    // set gps nmea output interval
    for(uint8_t i = 0;i<3;++i)
    {
        bool ret = GPS_SetOutputInterval(10000);
        Trace(1,"set gps ret:%d",ret);
        if(ret)
            break;
        OS_Sleep(1000);
    }

    // if(!GPS_ClearInfoInFlash())
    //     Trace(1,"erase gps fail");
    
    // if(!GPS_SetQzssOutput(false))
    //     Trace(1,"enable qzss nmea output fail");

    // if(!GPS_SetSearchMode(true,false,true,false))
    //     Trace(1,"set search mode fail");

    // if(!GPS_SetSBASEnable(true))
    //     Trace(1,"enable sbas fail");
    
    if(!GPS_GetVersion(buffer,150))
        Trace(1,"get gps firmware version fail");
    else
        Trace(1,"gps firmware version:%s",buffer);

    // if(!GPS_SetFixMode(GPS_FIX_MODE_LOW_SPEED))
        // Trace(1,"set fix mode fail");

    if(!GPS_SetOutputInterval(1000))
        Trace(1,"set nmea output interval fail");
    
    Trace(1,"init ok");

    while(1)
    {
        //show fix info
        uint8_t isFixed = gpsInfo->gsa[0].fix_type > gpsInfo->gsa[1].fix_type ?gpsInfo->gsa[0].fix_type:gpsInfo->gsa[1].fix_type;
        char* isFixedStr;            
        if(isFixed == 2)
            isFixedStr = "2D fix";
        else if(isFixed == 3)
        {
            if(gpsInfo->gga.fix_quality == 1)
                isFixedStr = "3D fix";
            else if(gpsInfo->gga.fix_quality == 2)
                isFixedStr = "3D/DGPS fix";
        }
        else
            isFixedStr = "no fix";

        //convert unit ddmm.mmmm to degree(°) 
        
        int temp = (int)(gpsInfo->rmc.latitude.value/gpsInfo->rmc.latitude.scale/100);
        double latitude = temp+(double)(gpsInfo->rmc.latitude.value - temp*gpsInfo->rmc.latitude.scale*100)/gpsInfo->rmc.latitude.scale/60.0;
        temp = (int)(gpsInfo->rmc.longitude.value/gpsInfo->rmc.longitude.scale/100);
        double longitude = temp+(double)(gpsInfo->rmc.longitude.value - temp*gpsInfo->rmc.longitude.scale*100)/gpsInfo->rmc.longitude.scale/60.0;

        gcvt(latitude,6,buff1);
        gcvt(longitude,6,buff2);
        
        //you can copy ` buff1,buff2 `(latitude,longitude) to http://www.gpsspg.com/maps.htm check location on map

        snprintf(buffer,sizeof(buffer),"GPS fix mode:%d, BDS fix mode:%d, fix quality:%d, is fixed:%s, coordinate:WGS84, Latitude:%s, Longitude:%s, unit:degree",gpsInfo->gsa[0].fix_type, gpsInfo->gsa[1].fix_type,
                                                            gpsInfo->gga.fix_quality,isFixedStr, buff1,buff2);
        //show in tracer
        Trace(2,buffer);
        //send to UART1
        UART_Write(UART1,buffer,strlen(buffer));
        UART_Write(UART1,"\r\n\r\n",4);

        OS_Sleep(5000);
    }
}


void gps_MainTask(void *pData)
{
    API_Event_t* event=NULL;
    

    //open UART1 to print NMEA infomation
    UART_Config_t config = {
        .baudRate = UART_BAUD_RATE_115200,
        .dataBits = UART_DATA_BITS_8,
        .stopBits = UART_STOP_BITS_1,
        .parity   = UART_PARITY_NONE,
        .rxCallback = NULL,
        .useEvent   = true
    };
    UART_Init(UART1,config);

    //Create UART1 send task and location print task
    OS_CreateTask(gps_testTask,
            NULL, NULL, MAIN_TASK_STACK_SIZE, MAIN_TASK_PRIORITY, 0, 0, MAIN_TASK_NAME);

    //Wait event
    while(1)
    {
        if(OS_WaitEvent(gpsTaskHandle, (void**)&event, OS_TIME_OUT_WAIT_FOREVER))
        {
            EventDispatch(event);
            OS_Free(event->pParam1);
            OS_Free(event->pParam2);
            OS_Free(event);
        }
    }
}


void gps_Main(void)
{
    gpsTaskHandle = OS_CreateTask(gps_MainTask,
        NULL, NULL, MAIN_TASK_STACK_SIZE, MAIN_TASK_PRIORITY, 0, 0, MAIN_TASK_NAME);
    OS_SetUserMainHandle(&gpsTaskHandle);
}```

Hi, @trong_quan
Welcome to the forum.

I am no GPS expert, but why are you turning the unit off each time.
To get good reliable and accurate readings you need to leave the GPS turned on, that way it will also keep time.

Tom.. :grinning: :+1: :coffee: :australia:

Your topic has been moved to a more suitable location on the forum. Please do not post in "Uncategorized"; see Uncategorized - Arduino Forum

how do you know i turning the unit off each time, this is the demo code of GPRS_C_SDK, i have read it but i don't know where i turning the unit off

Hi, @trong_quan

Tom... :grinning: :+1: :coffee: :australia:

1 Like

aha, thank you for your carefully reading, but my mind is when i turn off the module ( power off) and move to point B about 60km then turn on the module, it will update location like a phone( you clearly power off the phone and move then turn on, the phone auto update location), i want the module can automatically update the location when i turn on
updated: i have erase the flash of the module, it seem the module return the value from the flash and the flash isn't updated NMEA value, so when i erase, the value return is default of A9G


how can i fix this bug, i can still send sms and call

Hi,

You do not normally turn your phone off, you actually put it to sleep, some of the phone keeps working.
If you leave your project on and travel the 60kms, does the problem still occur?

The GPS needs time to acquire the number of satellites it needs to give an accurate reading, how long are you leaving the project turned on when you get to the 60km point?

Can you please post some pictures of your project?

Thanks... Tom... :grinning: :+1: :coffee: :australia:

It will do that, but after every power cycle, it takes some time to find all the satellites and calculate a new location.

If you use a battery-backed GPS module, the restart is usually much faster.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.