###串口通讯协议
串口通讯为了正确地解码接受到的信息,在接收端需要识别每个消息的开始标识和结束标识。
消息开始的标识–报头,一个或多个特殊字符。
结束的标识–报尾,一个或多个特殊字符。
消息的内容可以文本格式或二进制格式发送。
####文本格式发送和信息接收
以人类可读的字符和单词的方式发送命令和数值。数字通过一代表数值的数字字符串来发送。例如,如果该值是1234,字符1、2、3、4作为单个字符进行发送。
####二进制格式发送和信息接收
二进制数据通常更有效(需要发送的字节数更少),但是数据不像文本那样让人类可读。使得它更难调试。例如,Arduino用4字节数字4210(4X256+210=1234)代表1234.
####Arduino1.0变化
- Serial.flush 现在是要等待所有要传送的数据被发送,而不是丢弃收到的数据。如果想丢弃所有接受缓冲区的数据,可以用while(Serial.read()>=0);
####例子1-Arduino接受单字符数字
接收8位值,接收单个数字。并让13号引脚上的LED按照与接收到的数字值成正比例的速率闪烁。
/*
* SerialReceive sketch
* Blink the LED at a rate proportional to the received digit value
*/
const int ledPin = 13; // pin the LED is connected to
int blinkRate=0; // blink rate stored in this variable
void setup()
{
Serial.begin(9600); // Initialize serial port to send and receive at 9600 baud
pinMode(ledPin, OUTPUT); // set this pin as output
}
void loop()
{
if ( Serial.available()) // Check to see if at least one character is available
{
char ch = Serial.read();
if( isDigit(ch) ) // 判断接收到的字符是否是在 0 到 9之间?
{
blinkRate = (ch - '0'); // ASCII 数值转换为数字值
blinkRate = blinkRate * 100; // actual rate is 100mS times received digit
}
}
blink();
}
// blink the LED with the on and off times determined by blinkRate
void blink()
{
digitalWrite(ledPin,HIGH);
delay(blinkRate); // delay depends on blinkrate value
digitalWrite(ledPin,LOW);
delay(blinkRate);
}
blinkRate = (ch - ‘0’); 把字符型ch 转化成它的数字值。
该ASCII字符’0’–'9’的值是48-57.把’1’转换成1是通过减去“0”来完成的。换句话说(ch - ‘0’)和(ch-48)的效果相同,都是把变量ch的ASCII值转换成数字值。
####例子2-Arduino接收多字符数字,以换行符结束
/*
* SerialReceive sketch
* Blink the LED at a rate proportional to the received digit value
*/
const int ledPin = 13; // pin the LED is connected to
int blinkRate=0; // blink rate stored in this variable
int value;
void setup()
{
Serial.begin(9600); // Initialize serial port to send and receive at 9600 baud
pinMode(ledPin, OUTPUT); // set this pin as output
}
void loop()
{
if ( Serial.available()) // Check to see if at least one character is available
{
char ch = Serial.read();
if( isDigit(ch) ) // is this an ascii digit between 0 and 9?
{
value=(value*10)+(ch-'0');//计算累积值
}
else if(ch==10){//检测这个字符是否是换行符,遇到换行符时,停止接收
blinkRate=value;
Serial.println(blinkRate);
value=0;
}
}
blink();
}
// blink the LED with the on and off times determined by blinkRate
void blink()
{
digitalWrite(ledPin,HIGH);
delay(blinkRate); // delay depends on blinkrate value
digitalWrite(ledPin,LOW);
delay(blinkRate);
}
每个接收到的数字都是从它的ASCII值转换成它对应的数值。该数字是十进制表示,所以每个相连数字乘以10,以10进位。
####例子3-Arduino接收多字符数字,以换行符结束.判断正负数
如果接受到的数据有负数,那代码需要判断是否有一个先导的负号。每个数值以不是数字或者负号的字符隔开
int value=0;
int sign=1;
void setup()
{
Serial.begin(9600); // Initialize serial port to send and receive at 9600 baud
}
void loop()
{
if ( Serial.available()) // Check to see if at least one character is available
{
char ch = Serial.read();
if( isDigit(ch) ) // is this an ascii digit between 0 and 9?
{
value=(value*10)+(ch-'0');//计算累积值
}
else if(ch=='-'){
sign=-1; //判断是否接受到负号
}
else{
value=value*sign; //相乘处理
Serial.println(value);
value=0;
sign=1; //复位
}
}
}
####例子4-Arduino接收多字符数字,atoi方式
要使用它们,必须接受整个字符串,并把他们储存到字符数组中,然后才能调用转换函数.atoi