心之永恒 发表于 2012-11-16 10:16:54

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

最近在做GPS模块。
但是出现一些问题,由于GPS每秒钟输出一次,每次输出的数据量都好大,我只要其中的$GPRMC和$GPGGA。
如果单独只有GPS模块的话还好办,单片机可以全力处理这个模块。但是添加其他模块之后就会出现输出数据丢失情况。
例如正常情况是:$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

有时候数据丢失:

$GPGLL$GPRMC,112026.00,A,3157.64479,N,11850.55005,E,0.015,,240712,,,A*70

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

davidce 发表于 2012-11-16 12:42:33

把就收到的数据存入缓存中,一条信息接收完再做其它的运算

心之永恒 发表于 2012-11-16 12:57:04

davidce 发表于 2012-11-16 12:42 static/image/common/back.gif
把就收到的数据存入缓存中,一条信息接收完再做其它的运算

目前就是一条接收一次 有一定概率会出现错乱void read_GPS()
{
   char c;
    sum =0;
    if(GPS.available())
    {
      while(1)
      {
          c = GPS.read();
          if(c == -1) continue;
          if(c == '\n') continue;
          if((sum==BUFFSIZ-1)||(c=='\r'))
          {
            GPS_buffer=0;
            return;
          }
          GPS_buffer=c;
      }
    }
}上面是接受一条一条的,接收完一条就判断文件头是不是$GPRMC
但有时候GPRMC会出现在其他语句中间 这样我GPS数据就像停掉了一样
例如这样:$GPGLL$GPRMC,112026.00,A,3157.64479,N,11850.55005,E,0.015,,240712,,,A*70

davidce 发表于 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=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==comandoGPR)

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==',')

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

238.                indices=i;

239.                cont++;

240.            }

241.            if (linea=='*')

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

243.                indices=i;

244.                cont++;

245.            }

246.            }

247.            String dataString;

248.            int outindex;

249.            outindex=1;

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

251.            {

252.            if(linea=='A')

253.            {

254.                isGPSOK = true;

255.            }

256.            }

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

258.            dataString="";

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

260.            {

261.            dataString = dataString + linea;

262.            }

263.            datestr=dataString;

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

265.            dataString="";

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

267.            {

268.            dataString = dataString + linea;

269.            }

270.            timestr=dataString;

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

272.            dataString="";

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

274.            {

275.            dataString = dataString + linea;

276.            }

277.            latstr=dataString;

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

279.            dataString="";

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

281.            {

282.            dataString = dataString + linea;

283.            }

284.            lonstr=dataString;

285.          }

286.          // Reset the buffer

287.          conta=0;                  

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

289.          {   

290.            linea=' ';            

291.          }

292.      }

293.      }

294.    }

另外 ,波特率是不是太高了

davidce 发表于 2012-11-16 13:06:28

46.//GPS

47.int byteGPS = -1;

48.char linea = "";

49.char comandoGPR = "$GPRMC";

50.int cont=0;

51.int bien=0;

52.int conta=0;

53.int indices;

ttyp 发表于 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 static/image/common/back.gif
//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 static/image/common/back.gif
$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53


这个可以读逗号,判断完$之后的数据,判断第几个逗号是什么。把逗号之间的字符放到数组,再进行处理。   if((GPS_buffer=='G')&&(GPS_buffer=='G')&&(GPS_buffer=='A'))
    {
//   Serial.println(GPS_buffer); //测试输出数据是否正常
      for(i=0; i<=BUFFSIZ; i++)
      {
         if(GPS_buffer==',')
          {
            j=j+1;
          }
            if(j==1)
            {
             GPS_UTC=GPS_buffer;//读取UTC时间
            }
          if(j==2)
         {
            GPS_LAT=GPS_buffer;//读取纬度
         }
         if(j==3)
         {
            GPS_NS=GPS_buffer; //读取南北半球
         }
          if(j==4)
         {
            GPS_LON=GPS_buffer; //读取经度
         }
          if(j==5)
         {
            GPS_WE=GPS_buffer; //读取东西半球
         }
         
      }
    }写的不是很好,C语言基础薄弱了点{:3_60:}

四九零二 发表于 2012-11-16 16:06:31

多谢了 我是有点不清楚串口读到的数据是什么意思~
以后跟你学了~ 呵呵~

laoliu1982 发表于 2012-11-17 10:43:52

心之永恒 发表于 2012-11-16 14:22 static/image/common/back.gif
这个可以读逗号,判断完$之后的数据,判断第几个逗号是什么。把逗号之间的字符放到数组,再进行处理。写 ...

别纠结了,淘宝上买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模块,想要哪条数据不要哪条数据就串口设置一下完毕了。
页: [1] 2
查看完整版本: arduino应该如何处理GPS模块输出的大量数据呢?