极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 168576|回复: 67

Arduino学习笔记A6(补充) - 在串口读取多个字符串,并且转换为数字数组

  [复制链接]
发表于 2011-12-1 09:57:28 | 显示全部楼层 |阅读模式
Arduino学习笔记A6(补充) - 在串口读取多个字符串,并且转换为数字数组


功能如题目。
在串口收到逗号分割的6串数字比如
100,200,45,4,87,99
然后在6个PWM端口3, 5, 6, 9, 10, 11输出对应PWM值


代码注释很详细了,就不再说明了。
  1. //定义一个comdata字符串变量,赋初值为空值
  2. String comdata = "";
  3. //numdata是分拆之后的数字数组
  4. int numdata[6] = {0}, PWMPin[6] = {3, 5, 6, 9, 10, 11}, mark = 0;
  5. void setup()
  6. {
  7. //定义0~6脚是输出
  8.   for(int i = 0; i < 6; i++) pinMode(PWMPin[i], OUTPUT);
  9.   Serial.begin(9600);
  10. }

  11. void loop()
  12. {
  13. //j是分拆之后数字数组的位置记数
  14.   int j = 0;
  15.   
  16.   //不断循环检测串口缓存,一个个读入字符串,
  17.   while (Serial.available() > 0)
  18.   {
  19.   //读入之后将字符串,串接到comdata上面。
  20.     comdata += char(Serial.read());
  21.       //延时一会,让串口缓存准备好下一个数字,不延时会导致数据丢失,
  22.     delay(2);
  23.     //标记串口读过数据,如果没有数据的话,直接不执行这个while了。
  24.     mark = 1;
  25.   }
  26.    
  27.   if(mark == 1)  //如果接收到数据则执行comdata分析操作,否则什么都不做。
  28.   {
  29.   //显示刚才输入的字符串(可选语句)
  30.     Serial.println(comdata);
  31.       //显示刚才输入的字符串长度(可选语句)
  32.     Serial.println(comdata.length());
  33.    
  34. /*******************下面是重点*******************/
  35. //以串口读取字符串长度循环,
  36.     for(int i = 0; i < comdata.length() ; i++)
  37.     {
  38.     //逐个分析comdata[i]字符串的文字,如果碰到文字是分隔符(这里选择逗号分割)则将结果数组位置下移一位
  39.     //即比如11,22,33,55开始的11记到numdata[0];碰到逗号就j等于1了,
  40.     //再转换就转换到numdata[1];再碰到逗号就记到numdata[2];以此类推,直到字符串结束
  41.       if(comdata[i] == ',')
  42.       {
  43.         j++;
  44.       }
  45.       else
  46.       {
  47.          //如果没有逗号的话,就将读到的数字*10加上以前读入的数字,
  48.          //并且(comdata[i] - '0')就是将字符'0'的ASCII码转换成数字0(下面不再叙述此问题,直接视作数字0)。
  49.          //比如输入数字是12345,有5次没有碰到逗号的机会,就会执行5次此语句。
  50.          //因为左边的数字先获取到,并且numdata[0]等于0,
  51.          //所以第一次循环是numdata[0] = 0*10+1 = 1
  52.          //第二次numdata[0]等于1,循环是numdata[0] = 1*10+2 = 12
  53.          //第三次是numdata[0]等于12,循环是numdata[0] = 12*10+3 = 123
  54.          //第四次是numdata[0]等于123,循环是numdata[0] = 123*10+4 = 1234
  55.          //如此类推,字符串将被变成数字0。
  56.         numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
  57.       }
  58.     }
  59.     //comdata的字符串已经全部转换到numdata了,清空comdata以便下一次使用,
  60.     //如果不请空的话,本次结果极有可能干扰下一次。
  61.     comdata = String("");


  62.     //循环输出numdata的内容,并且写到PWM引脚
  63.     for(int i = 0; i < 6; i++)
  64.     {
  65.       Serial.print("Pin ");
  66.       Serial.print(PWMPin[i]);
  67.       Serial.print(" = ");
  68.       Serial.println(numdata[i]);
  69.       analogWrite(PWMPin[i], numdata[i]);
  70.       numdata[i] = 0;
  71.     }
  72.     //输出之后必须将读到数据的mark置0,不置0下次循环就不能使用了。
  73.     mark = 0;
  74.   }
  75. }
复制代码

评分

参与人数 1 +5 收起 理由
弘毅 + 5 对群里的问题进行了详解,赞。

查看全部评分

回复

使用道具 举报

发表于 2013-2-24 17:40:08 | 显示全部楼层
力挺楼主,我发了求助也没人应我,终于在这里找到答案了!
回复 支持 0 反对 1

使用道具 举报

发表于 2011-12-2 01:56:48 | 显示全部楼层
处理PC串口输入数据的方法真的有很多很多种.......我自己就研究了三种。
回复 支持 反对

