学完DF100入门教程之后,现在来巩固一下学习的成果。 课程中学习了许多有趣的元件,现在结合几个元件,动手做一个红外遥控控制舵机转动的实验。
步骤1 功能描述
数码管显示红外遥控的按键数字,同时按键0~9可以使舵机从0度慢慢转到180度,也可以通过前进或者后退键直接使舵机转到180度或者0度。红外遥控的电源键也可以控制面包板上的继电器,从而控制led的点亮与熄灭。
步骤2 电路图
电路图中数码管部分和入门教程中实验15的数码管接法一致(电阻边的红色标号对应pin2~9),在其基础上添加了红外接收器、舵机、继电器、led等。
步骤3 实物图
代码
#include <IRremote.h> //调用IRremote.h库
int relayPin = 10; // 继电器连接到数字10
int relayState = HIGH; // 继电器初始状态为HIGH
#include <Servo.h> // 声明调用Servo.h库
Servo myservo; // 创建一个舵机对象
int pos = 0; // 变量pos用来存储舵机位置
int flag = 0;
int RECV_PIN = 11; //定义RECV_PIN变量为11
IRrecv irrecv(RECV_PIN); //设置RECV_PIN(也就是11引脚)为红外接收端
decode_results results; //定义results变量为红外结果存放位置
int currentNumber = 0; //该变量用于存放当前数字
long codes[13]= //该数组用来存放红外遥控器发出的红外码
{
0xFD30CF,0xFD08F7, // 0 ,1
0xFD8877,0xFD48B7, // 2 ,3
0xFD28D7,0xFDA857, // 4 ,5
0xFD6897,0xFD18E7, // 6 ,7
0xFD9867,0xFD58A7, // 8 ,9
0xFD20DF,0xFD609F, // 前进 ,后退
0xFD00FF, //电源键
};
int number[10][8] = //该数组用来存放数码管显示的数字
{
{0,0,0,1,0,0,0,1},//0
{0,1,1,1,1,1,0,1},//1
{0,0,1,0,0,0,1,1},//2
{0,0,1,0,1,0,0,1},//3
{0,1,0,0,1,1,0,1},//4
{1,0,0,0,1,0,0,1},//5
{1,0,0,0,0,0,0,1},//6
{0,0,1,1,1,1,0,1},//7
{0,0,0,0,0,0,0,1},//8
{0,0,0,0,1,1,0,1} //9
};
void numberShow(int i) { //该函数用来让数码管显示数字
for(int pin = 2; pin <= 9 ; pin++){
digitalWrite(pin, number[i][pin - 2]);
}
}
void setup(){
Serial.begin(9600); //设置波特率为9600
myservo.attach(12); // 将引脚12上的舵机与声明的舵机对象连接起来
irrecv.enableIRIn(); //启动红外解码
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, relayState); // 设置继电器的初始状态
for(int pin = 2 ; pin <= 9 ; pin++){ //设置数字引脚2~9为输出模式
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
}
}
void loop() {
//判断是否接收到解码数据,把接收到的数据存储在变量results中
if (irrecv.decode(&results)) {
flag = 1;
for(int i = 0; i <= 12; i++){
//判断是否接收到0~9按键的红外码
if(results.value == codes[i]&& i <= 9){
numberShow(i); //在数码管上对应显示0~9
currentNumber = i; //把当前显示的值赋给变量currentNumber
Serial.println(i);
myservo.write(i*18);
break;
}
//判断是否接收到递减的红外码,并且当前值不为0
else if(results.value == codes[10]&& currentNumber != 0){
myservo.write(0); //舵机回到0位置
currentNumber = 0; //当前数字改为0
numberShow(0); //数码管显示递减后的值
Serial.println(currentNumber); //串口输出递减后的值
break;
}
//判断是否接收到递增的红外码,并且当前值不为9
else if(results.value == codes[11]&& currentNumber != 9){
myservo.write(180); //舵机转到180位置
currentNumber = 9; //当前数字改为9
numberShow(9); //数码管显示递增后的值
Serial.println(currentNumber); //串口输出递增后的值
break;
}
//判断是否接收到电源键的红外码
else if(results.value == codes[12]&&flag){
flag = 0;
relayState = !relayState; //继电器转变状态,实现开关
delay(250);
digitalWrite(relayPin, relayState);
}
}
Serial.println(results.value, HEX); //串口监视器查看红外码
irrecv.resume(); //等待接收下一个信号
}
}
ASH腻2018.11.27
不错 支持一下