基础
串口硬件的发送和接收表示序列位的电脉冲数据。每个字节信息由各种组合的"0"和"1"构成。
我们向arduino发送数据通常有两种方式,一种是通过串口监视器,一种是通过Serial.print。
串口打印(Serail.print)信息不能拼接字符串或变量,这是个很大的缺陷,可以用springf来实现,如:
char inf[100]="";
int n=10;
sprintf(inf,"abab%d",n);
串口协议
协议命令 | 小车状态 |
---|---|
$0,0,0# | 停止 |
$1,0,0# | 前进 |
$2,0,0# | 后退 |
$3,0,0# | 左转 |
$4,0,0# | 右转 |
$0,1,0# | 原地左转 |
$0,2,0# | 原地右转 |
串口解析
#define run_car '1'//按键前
#define back_car '2'//按键后
#define left_car '3'//按键左
#define right_car '4'//按键右
#define stop_car '0'//按键停
/*小车运行状态枚举*/
enum {
enSTOP = 0,
enRUN,
enBACK,
enLEFT,
enRIGHT,
enTLEFT,
enTRIGHT
} enCarState;
void serial_data_parse()
{
//小车原地左旋右旋判断
if (InputString[3] == '1') //小车原地左旋
{
g_CarState = enTLEFT;
}
else if (InputString[3] == '2') //小车原地右旋
{
g_CarState = enTRIGHT;
}
else
{
g_CarState = enSTOP;
}
//小车的前进,后退,左转,右转,停止动作
if (g_CarState != enTLEFT && g_CarState != enTRIGHT)
{
switch (InputString[1])
{
case run_car: g_CarState = enRUN; break;
case back_car: g_CarState = enBACK; break;
case left_car: g_CarState = enLEFT; break;
case right_car: g_CarState = enRIGHT; break;
case stop_car: g_CarState = enSTOP; break;
default: g_CarState = enSTOP; break;
}
}
InputString = ""; //清空串口数据
NewLineReceived = false;
//根据小车状态做相应的动作
switch (g_CarState)
{
case enSTOP: Motor.stop(200,5); break;
case enRUN: Motor.forward(200); break;
case enLEFT: Motor.turnLeft(200,5); break;
case enRIGHT: Motor.turnRight(200,5); break;
case enBACK: Motor.back(200,5); break;
case enTLEFT: Motor.turnLeftOrigin(200,5); break;
case enTRIGHT: Motor.turnRightOrigin(200,5); break;
default: Motor.stop(200,5); break;
}
}
串口解包
void serialEvent()
{
while (Serial.available())
{
//一个字节一个字节地读,下一句是读到的放入字符串数组中组成一个完成的数据包
IncomingByte = Serial.read();
if (IncomingByte == '$')
{
StartBit = true;
}
if (StartBit == true)
{
InputString += (char) IncomingByte;
}
if (IncomingByte == '#')
{
NewLineReceived = true;
StartBit = false;
}
}
}
主函数
void loop()
{
if (NewLineReceived)
{
serial_data_parse(); //调用串口解析函数
}
}