使用道具 举报

发表于 2012-3-15 23:05:38 | 显示全部楼层
谢谢,楼主真的很有研究精神
回复 支持 反对

使用道具 举报

发表于 2012-5-3 15:37:36 | 显示全部楼层
   非常好 ....加油!
回复 支持 反对

使用道具 举报

发表于 2012-5-3 16:28:30 | 显示全部楼层
这种方法可以用在GPS协议的分析上~~
回复 支持 反对

使用道具 举报

发表于 2012-6-23 07:58:31 | 显示全部楼层
一定要 mark 么...?
回复 支持 反对

使用道具 举报

发表于 2012-6-24 10:39:33 | 显示全部楼层
这个程序处理的是字节型的数据,用于控制或者显示到LCD都还简单的,但是如果接收传送的是整形乃至浮点的时候该怎么处理呢,这个问题在用串口,无线模块,网络时都是存在的。。。
回复 支持 反对

使用道具 举报

发表于 2012-6-24 12:22:22 | 显示全部楼层
很好,最有个打包字符串教程就好了
回复 支持 反对

使用道具 举报

发表于 2012-7-6 18:20:14 | 显示全部楼层
很有用处,谢谢
回复 支持 反对

使用道具 举报

发表于 2012-7-21 11:46:09 | 显示全部楼层
  受用了。
回复 支持 反对

使用道具 举报

发表于 2012-8-18 21:53:53 | 显示全部楼层
本帖最后由 xietu 于 2012-8-18 21:59 编辑

//我最近正好有用到这个代码,很感谢,不过我需要输入负数,所以加了些改动;我刚接触arduino,编码还不熟,可能变得不够精炼,希望大侠们指点。


String comdata = "";
int numdata[6] = {0}, PWMPin[6] = {3, 5, 6, 9, 10, 11}, mark = 0,mark1 = 0;//加了一个指针,来判断是否有"-"负号存在。
void setup()
{
  for(int i = 0; i < 6; i++) pinMode(PWMPin, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  int j = 0;
  while (Serial.available() > 0)
  {
    comdata += char(Serial.read());
    delay(2);
    mark = 1;
  }
  if(mark == 1)
  {
    Serial.println(comdata);
    Serial.println(comdata.length());
  
    for(int i = 0; i < comdata.length()-1 ; i++)//这个位置“i < comdata.length()-1“原来的代码是”i < comdata.length()“,但我运行发现最后一个数字总是错的,我加了一个”-1“后,就正常了,我还不明白为什么
    {
    if(comdata == ',')
  {
     ++j;//原文是"j++",我查了“x++”,x将返回原值,这样的话“j”不就一直是0吗?“j++”和“++j”我都试过,都没出错,我很疑惑
    mark1=0;//读取到','时,将mark1恢复到0值,便于下个字符是"-"时,赋予"1"
   }
  else
    {
     if(comdata == '-')
     {
      mark1=1;//判断是否有负号"-"
     }
     else if(mark1==1)
     {
      numdata[j] =abs(numdata[j]);
      numdata[j] =numdata[j] * 10 + (comdata - '0');
      numdata[j] =0-numdata[j];//在执行此"else if"循环最后一条指令时,将数值转换为负值
     }
     else
     {
      numdata[j] = numdata[j] * 10 + (comdata - '0');
     }
     }//if(comdata == ',')的else结尾
   }//for(int i = 0; i < comdata.length()-1 ; i++)的结尾
    comdata = String("");
    for(int i = 0; i < 6; i++)
    {
      Serial.print("Pin ");
      Serial.print(PWMPin);
      Serial.print(" = ");
      Serial.println(numdata);
      analogWrite(PWMPin, numdata);
      numdata = 0;
    }
    mark = 0;
  }
}

评分

参与人数 1 +30 收起 理由
Ansifa + 30 赞一个!

查看全部评分

回复 支持 反对

使用道具 举报

发表于 2012-8-22 20:18:19 | 显示全部楼层
好多好多要学习的~
回复 支持 反对

使用道具 举报

发表于 2012-8-27 10:52:21 | 显示全部楼层
xietu 发表于 2012-8-18 21:53
//我最近正好有用到这个代码,很感谢,不过我需要输入负数,所以加了些改动;我刚接触arduino,编码还不熟, ...

字符串comdata后会加一个隐藏字符,表示字符串结束,而这个隐藏字符是要算长度的,所以得-1
回复 支持 反对

使用道具 举报

发表于 2012-8-30 20:50:43 | 显示全部楼层
好好学习,不错
回复 支持 反对

使用道具 举报

发表于 2012-9-20 00:02:16 | 显示全部楼层
受教了,佩服楼主的研究精神
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-26 02:56 , Processed in 0.048702 second(s), 35 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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