使用 libgps 库获取gps数据

一、安装启动守护进程

准确来说 libgps(man libgps)是一个与 GPS 守护进程进行通信的 C 库。包含打开、收发、解析数据包等接口,我们只需要使用libgps提供的接口就可拿到GPS数据。但是这个库的接口的使用,依赖 GPS 守护进程的运行。而这个守护进程才是真正基于上述协议与 GPS 接收器进行通信的。
1、选配上gpsd编译进文件系统(make menuconfig)
在这里插入图片描述
2、在开发板启动这个守护进程

/usr/sbin/gpsd -N -n -S 2947 /dev/ttyUSB0

3、如果说你要获取gps数据,目前我的gps模块被开发板识别为/dev/ttyUSB0,你可以直接通过cat 查看得到的gps数据,前提是需要关掉gpsd服务,同时gps天线能够在室外:
使用 libgps 库获取gps数据_第1张图片
4、GPS数据分析(图片来自供应商提供的手册)
使用 libgps 库获取gps数据_第2张图片

$GNGGA,052656.000,3107.52352,N,12121.56231,E,1,15,0.8,106.2,M,10.4,M,,0000*48
全球定位信息,接收机的时间、位置和定位相关数据。
$GNGLL,3107.52352,N,12121.56231,E,052656.000,A,A*41
地理定位信息,位置、时间和固定状态。
$GNGSA,A,3,10,18,23,24,25,31,32,193,,,,,1.4,0.8,1.2*12
当前卫星信息,用于表示用于定位的卫星的ID。当使用GPS卫星定位时,输出$GNGSA语句,系统ID为1。使用GLONASS卫星定位时,输出SGNGSA语句,系统ID为2。使用北斗卫星进行定位时,输出SGNGSA语句,系统ID为4。
$BDGSV,5,3,17,201,46,141,,214,42,322,34,224,40,204,29,204,34,123,*64
卫星仰角、方位角和CNR信息,SGPGSV用于GPS卫星,SGLGSV用于GLONASS卫星,SGAGSV用于GALILEO卫星,$GBGSV用于北斗卫星
$GNRMC,052656.000,A,3107.52352,N,12121.56231,E,000.0,065.6,081121,,,A*78
推荐定位信息,时间,日期,位置,航向,和速度
$GNVTG,065.6,T,,M,000.0,N,000.0,K,A*16
地面速度信息,相对于地面的航向和速度
$GNZDA,052656.000,08,11,2021,00,00*43
UTC时间,年月日和时区

二、启动客户端

代码如下:因为本人需要将gps数据转换为JSON格式数据上传给前端工程师,从而在web端显示设备位置,所以得到数据后进行了处理

#include                                                                                                                                                                                           
#include "mgps.h"
#include "gps.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MESH_GPSD_LOCALTION_JSON "/www/meshgps.json"
#define LOCATION_SERVICE_EXIT "/bin/rm -rf /var/run/meshgps.pid"
#define GPSD_DATE_LOCALTION_JSON "/www/meshgps.json"
#define GPSD_SERVICE_RESTART "/etc/init.d/gpsd restart"

FILE *fp;
char coor_buf[128] = {0};
char type_buf[32] = {0};
pthread_mutex_t gps_mutex = PTHREAD_MUTEX_INITIALIZER;

