极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10677|回复: 4

请高手帮忙看看这是什么原因?

[复制链接]
发表于 2013-4-12 08:30:03 | 显示全部楼层 |阅读模式
本帖最后由 fangtaonj 于 2013-4-12 08:32 编辑

编辑大人最好不要把我这个帖子挪到提问区,那边没人气啊!总没人回帖。

两段程序都正常,但合起来就不正常了。
这个程序的目的是用串口读取GPS字符串,取出其中经度、维度、速度信息显示和串口打印出来。
最终目的是用GPS,但是到现在为止,我都是用PC通过串口给arduino板输出一个模拟的GPS信号,同时再接受板子的输出结果,接收板子的输出结果的目的是调试程序,等调试好了Serial.print()语句就会去掉的。
程序运行结果却总是不正常。。
之前把这个程序分成两段调试。分别是串口数据读入和字符串内需要的部分挑选出来并显示。
1、第一个目的是读串口,在代码中基本上就是22行到第31行的语句。单独也调通了,用串口工具软件发送"$GPRMC,091859.800,A,3204.8736,N,11853.4971,E,1.46,14.92,280313,,,A*56",第31行31.Serial.print(comdata); 能够正确显示该字符串,说明串口读取正确。
2、第二个目的是把这个字符串内需要的部分挑选出来并显示。当时用赋值语句comdata="$GPRMC,091859.800,A,3204.8736,N,11853.4971,E,1.46,14.92,280313,,,A*56";整个程序就是我附的代码中34行和之后的部分。这样做也调通了。能正常串口输出和显示屏输出。
3、然后把上面两段程序组合起来,却运行不了,不能正常执行我想要的结果,显示屏不显示,串口输出经纬度和速度也都不显示。去掉31行的//让它打印comdata,说明commdata应该得到了真确的结果,是正常的。为什么总的程序不正常?一直找不到原因。
请各位高手帮帮忙给看看什么原因?
不知我说清楚了吗?

1.#include <LiquidCrystal.h>
2.String comdata = "";
3.String text4;
4.String text5;
5.String text6;
6.int i;
7.LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
8.void setup()
9.{
10.
11.  lcd.clear();
12.  Serial.begin(9600);
13.//  delay(3000);
14.// Serial.print ("PMTK251,115200");
15.// Serial.print ("PMTK300,100,0,0,0,0");
16.Serial.print ("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29");
17.  lcd.begin(16,2);
18.  lcd.print("GPS DEMO");
19.  delay(3000);
20.  lcd.clear();
21.}
22.void loop()
23.{//y
24.   while (Serial.available() > 0)
25.{   //y
26.   for (byte i=1;i<=70;i++);
27.   {
28.comdata += char(Serial.read());
29.    delay(2);
30.   }
31.Serial.print(comdata);   //A
32.//comdata.toUpperCase();
33.// comdata.trim();
34.//comdata="$GPRMC,091859.800,A,3204.8736,N,11853.4971,E,1.46,14.92,280313,,,A*56";//B
35.
36.text4=(comdata.substring(comdata.indexOf('$')));
37.//Serial.println(text4);
38.text5=(text4.substring(text4.indexOf('A')+2));
39.text6=(text5.substring(0,text5.indexOf(',')));
40.Serial.print(text6);
41.  lcd.setCursor(0, 0);
42.  lcd.print((text6));
43.
44.  text5=(text4.substring(text4.indexOf('N')+2));
45.  text6=(text5.substring(0,text5.indexOf(',')));
46.  Serial.print(text6);
47.  lcd.setCursor(0, 1);
48.  lcd.print((text6));
49.
50.  text5=(text4.substring(text4.indexOf('E')+2));
51.  text6=(text5.substring(0,text5.indexOf(',')));
52.  Serial.print(text6);
53.  lcd.setCursor(10, 0);
54.  lcd.print((text6));
55.//    lcd.clear();
56.  comdata = "";
57.
58.}//y
59.}


第一段程序本来输出的结果就是comdata="$GPRMC,091859.800,A,3204.8736,N,11853.4971,E,1.46,14.92,280313,,,A*56",第二段程序的输入用赋值语句也让comdata为上面字符串时也正常,程序的蹊跷之处在于让第一段程序的结果(comdata)直接作为第二段程序的输入时,就不正常了。两段程序单独调试却都没问题,请高手再给看看。
回复

