今天学习了串口通信的相关内容,其实就是Serial的一系列函数:
Serial.begin(); //开启串口
Serial.end(); //关闭串口
Serial.available();//判断串口缓冲器是否有数据装入
Serial.read(); //读取串口数据
Serial.flush(); //清空串口缓存
Serial.print(); //写入字符串数据到串口
Serial.println(); //写入字符串数据+换行到串口
Serial.write(); //写入二进制数据到串口
Serial.SerialEvent();//read时触发的事件函数
Serial.readBytes(buffer,length);//读取固定长度的二进制流
我想实现一个通过串口控制arduino板子上LED等点亮和熄灭的程序,具体代码如下:
String str = "Hello world!";
int val =20;
float iVal=2.29;
void setup(){
Serial.begin(9600);//
pinMode(13,OUTPUT);
}
void loop(){
// while (Serial.available()>0){
// val = Serial.read();
// Serial.println(char(val));
// val = int(val);
// Serial.println(val);
// if(val == 82){
// Serial.println(str);//
// Serial.println(val);
// digitalWrite(13,HIGH);
// delay(2000);
// }else{
// digitalWrite(13,LOW);
// }
// }
str = parseString();
//Serial.println(str);
if(str=="open"){
val = 101;
}else if(str=="close"){
val = 10;
}
switch(val){
case 101:
digitalWrite(13,HIGH);
Serial.println(56,BIN);
Serial.println(56,OCT);
Serial.println(56,DEC);
Serial.println(56,HEX);
Serial.println(1.2343,0);
Serial.println(1.2343,1);
Serial.println(1.2343,2);
Serial.println(1.2343,3);
// Serial.write(iVal);
val = 0;
delay(2000);
break;
case 10:
digitalWrite(13,LOW);
val = 0;
break;
default:
break;
}
}
String parseString(){
String str ;
while(Serial.available()>0){
str +=char(Serial.read());
delay(1);
}
return str;
}
这个代码是在完成基本功能的情况下又做了一些测试工作。首先我想将命令字符变成一个字符串,测试一些在串口上传输一个字符串的接受方法,写在parseString这个函数里面。另外对printLn和write函数的功能区别进行了探究。有一下几点内容需要注意:
一、关于arduino编程环境的理解
在这个环境中有两个最基本的函数,一个是setup()主要负责初始化工作,比如引脚的定义,串口波特率的定义等等。另一个是loop()函数,这个函数就相当于是单片机的操作系统,当程序注入到芯片后,完成相关初始化工作,这个程序就会反复执行。注意是一遍一遍的反复执行,在执行过程中,根据代码的指令要求做相关的事项,比如从串口读取数据等。由于她会反复执行,所以写这个函数的代码时要注意代码逻辑(这里面有循环)!
二、关于时延的问题
在从串口read数据时,如果读取的是一个字节序列,那么读完一个字节,要加入一个delay,如果不加入的话就无法正常读取字节序列,这个可能是因为串口通信的同步问题造成的。这也是硬件开发与软件开发的一个区别,可能还有点类似与软件开发过程中的异步问题,但这里没有多线程,所以只能等待,这也就可能导致数据传输的速率不可能太快。
三、关于read()函数
该函数每次只能从缓冲区中读取一个字节,并把该字节解析为一个ASCII码,如果你想把他转化为其他类型,可以对其进行强制类型转化,可以使用Serial.available()>0判断缓冲区中是否还有数据,这两个函数配合就能实现输入数据的读取。并且read函数执行之后,就会把已经读取的数据自动从缓冲区中删除,这样就不会重复读取数据的情况。
四、关于print和write两个函数的区别
在输出字符串方面这两个函数的效果是一致的,例如Serial.write(“jfdslajfdslk\n”);
Serial.println(“jfdslajfdslk”);
这两个函数输出后在控制台接受到的内容是完全一样的。(\n是换行的意思。等同于print后面的ln)但是如果是如下
Serial.println(56);
Serial.write(56);
这两个的输入结果就是不一样的,
print输出的是数字56,而write输出的是56所代表的ASCII码。也就是说在函数print中你可以输出任何东西,你输出的东西他都会将其转换为字符进行传输,所以当我们print(56)时,其传输的并不是数字56,而是将其转换为字符串,然后传输,所以你得到的56其实是一个字符串,而并不是一个整数。而write函数的输入参数如果是整数,他会把这个整数转换成一个字节的ASCII码然后传输,所以得到的是56所代表的ASCII码。另外,write函数的输入参数只能是字符串或者整数。而且正如代码中看到的print的还有第二参数,可以规定第一个输入参数的类型,如果是浮点型,还可以规定精度。可见print要比write要灵活的多。
但是有一点是确定的,在这个通信的过程中传输的都是一个字节的ASCII或者是ASCII的序列,只不过print函数在接受到后对数据进行了处理。也许这会导致在传输较大数量的数据时write的效率要比print要高一些。