arduino通信问题的学习与解决
Posted anandexuechengzhangzhilu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了arduino通信问题的学习与解决相关的知识,希望对你有一定的参考价值。
{
Serial.begin(9600);
}
{
while (Serial.available() > 0)
{
comdata += char(Serial.read());
delay(2);
}
if (comdata.length() > 0)
{
Serial.println(comdata);
comdata = "";
}
}此代码作用就是用Serial.read()以此读入数据,然后存在comdata字符串内,之后要调用只需要comdata[x](x为你指定的整型数字)即可,但是我加进我的程序之后,发现问题并不这么简单,怎么调都出问题,在无能为力的情况下,只能重新写程序,一点一点研究走。我自己重写了一个程序,用于研究。
首先,我认为问题出在串口上面,arduino的串口一次通过一个值,如果不通过电脑给arduino输出的话,它应该会通过一个默认值。写入程序,发现这个默认值为-1
那么我们就需要一个判断语句,把这些没用的值过滤掉。if(myinput > 0)即可。这里注意,Serial.read()语句调用一次读一个字符,调用第二次就读下一个字符,所以我们需要一个临时的变量存储Serial.read()读到的值,问题是,该用什么类型定义这个变量呢?int myinput;然后 myinput = Serial.read(); 为啥?这里重要的事情说三遍:Serial.read()从电脑端读入的值强制转换成整型输出!Serial.read()从电脑端读入的值强制转换成整型输出!Serial.read()从电脑端读入的值强制转换成整型输出!但是,你从电脑端输入的是字符型;你从电脑端输入的是字符型;你从电脑端输入的是字符型;也就是说,你要输入1,myinput就是1字符的ASC2码,就是49,输入2,myinput就是整型50,输入S,返回的就是83!所以,要把myinput减一个‘0’,让他变成整形数字,这样的话,1为1,2为2,S就是35。明白了这个,之后的操作才可行。
输入123JS,成功!不过串口默认值变成-4。
当然你也可以用char来处理,不过默认值就变成了不知道什么的字符,看着很难受。
解决的这个问题后,来解决下一个问题,如果我在电脑上输入两个字符LS,存进两个myinput里,但是机器怎么识别是不是有默认值混进来呢,因为电脑不传命令,就传默认值,所以到头来,我的myinput可能是-1L,或是S-1,这就不好了。没有关系,加入这段代码即可//判断输入指令 if(myinput1 > 0) { order1 = myinput1 - ‘0‘; order2 = myinput2 - ‘0‘; } else { order1 = myinput2 - ‘0‘; order2 = myinput3 - ‘0‘; }意思是,从串口里读入三个信号,然后从中依次判别各个信号是否有效(是否大于0),最后输出有效字符,存入order内,从而剔除了默认值-1。串口的问题已解决,之后的问题都迎刃而解,程序一下次就实验成功了。下面给出arduino源码//arduino环境#include <string.h>int servopinL1=9;//定义数字接口9 连接左手旋转伺服舵机信号线int servopinL2=10;//定义数字接口10 连接左手夹持伺服舵机信号线int servopinR1=8;//定义数字接口9 连接右手旋转伺服舵机信号线int servopinR2=7;//定义数字接口10 连接右手夹持伺服舵机信号线int myinput1;int myinput2;int myinput3;int order1;int order2;int myangle;//定义角度变量int pulsewidth;//定义脉宽变量int val;String comdata = "";void servopulse(int servopin,int myangle)//定义一个脉冲函数{pulsewidth=(myangle*11)+500;//将角度转化为500-2480 的脉宽值digitalWrite(servopin,HIGH);//将舵机接口电平至高delayMicroseconds(pulsewidth);//延时脉宽值的微秒数digitalWrite(servopin,LOW);//将舵机接口电平至低delay(20-pulsewidth/1000);}void setup(){ Serial.begin(9600);//连接到串行端口,波特率为9600 Serial.println("servo1 ready" ) ; Serial.println("servo2 ready" ) ; pinMode(servopinL1,OUTPUT);//设定舵机接口为输出接口 pinMode(servopinL2,OUTPUT);//设定舵机接口为输出接口 pinMode(servopinR1,OUTPUT);//设定舵机接口为输出接口 pinMode(servopinR2,OUTPUT);//设定舵机接口为输出接口}void loop(){ myinput1 = Serial.read(); myinput2 = Serial.read(); myinput3 = Serial.read(); Serial.println(myinput1); Serial.println(myinput2); Serial.println(myinput3); delay(1000); //判断输入指令 if(myinput1 > 0) if(myinput2 > ‘0‘) { order1 = myinput1 - ‘0‘; order2 = myinput2 - ‘0‘; } else { order1 = myinput2 - ‘0‘; order2 = myinput3 - ‘0‘; } if(order1 > 0 && order2 > 0) { Serial.println(order1); Serial.println(order2); if(order1 == 28) { switch (order2) { case 1: val = 0; val=val*(180/2);//将数字转化为角度 Serial.print("anticlockwise "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinL1,val);//引用脉冲函数 } break; case 2: val = 1; val=val*(180/2);//将数字转化为角度 Serial.print("no move "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinL1,val);//引用脉冲函数 } break; case 3: val = 2; val=val*(180/2);//将数字转化为角度 Serial.print("clockwise "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinL1,val);//引用脉冲函数 } break; case 26: //字符串‘J‘的ASC二码转化为整形后 - ‘0‘ val = 4; val=val*(180/9);//将数字转化为角度 Serial.print("close "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinL2,val);//引用脉冲函数 } break; case 35: //字符串‘S‘的ASC二码转化为整形后 - ‘0‘ val = 2; val=val*(180/9);//将数字转化为角度 Serial.print("open "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinL2,val);//引用脉冲函数 } break; } Serial.println("Good job!"); myinput1 = 0; myinput2 = 0; myinput3 = 0; order1 = 0; order2 = 0; } else if(order1 == 34) { switch (order2) { case 1: val = 0; val=val*(180/2);//将数字转化为角度 Serial.print("anticlockwise "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinR1,val);//引用脉冲函数 } break; case 2: val = 1; val=val*(180/2);//将数字转化为角度 Serial.print("no move "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinR1,val);//引用脉冲函数 } break; case 3: val = 2; val=val*(180/2);//将数字转化为角度 Serial.print("clockwise "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinR1,val);//引用脉冲函数 } break; case 26: //字符串‘J‘的ASC二码转化为整形后 - ‘0‘ val = 5; val=val*(180/9);//将数字转化为角度 Serial.print("close "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinR2,val);//引用脉冲函数 } break; case 35: //字符串‘S‘的ASC二码转化为整形后 - ‘0‘ val = 0; val=val*(180/9);//将数字转化为角度 Serial.print("open "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopinR2,val);//引用脉冲函数 } break; } Serial.println("Good job!"); myinput1 = 0; myinput2 = 0; myinput3 = 0; order1 = 0; order2 = 0; } } }
---------------------
来源:CSDN
原文:https://blog.csdn.net/qq_26371477/article/details/79397613
以上是关于arduino通信问题的学习与解决的主要内容,如果未能解决你的问题,请参考以下文章
关于通过 USART 上的 MDB 协议与自动售货机通信时 Arduino 的 TX 线的问题
通过 CDC COM 端口与 Arduino 进行 Windows COM 通信
Arduino与Proteus仿真实例-两个Arduino之间SPI通信仿真