int mesh_query_console_baudrate(const char *device)                                                                                                                                                         
{
    int fd = 0;
    speed_t baudrate = B115200;
    struct termios tio;
    if ((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
    {
        printf("%s open serial console failed\n", __func__);
        return -1;
    }
    if (tcgetattr(fd, &tio) != 0)
    {
        printf("%s get console attr error\n", __func__);
        close(fd);
        return -1;
    }
    syslog(LOG_INFO, "console input buadrate  %d output buadrate  %d\n",cfgetispeed(&tio), cfgetospeed(&tio));
    if (cfgetispeed(&tio) == cfgetospeed(&tio) && baudrate == cfgetispeed(&tio))
    {
        printf("%s correct console baudrates\n", __func__);
        close(fd);
    }
    else
    {
        printf("%s console buadrate input %d output %d  src %d is unavailable\n",
                __func__, cfgetispeed(&tio), cfgetospeed(&tio), baudrate);
        cfsetispeed(&tio, baudrate);
        cfsetospeed(&tio, baudrate);

        int ret = tcsetattr(fd, TCSANOW, &tio);
        printf("%s after set console buadrate input %d output %d ret %d\n",
                __func__, cfgetispeed(&tio), cfgetospeed(&tio), ret);
        close(fd);
    }
    system(GPSD_SERVICE_RESTART);
    return 0;
}
void *parse_location(struct gps_data_t *gps_data)
{
    int i = 0;
    while(1)
    {
        pthread_mutex_lock(&gps_mutex);

        memset(coor_buf, 0, sizeof(coor_buf));
        memset(type_buf, 0, sizeof(type_buf));
        /*if over 6 minutes no gps data,then exit and report*/
        if (i > 120)
        {
            printf( "receive GPS data timeout\n");
            goto ERR_RET;
        }
       /* non block wait for 2 seconds to receive data */
        if (gps_waiting(gps_data, 2 * 1000 * 1000))
        {
            /* read data */
            if ((gps_read(gps_data, NULL, 0)) == -1)
            {
                printf("error occured reading gps data\n");
                goto ERR_RET;
            }
            /* Display data from the GPS receiver. */
            if ((gps_data->status == STATUS_NO_FIX))
            {
                printf("gps status %d mode %d latitude %f longitude %f\n", gps_data->status, gps_data->fix.mode, gps_data->fix.latitude, gps_data->fix.longitude);
            }
            if ((gps_data->status != STATUS_NO_FIX) && (gps_data->fix.mode == MODE_2D ||
                        gps_data->fix.mode == MODE_3D) &&
                    !isnan(gps_data->fix.latitude) && !isnan(gps_data->fix.longitude))
            {
                printf("latitude: %f, longitude: %f, timestamp:%ld\n",
                        gps_data->fix.latitude, gps_data->fix.longitude, gps_data->fix.time.tv_sec);
                strcat(coor_buf, "{\"time\":\"");                                                                                                                                                           
                sprintf(type_buf, "%ld", gps_data->fix.time.tv_sec);
                strcat(coor_buf, type_buf);
                strcat(coor_buf, "\",\"latitude\":\"");
                sprintf(type_buf, "%lf", gps_data->fix.latitude);
                strcat(coor_buf, type_buf);
                strcat(coor_buf, "\"}");

                if (strlen(coor_buf) != 0)
                {
                    printf("coor_buf = %s\n",coor_buf);
                    fp = fopen(GPSD_DATE_LOCALTION_JSON, "w+");
                    fputs(coor_buf, fp);
                    fclose(fp);
                }

                goto ERR_RET;
            }
            else
            {
                i++;
            }

      pthread_mutex_unlock(&gps_mutex);
      sleep(3);
    }
  }
ERR_RET:
  pthread_mutex_unlock(&gps_mutex);
  gps_stream(gps_data, WATCH_DISABLE, NULL);
  gps_close(gps_data);
  system(LOCATION_SERVICE_EXIT);
  return NULL;
}
int main()
{
    struct gps_data_t gps_data;
    pthread_t thread;

    if (mesh_query_console_baudrate("/dev/ttyUSB0"))
    {
        printf("gpsd error\n");
        goto ERR_EXIT;
    }

    if ((gps_open("localhost", "2947", &gps_data)) == -1)
    {
         printf("gps open device fail\n");
         goto ERR_EXIT;
    }

    if (-1 == gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL))
    {
         printf("%s gps stream error\n", __func__);
         gps_close(&gps_data);
         goto ERR_EXIT;
    }

    pthread_create(&thread, NULL, (void *)parse_location,(struct gps_data_t *)&gps_data);

    pthread_join(thread, NULL);
    return 0;

ERR_EXIT:
    system(LOCATION_SERVICE_EXIT);
    return -1;

三、交叉编译运行程序

因为我目前只需要时间和经纬度这三个数据,就读取了这三类数据:
使用 libgps 库获取gps数据_第3张图片
使用 libgps 库获取gps数据_第4张图片

你可能感兴趣的:(ARM,linux,arm,c语言,物联网)