概述
在第二课中介绍了如何控制电机,这一课中我们会简介如何用红外遥控器控制坦克小车运动。
工作原理
坦克小车上有一个红外接收器,当遥控器按下按键,红外接收器会接收红外信号,arduino会把这个红外信号解码这个红外信号,每个按键对应一个不同的红外信号,当arduino接收到不同的红外信号后执行不同的操作,实现不同的功能。例如,arduino接收到遥控器上“1”对应的红外信号后坦克小车前进;接收到“2”对应的红外信号小车后退。
软件
下载https://osoyoo.com/driver/tank_robot_lesson3.zip并解压文件,用arduino IDE打开tank_robot_lesson3.ino文件,下面对代码做简要说明。
将要用到按键的红外编码在软件中做如下定义,每个按键的红外编码可以烧录第一课中的代码,对着红外接收器按遥控器,Serial Monitor就会打印出对应按键的红外编码。
#define IR_ADVANCE 0x00FF18E7 //code from IR controller "▲" button #define IR_BACK 0x00FF4AB5 //code from IR controller "▼" button #define IR_RIGHT 0x00FF5AA5 //code from IR controller ">" button #define IR_LEFT 0x00FF10EF //code from IR controller "<" button #define IR_SERVO 0x00FF38C7 //code from IR controller "OK" button #define IR_OPENLED 0x00FFB04F //code from IR controller "#" button #define IR_CLOSELED 0x00FF6897 //code from IR controller "*" button #define IR_BEEP 0x00FF9867 //code from IR controller "0" button
在本课中我们用到的按键和对应的功能如下表所示
| 按键名 | 对应功能 |
| ▲ | 前进 |
| ▼ | 后退 |
| > | 右转 |
| < | 左转 |
| OK | 旋转舵机 |
| # | 打开LED |
| * | 关闭LED |
| 0 | 蜂鸣器响 |
通过枚举类型定义上表中各个功能对应代码
enum DN
{
GO_ADVANCE, //go ahead
GO_LEFT, //left turn
GO_RIGHT,//right turn
GO_BACK,//go back
MOVE_SERVO,//move servo
OPEN_LED,//open led
CLOSE_LED,//close led
BEEP,//control buzzer
DEF
}Drive_Num=DEF;
解码红外信号
void do_IR_Tick()
{
if(IR.decode(&IRresults))
{
if(IRresults.value==IR_ADVANCE)
{
Drive_Num=GO_ADVANCE;
}
else if(IRresults.value==IR_RIGHT)
{
Drive_Num=GO_RIGHT;
}
else if(IRresults.value==IR_LEFT)
{
Drive_Num=GO_LEFT;
}
else if(IRresults.value==IR_BACK)
{
Drive_Num=GO_BACK;
}
else if(IRresults.value==IR_SERVO)
{
Drive_Num=MOVE_SERVO;
}
else if(IRresults.value==IR_OPENLED)
{
Drive_Num=OPEN_LED;
}
else if(IRresults.value==IR_CLOSELED)
{
Drive_Num=CLOSE_LED;
}
else if(IRresults.value==IR_BEEP)
{
Drive_Num=BEEP;
}
IRresults.value = 0;
IR.resume();
}
}
通过调用IR.decode(&IRresults)将红外信号解码结果存储在IRresults.value变量中,将IRresults.value变量与预定义的按键红外编码比较,如果相等,就把对应的功能代码赋值给枚举变量Drive_Num。
void do_Drive_Tick()
{
switch (Drive_Num)
{
case GO_ADVANCE:
go_ahead(10);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_ADVANCE code is detected, then go advance
case GO_LEFT:
turn_left(10);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_LEFT code is detected, then turn left
case GO_RIGHT:
turn_right(10);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_RIGHT code is detected, then turn right
case GO_BACK:
go_back(10);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_BACK code is detected, then backward
case MOVE_SERVO:
move_servo();JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//move servo
case OPEN_LED:
open_led(1),open_led(2);JogTime = 0;break;//open led
case CLOSE_LED:
close_led(1),close_led(2);JogTime = 0;break;//close led
case BEEP:
control_beep();JogTime = 0;break;//control beep
default:break;
}
Drive_Num=DEF;
//keep current moving mode for 200 millis seconds
if(millis()-JogTime>=200)
{
JogTime=millis();
if(JogFlag == true)
{
stopFlag = false;
if(JogTimeCnt <= 0)
{
JogFlag = false; stopFlag = true;
}
JogTimeCnt--;
}
if(stopFlag == true)
{
JogTimeCnt=0;
go_stop();
}
}
}
在do_Drive_Tick()函数中,判断Drive_Num变量的值并执行对应的功能函数。
void open_led(int led_num)
{
if (led_num == 1) digitalWrite(LED1,LOW);
else digitalWrite(LED2,LOW);
}
void close_led(int led_num)
{
if (led_num == 1) digitalWrite(LED1,HIGH);
else digitalWrite(LED2,HIGH);
}
/*******control buzzer*******/
void control_beep()
{
digitalWrite(BUZZER,LOW),delay(100);
digitalWrite(BUZZER,HIGH),delay(100);
}
/***move servo***/
void move_servo()
{
int i;
for(i = 0;i<180;i++){ head.write(i); delay(5); } for(i = 180;i>=0;i--){
head.write(i);
delay(5);
}
head.write(90);
}
上面的4个函数分别用于控制LED的打开、关闭、控制蜂鸣器响以及让舵机从0度转到180度,再从180度转到0度,最后回到90度。
用usb线把坦克下车与pc连接起来,选择正确的板子型号和端口号,将程序烧录到arduino中,打开电池盒电源,将遥控器对着红外接收器按按键,如果所按按键是程序预先定义好的,小车将执行相应的功能函数;如果所按按键是程序未定义的,小车不做任何操作。
DownLoad Url osoyoo.com