极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 38477|回复: 17

arduino应该如何处理GPS模块输出的大量数据呢?

[复制链接]
发表于 2012-11-16 10:16:54 | 显示全部楼层 |阅读模式
最近在做GPS模块。
但是出现一些问题,由于GPS每秒钟输出一次,每次输出的数据量都好大,我只要其中的$GPRMC和$GPGGA。
如果单独只有GPS模块的话还好办,单片机可以全力处理这个模块。但是添加其他模块之后就会出现输出数据丢失情况。
例如正常情况是:[pre lang="GPS" line="1"]$GPRMC,112026.00,A,3157.64479,N,11850.55005,E,0.015,,240712,,,A*70
$GPVTG,,T,,M,0.015,N,0.028,K,A*2D
$GPGGA,112026.00,3157.64479,N,11850.55005,E,1,05,4.03,33.3,M,2.6,M,,*5F
$GPGSV,2,2,06,20,44,057,41,27,08,288,34*72
$GPGLL,3157.64643,N,11850.54927,E,112047.00,A,A*6B
$GPRMC,112048.00,A,3157.64651,N,11850.54924,E,0.017,,240712,,,A*79
$GPVTG,,T,,M,0.017,N,0.032,K,A*24
$GPGGA,112048.00,3157.64651,N,11850.54924,E,1,05,4.08,33.5,M,2.6,M,,*59
$GPGSA,A,3,17,20,04,27,09,,,,,,,,4.77,4.08,2.47*07
$GPGSV,2,1,06,04,48,271,41,09,06,298,34,11,,,23,17,64,002,40*4D
$GPGSV,2,2,06,20,44,057,41,27,08,288,34*72
$GPGLL,3157.64651,N,11850.54924,E,112048.00,A,A*64[/code]

有时候数据丢失:
[pre lang="GPS" line="1"]
$GPGLL$GPRMC,112026.00,A,3157.64479,N,11850.55005,E,0.015,,240712,,,A*70[/code]

请问谁有什么解决的方法?
回复

使用道具 举报

发表于 2012-11-16 12:42:33 | 显示全部楼层
把就收到的数据存入缓存中,一条信息接收完再做其它的运算
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-16 12:57:04 | 显示全部楼层
davidce 发表于 2012-11-16 12:42
把就收到的数据存入缓存中,一条信息接收完再做其它的运算

目前就是一条接收一次 有一定概率会出现错乱
  1. void read_GPS()
  2. {
  3.    char c;
  4.     sum =0;
  5.     if(GPS.available())
  6.     {
  7.       while(1)
  8.       {
  9.           c = GPS.read();
  10.           if(c == -1) continue;
  11.           if(c == '\n') continue;
  12.           if((sum==BUFFSIZ-1)||(c=='\r'))
  13.           {
  14.               GPS_buffer[sum]=0;
  15.               return;
  16.           }
  17.           GPS_buffer[sum++]=c;
  18.       }
  19.     }
  20. }
复制代码
上面是接受一条一条的,接收完一条就判断文件头是不是$GPRMC
但有时候GPRMC会出现在其他语句中间 这样我GPS数据就像停掉了一样
例如这样:$GPGLL$GPRMC,112026.00,A,3157.64479,N,11850.55005,E,0.015,,240712,,,A*70
回复 支持 反对

使用道具 举报

发表于 2012-11-16 13:04:58 | 显示全部楼层
//GPS

204.    String datestr = "";    //date UTC (ddmmyy)

205.    String timestr = "";    //time UTC (hhmmss.sss)

206.    String latstr = "";    //Latitude (ddmm.mmmm)

207.    String lonstr = "";    //Longitude (dddmm.mmmm)

208.    boolean isGPSOK = false;

209.    bien=0;

210.    while(bien!=6)

211.    {

212.      byteGPS=Serial.read();

213.      if(byteGPS == -1)

214.      {

215.        delay(100);

216.      }

217.      else

218.      {

219.        linea[conta]=byteGPS;        // If there is serial port data, it is put in the buffer

220.        conta++;

221.        if(byteGPS==13)

222.        {

223.          cont=0;

224.          bien=0;

225.          for (int i=1;i<7;i++)

226.          {     // Verifies if the received command starts with $GPRMC

227.            if (linea[i]==comandoGPR[i-1])

228.            {

229.              bien++;

230.            }

231.          }

232.          if(bien==6)  // If yes, continue and process the data

233.          {

234.            for (int i=0;i<300;i++)

235.            {

236.              if (linea[i]==',')

237.              {    // check for the position of the  "," separator

238.                indices[cont]=i;

239.                cont++;

240.              }

241.              if (linea[i]=='*')

242.              {    // ... and the "*"

243.                indices[12]=i;

244.                cont++;

245.              }

246.            }

247.            String dataString;

248.            int outindex;

249.            outindex=1;

250.            for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)

251.            {

252.              if(linea[j+1]=='A')

253.              {

254.                isGPSOK = true;

255.              }

256.            }

257.            outindex=8;  //Date UTC (ddmmyy)

258.            dataString="";

259.            for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)

260.            {

261.              dataString = dataString + linea[j+1];

262.            }

263.            datestr=dataString;

264.            outindex=0;  //time UTC (hhmmss.sss)

265.            dataString="";

266.            for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)

267.            {

268.              dataString = dataString + linea[j+1];

269.            }

270.            timestr=dataString;

271.            outindex=2;  //Latitude (ddmm.mmmm)

272.            dataString="";

273.            for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)

