اشتباه در نشان دادن لوکیشن MC60

سلام من وقتی اطلاعات RMC رو از ماژول می گیرم و بعد lat و long رو کانورتش میکنم حدود 2 کیلومتر از موقعیت واقعی فاصله داره، کسی میدونه مشکل از چیه؟

سلام،
دوست عزیز کدی که نوشتید رو هم بذارید تا دقیق‌تر بشه مشکل رو بررسی کرد.

#ifdef __CUSTOMER_CODE__

#include <stdio.h>      
#include <string.h>     

#include "ql_type.h"
#include "ql_trace.h"
#include "ql_system.h"
#include "ql_uart.h"
#include "ql_timer.h"
#include "ql_gpio.h"
#include "ql_stdlib.h"
#include "ql_error.h"
#include "ql_memory.h"

#include "ril.h"
#include "ril_util.h"
#include "ril_telephony.h"
#include "ril_system.h"
#include "ril_sms.h"
#include "ril_gps.h"  

#if (defined(__OCPU_RIL_SUPPORT__) && defined(__OCPU_RIL_SMS_SUPPORT__))

#define MAIN_UART_PORT        UART_PORT1    

#define GPS_READ_TIMER_ID     (0x102)        
#define GPS_READ_INTERVAL_MS  (300000)        // 30 seconds 

static char g_myPhoneNum[] = "+98919*******";

static u8  g_RMC_Buffer[200] = {0};