使用道具 举报

发表于 2013-4-12 09:14:05 | 显示全部楼层
建议第二句定义String comdata = "";时,先用字符填充成比所需字符长度稍长字符串,或者直接使用固定长度的字符串数组~~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-4-12 10:46:53 | 显示全部楼层
本帖最后由 fangtaonj 于 2013-4-12 10:49 编辑
飞翔的红猪 发表于 2013-4-12 09:14
建议第二句定义String comdata = "";时,先用字符填充成比所需字符长度稍长字符串,或者直接使用固定长度的字 ...


红猪您好!谢谢您的提示!按照您的提示我把String comdata = "";改为String comdata="$GPRMC,091859.800,A,3204.8736,N,11853.4971,E,12.34,14.92,280313,,,A*56";奇怪的刚看上去是显示都正常了,但又发模拟GPS数据的串口输入无效,无论怎么变化串口数据,都显示上面这个字符串的内容里的经纬度和速度数据,就是看上去串口输入的数据不能改变comdata。为了验证这点,我改了程序部分语句,变成:
#include <LiquidCrystal.h>   
String comdata1 = "";
String comdata;
String text4;
String text5;
String text6;
int i;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup()
{

  lcd.clear();
  Serial.begin(9600);
//  delay(3000);
// Serial.print ("PMTK251,115200");
// Serial.print ("PMTK300,100,0,0,0,0");
Serial.print ("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29");
  lcd.begin(16,2);
  lcd.print("GPS DEMO");
  delay(3000);
  lcd.clear();
}
void loop()
{//y
   while (Serial.available() > 0)
{   //y
   for (byte i=1;i<=70;i++);
   {
comdata1 += char(Serial.read());
    delay(2);
   }
comdata1.toUpperCase();
comdata1.trim();
comdata = comdata1;                                                                                                                                    //A:
//comdata="$GPRMC,091859.800,A,3204.8736,N,11853.4971,E,12.34,14.92,280313,,,A*56";                   //B:
Serial.print(comdata);
text4=(comdata.substring(comdata.indexOf('$')));
//Serial.println(text4);
text5=(text4.substring(text4.indexOf('A')+2));
text6=(text5.substring(0,text5.indexOf(',')));  
Serial.print(text6);
  lcd.setCursor(0, 0);
  lcd.print((text6));
  text5=(text4.substring(text4.indexOf('N')+2));
  text6=(text5.substring(0,text5.indexOf(',')));  
  Serial.print(text6);
  lcd.setCursor(0, 1);
  lcd.print((text6));
  text5=(text4.substring(text4.indexOf('E')+2));
  text6=(text5.substring(0,text5.indexOf(',')));  
  Serial.print(text6);
  lcd.setCursor(10, 0);
  lcd.print((text6));
//    lcd.clear();
  comdata1 = "";

}//y
}
主要是增加了commdata1这个变量,让前半部分用comdata1变量,后半部分用comdata变量,中间通过
commdata=commdata1给commdata变量数据看看是否接受到串口数据,结果用commdata=commdata1就不正常,用comdata="$GPRMC,091859.800,A,3204.8736,N,11853.4971,E,12.34,14.92,280313,,,A*56";就能屏幕显示(当然这个数是死的),就是说分别屏蔽语句A和语句B结果不一样,您看着是什么原因?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-4-12 10:50:54 | 显示全部楼层
飞翔的红猪 发表于 2013-4-12 09:14
建议第二句定义String comdata = "";时,先用字符填充成比所需字符长度稍长字符串,或者直接使用固定长度的字 ...

至于您说的使用固定长度的字符串数组,这个我还不太会弄,呵呵,刚学,不会的太多。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-4-12 21:27:36 | 显示全部楼层
我找到原因了,是每次的loop循环通过串口只读到一个字符,而不是这串字符都读出来再送到后面显示。每次一个字符当然不能显示,前半段调通的原因是它多次loop循环猜得到正确结果,而不是一次得到,我很奇怪,我设置70次的FOR循环读入难道有错误吗?各位高手帮帮忙,虽然原因找到但我怎么改程序呢?
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-5 05:45 , Processed in 0.034942 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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