概述
在第二课中介绍了如何控制电机,这一课中我们会简介如何用红外遥控器控制坦克小车运动。
工作原理
坦克小车上有一个红外接收器,当遥控器按下按键,红外接收器会接收红外信号,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