274.            {

275.              dataString = dataString + linea[j+1];

276.            }

277.            latstr=dataString;

278.            outindex=4;  //Longitude (dddmm.mmmm)

279.            dataString="";

280.            for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)

281.            {

282.              dataString = dataString + linea[j+1];

283.            }

284.            lonstr=dataString;

285.          }

286.          // Reset the buffer

287.          conta=0;                    

288.          for (int i=0;i<300;i++)

289.          {   

290.            linea[i]=' ';            

291.          }

292.        }

293.      }

294.    }

另外 ,波特率是不是太高了
回复 支持 反对

使用道具 举报

发表于 2012-11-16 13:06:28 | 显示全部楼层
46.//GPS

47.int byteGPS = -1;

48.char linea[300] = "";

49.char comandoGPR[7] = "$GPRMC";

50.int cont=0;

51.int bien=0;

52.int conta=0;

53.int indices[13];

回复 支持 反对

使用道具 举报

发表于 2012-11-16 13:31:37 | 显示全部楼层
自己找规律优化了,如先找到$,然后再比较后4位,没用的数据就丢掉,buffer里的数据混乱是难以避免的,和硬件有关吧
回复 支持 反对

使用道具 举报

发表于 2012-11-16 13:35:02 | 显示全部楼层
边接收,边处理,来得及~
回复 支持 反对

使用道具 举报

发表于 2012-11-16 13:36:16 | 显示全部楼层
C:\Users\allen4902\Desktop 我的是这样的怎么读啊
回复 支持 反对

使用道具 举报

发表于 2012-11-16 13:37:17 | 显示全部楼层
$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64

回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-16 14:21:09 | 显示全部楼层
davidce 发表于 2012-11-16 13:04
//GPS

204.    String datestr = "";    //date UTC (ddmmyy)

波特率默认9600 尝试过其他波特率 但是次日就自动恢复默认波特率了 谢谢你的代码哦 我研究一下{:3_59:}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-16 14:22:46 | 显示全部楼层
本帖最后由 心之永恒 于 2012-11-16 14:25 编辑
四九零二 发表于 2012-11-16 13:37
$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53


这个可以读逗号,判断完$之后的数据,判断第几个逗号是什么。把逗号之间的字符放到数组,再进行处理。
  1.      if((GPS_buffer[3]=='G')&&(GPS_buffer[4]=='G')&&(GPS_buffer[5]=='A'))
  2.     {
  3. //     Serial.println(GPS_buffer); //测试输出数据是否正常
  4.       for(i=0; i<=BUFFSIZ; i++)
  5.         {
  6.          if(GPS_buffer[i]==',')
  7.           {  
  8.             j=j+1;
  9.           }
  10.               if(j==1)
  11.             {
  12.              GPS_UTC[utc++]=GPS_buffer[i];  //读取UTC时间
  13.             }
  14.           if(j==2)
  15.            {
  16.             GPS_LAT[lat++]=GPS_buffer[i];//读取纬度
  17.            }
  18.            if(j==3)
  19.            {
  20.             GPS_NS[ns++]=GPS_buffer[i]; //读取南北半球
  21.            }
  22.           if(j==4)
  23.            {
  24.             GPS_LON[lon++]=GPS_buffer[i]; //读取经度
  25.            }
  26.           if(j==5)
  27.            {
  28.             GPS_WE[we++]=GPS_buffer[i]; //读取东西半球
  29.            }
  30.            
  31.         }
  32.     }
复制代码
写的不是很好,C语言基础薄弱了点{:3_60:}
回复 支持 反对

使用道具 举报

发表于 2012-11-16 16:06:31 | 显示全部楼层
多谢了 我是有点不清楚串口读到的数据是什么意思~
以后跟你学了~ 呵呵~
回复 支持 反对

使用道具 举报

发表于 2012-11-17 10:43:52 | 显示全部楼层
心之永恒 发表于 2012-11-16 14:22
这个可以读逗号,判断完$之后的数据,判断第几个逗号是什么。把逗号之间的字符放到数组,再进行处理。写 ...

别纠结了,淘宝上买GPS的让他帮你烧好了固件,就要一种格式的输出 推荐用GPRMC(据说导航设备都用它)
$GPRMC,075300.000,A,3954.5639,N,11610.7730,E,0.00,335.56,140512,,,A*6C
忘了能不能定输出频率了,如果能定,可以把这个输出频率拉长点,比如两秒。这样就没问题了吧。


回复 支持 反对

使用道具 举报

发表于 2013-4-2 17:25:23 | 显示全部楼层
楼主您后,我用的GPS Shield With SD Card和Arduino UNO板,但是我读到的数据是这样的:
$GPGGA,085256.469,,,,,0,00,,,M,0.0,M,,0000*51
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,085256.469,V,,,,,,,020413,,,N*4E
。。。
不知道为什么是无效定位,有什么建议么?
回复 支持 反对

使用道具 举报

发表于 2013-4-3 13:53:56 | 显示全部楼层
嘿嘿,不要纠结了,自从用了ublox的gps模块,想要哪条数据不要哪条数据就串口设置一下完毕了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-15 12:16 , Processed in 0.104265 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表