static char DBG_BUFFER[512];
#define APP_DEBUG(FORMAT, ...)  \
{                               \
    memset(DBG_BUFFER, 0, sizeof(DBG_BUFFER)); \
    sprintf(DBG_BUFFER, FORMAT, ##__VA_ARGS__); \
    Ql_UART_Write(MAIN_UART_PORT, (u8*)DBG_BUFFER, strlen(DBG_BUFFER)); \
}

float convertToDecimalDegrees(char *coord, char hemisphere) {
    float degrees = 0.0;
    float minutes = 0.0;
    float decimalDegrees = 0.0;

    if (hemisphere == 'N' || hemisphere == 'S') {
        // Latitude: DDMM.MMMM
        sscanf(coord, "%2f%f", &degrees, &minutes);
    } else {
        // Longitude: DDDMM.MMMM
        sscanf(coord, "%3f%f", &degrees, &minutes);
    }

    decimalDegrees = degrees + (minutes / 60.0);

    if (hemisphere == 'S' || hemisphere == 'W') {
        decimalDegrees *= -1;
    }

    return decimalDegrees;
}

static void callback_GPS_ReadTimer(u32 timerId, void* param)
{
    if (GPS_READ_TIMER_ID != timerId)
        return;

    memset(g_RMC_Buffer, 0, sizeof(g_RMC_Buffer));
    s32 ret = RIL_GPS_Read((u8*)"RMC", g_RMC_Buffer);
    if (RIL_AT_SUCCESS != ret)
    {
        APP_DEBUG("RIL_GPS_Read(RMC) failed, ret=%d\r\n", ret);
        return;
    }

    APP_DEBUG("RMC: %s\r\n", g_RMC_Buffer);

    char* pGNRMC = strstr((char*)g_RMC_Buffer, "$GNRMC");
    if (!pGNRMC)
    {
        pGNRMC = strstr((char*)g_RMC_Buffer, "$GPRMC");
        if (!pGNRMC)
        {
            APP_DEBUG("No GNRMC or GPRMC found in RMC buffer.\r\n");
            return;
        }
    }

    #define MAX_FIELDS  12
    char* fields[MAX_FIELDS];
    memset(fields, 0, sizeof(fields));

    s32 fieldCount = 0;
    char* p = pGNRMC;
    fields[fieldCount++] = p;

    while (fieldCount < MAX_FIELDS)
    {
        char* commaPos = strchr(p, ',');
        if (!commaPos) break;
        *commaPos = '\0';         
        p = commaPos + 1;         
        fields[fieldCount++] = p;
    }

    if (fieldCount < 7)
    {
        APP_DEBUG("Not enough fields to parse lat/lon.\r\n");
        return;
    }

    if (fields[2] && (fields[2][0] == 'A')) 
    {
        // Convert latitude and longitude to decimal degrees
        float latitude = convertToDecimalDegrees((char*)fields[3], fields[4][0]);
        float longitude = convertToDecimalDegrees((char*)fields[5], fields[6][0]);

        
        char mapsLink[100] = {0};
        sprintf(mapsLink, "https://maps.google.com/?q=%.6f,%.6f", latitude, longitude);

        APP_DEBUG("Sending SMS with location...\r\n");
        {
            u32  nMsgRef = 0;
            s32  smsRet = RIL_SMS_SendSMS_Text(
                g_myPhoneNum,                        
                strlen(g_myPhoneNum),                
                LIB_SMS_CHARSET_GSM,
                (u8*)mapsLink,                       
                strlen(mapsLink),                    
                &nMsgRef
            );
            if (smsRet == RIL_AT_SUCCESS)
            {
                APP_DEBUG("SMS Sent!\r\n");
            }
            else
            {
                APP_DEBUG("SMS Send Failed, ret=%d\r\n", smsRet);
            }
        }
    }
    else
    {
        APP_DEBUG("No valid fix yet (RMC_BUFFER[2] != 'A').\r\n");
    }
}

static void Callback_MainUart(Enum_SerialPort port, Enum_UARTEventType event, bool level, void *param)
{
}

void proc_main_task(s32 taskId)
{
    ST_MSG taskMsg;

    Ql_UART_Register(MAIN_UART_PORT, Callback_MainUart, NULL);
    Ql_UART_Open(MAIN_UART_PORT, 115200, FC_NONE);
    APP_DEBUG("=== RIL_GPS + SMS Demo ===\r\n");

    Ql_Timer_Register(GPS_READ_TIMER_ID, callback_GPS_ReadTimer, NULL);

    while (1)
    {
        memset(&taskMsg, 0, sizeof(ST_MSG));
        Ql_OS_GetMessage(&taskMsg);

        switch (taskMsg.message)
        {
        case MSG_ID_RIL_READY:
            {
                APP_DEBUG("<-- RIL is ready -->\r\n");
                Ql_RIL_Initialize();

                s32 ret = RIL_GPS_Open(1);  
                if (ret != RIL_AT_SUCCESS)
                {
                    APP_DEBUG("RIL_GPS_Open(1) failed, ret=%d\r\n", ret);
                }
                else
                {
                    APP_DEBUG("GPS is powered ON\r\n");
                }

                Ql_Timer_Start(GPS_READ_TIMER_ID, GPS_READ_INTERVAL_MS, TRUE);
            }
            break;

        case MSG_ID_URC_INDICATION:
            {
                switch (taskMsg.param1)
                {
                case URC_GSM_NW_STATE_IND:
                    APP_DEBUG("<-- GSM Network Status:%d -->\r\n", taskMsg.param2);
                    break;

                case URC_SIM_CARD_STATE_IND:
                    APP_DEBUG("<-- SIM Card Status:%d -->\r\n", taskMsg.param2);
                    break;

                default:
                    break;
                }
            }
            break;

        default:
            break;
        }
    }
}

#endif // RIL & SMS SUPPORT
#endif // __CUSTOMER_CODE__

کدتون به نظر اوکی میاد، چند تا مسئله به ذهنم میرسه:

  1. ممکنه اطرافتون جمینگ GPS باشه. برای اطمینان میتونید دو تا کار بکنید، اول با یک گوشی اندرویدی تست کنید و ببینید موقعیت چطوریه (ترجیحاً با یک اپ که فقط طول و عرض رو میده تست کنید). دومین کاری که میتونید بکنید اینه که برای چند ساعت خروجی ماژول رو لاگ بگیرید و ببینید موقعیتی که میده آیا تغییرات هم داره یا نه (اگه جمینگ باشه باید نقاط مرتب تغییر بکنه).
  2. موقعیت رو از GPGGA بگیرید و ببینید اون چطوریه (وقتی 3D شد و GNSS Fix) داد.
1 پسندیده