Arduino学习笔记A6(补充) - 在串口读取多个字符串,并且转换为数字数组
Arduino学习笔记A6(补充) - 在串口读取多个字符串,并且转换为数字数组功能如题目。
在串口收到逗号分割的6串数字比如
100,200,45,4,87,99
然后在6个PWM端口3, 5, 6, 9, 10, 11输出对应PWM值
代码注释很详细了,就不再说明了。//定义一个comdata字符串变量,赋初值为空值
String comdata = "";
//numdata是分拆之后的数字数组
int numdata = {0}, PWMPin = {3, 5, 6, 9, 10, 11}, mark = 0;
void setup()
{
//定义0~6脚是输出
for(int i = 0; i < 6; i++) pinMode(PWMPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
//j是分拆之后数字数组的位置记数
int j = 0;
//不断循环检测串口缓存,一个个读入字符串,
while (Serial.available() > 0)
{
//读入之后将字符串,串接到comdata上面。
comdata += char(Serial.read());
//延时一会,让串口缓存准备好下一个数字,不延时会导致数据丢失,
delay(2);
//标记串口读过数据,如果没有数据的话,直接不执行这个while了。
mark = 1;
}
if(mark == 1)//如果接收到数据则执行comdata分析操作,否则什么都不做。
{
//显示刚才输入的字符串(可选语句)
Serial.println(comdata);
//显示刚才输入的字符串长度(可选语句)
Serial.println(comdata.length());
/*******************下面是重点*******************/
//以串口读取字符串长度循环,
for(int i = 0; i < comdata.length() ; i++)
{
//逐个分析comdata字符串的文字,如果碰到文字是分隔符(这里选择逗号分割)则将结果数组位置下移一位
//即比如11,22,33,55开始的11记到numdata;碰到逗号就j等于1了,
//再转换就转换到numdata;再碰到逗号就记到numdata;以此类推,直到字符串结束
if(comdata == ',')
{
j++;
}
else
{
//如果没有逗号的话,就将读到的数字*10加上以前读入的数字,
//并且(comdata - '0')就是将字符'0'的ASCII码转换成数字0(下面不再叙述此问题,直接视作数字0)。
//比如输入数字是12345,有5次没有碰到逗号的机会,就会执行5次此语句。
//因为左边的数字先获取到,并且numdata等于0,
//所以第一次循环是numdata = 0*10+1 = 1
//第二次numdata等于1,循环是numdata = 1*10+2 = 12
//第三次是numdata等于12,循环是numdata = 12*10+3 = 123
//第四次是numdata等于123,循环是numdata = 123*10+4 = 1234
//如此类推,字符串将被变成数字0。
numdata = numdata * 10 + (comdata - '0');
}
}
//comdata的字符串已经全部转换到numdata了,清空comdata以便下一次使用,
//如果不请空的话,本次结果极有可能干扰下一次。
comdata = String("");
//循环输出numdata的内容,并且写到PWM引脚
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,不置0下次循环就不能使用了。
mark = 0;
}
} 力挺楼主,我发了求助也没人应我,终于在这里找到答案了! 处理PC串口输入数据的方法真的有很多很多种.......我自己就研究了三种。 谢谢,楼主真的很有研究精神 非常好 ....加油! 这种方法可以用在GPS协议的分析上~~ 一定要 mark 么...? 这个程序处理的是字节型的数据,用于控制或者显示到LCD都还简单的,但是如果接收传送的是整形乃至浮点的时候该怎么处理呢,这个问题在用串口,无线模块,网络时都是存在的。。。 很好,最有个打包字符串教程就好了 很有用处,谢谢 :)受用了。 本帖最后由 xietu 于 2012-8-18 21:59 编辑
//我最近正好有用到这个代码,很感谢,不过我需要输入负数,所以加了些改动;我刚接触arduino,编码还不熟,可能变得不够精炼,希望大侠们指点。
String comdata = "";
int numdata = {0}, PWMPin = {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 =abs(numdata);
numdata =numdata * 10 + (comdata - '0');
numdata =0-numdata;//在执行此"else if"循环最后一条指令时,将数值转换为负值
}
else
{
numdata = numdata * 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;
}
} :dizzy:好多好多要学习的~ xietu 发表于 2012-8-18 21:53 static/image/common/back.gif
//我最近正好有用到这个代码,很感谢,不过我需要输入负数,所以加了些改动;我刚接触arduino,编码还不熟, ...
字符串comdata后会加一个隐藏字符,表示字符串结束,而这个隐藏字符是要算长度的,所以得-1
好好学习,不错 受教了,佩服楼主的研究精神