سلام من وقتی اطلاعات 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", °rees, &minutes);
} else {
// Longitude: DDDMM.MMMM
sscanf(coord, "%3f%f", °rees, &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__
کدتون به نظر اوکی میاد، چند تا مسئله به ذهنم میرسه:
- ممکنه اطرافتون جمینگ GPS باشه. برای اطمینان میتونید دو تا کار بکنید، اول با یک گوشی اندرویدی تست کنید و ببینید موقعیت چطوریه (ترجیحاً با یک اپ که فقط طول و عرض رو میده تست کنید). دومین کاری که میتونید بکنید اینه که برای چند ساعت خروجی ماژول رو لاگ بگیرید و ببینید موقعیتی که میده آیا تغییرات هم داره یا نه (اگه جمینگ باشه باید نقاط مرتب تغییر بکنه).
- موقعیت رو از
GPGGA
بگیرید و ببینید اون چطوریه (وقتی3D
شد وGNSS Fix
) داد.
1 پسندیده