前言
大家好,我是爱学习的小鱼,今天接着昨天的回充,不过今天使用的是红外回充方法。红外方法比较简单,其原理就像遥控器和空调之间的关系一样,机器人类似于空调,装有两个接收头,机器人充电桩上则装有两个红外发射灯,两个灯会发送不同的波,通过接收到的波的信号不同,则可以区分出充电桩的位置。我手拙画了个简单示意图。
只有机器人上的接收头朝向充电桩的时候,两个接收头才能分别都接收到两个发射头的信号,否则根据情况旋转机器人朝向充电桩即可。
1. 发射与接收电路设计
发射和接收电路设计如下:
- 发射端:两个红外发射灯,分别连接到微控制器的两个输出引脚。
- 接收端:两个红外接收头,分别连接到微控制器的输入引脚。
2. 发射代码
下面是用于控制红外发射灯的Arduino代码。它通过定时器中断产生两个不同宽度的红外信号。
#include <Arduino.h>
#define IR1IO 18
#define IR2IO 19
hw_timer_t * timer = NULL; // 声明一个定时器
#define digitalToggle(x) digitalWrite(x, !digitalRead(x))
bool openir1 = false;
bool openir2 = false;
void IRAM_ATTR onTimer() { // 中断函数
if(openir1){
digitalToggle(IR1IO);
}
if(openir2){
digitalToggle(IR2IO);
}
}
void setup() {
Serial.begin(115200);
Serial.println("loop----------------------------------------");
timer = timerBegin(0, 80, true); // 初始化
timerAttachInterrupt(timer, &onTimer, true); // 调用中断函数
timerAlarmWrite(timer, 13, true); // 设置定时器报警
timerAlarmEnable(timer); // 定时器使能
pinMode(IR1IO, OUTPUT); // 18
pinMode(IR2IO, OUTPUT); // 19
}
void loop() {
openir1 = true;
delay(7);
openir1 = false;
delay(25);
openir1 = true;
delay(1);
openir1 = false;
delay(67);
openir2 = true;
delay(7);
openir2 = false;
delay(36);
openir2 = true;
delay(1);
openir2 = false;
delay(56);
}
3. 接收代码
下面是用于接收和处理红外信号的Arduino代码。它通过检测红外信号的脉冲宽度来判断信号的来源。
struct IRData {
uint8_t d0 : 1;
uint8_t d1 : 1; // A
uint8_t d2 : 1; // B
uint8_t d3 : 1;
uint8_t d4 : 1;
uint8_t d5 : 1; // A
uint8_t d6 : 1; // B
uint8_t d7 : 1;
} __attribute__((packed));
struct IRData irdata;
uint16_t ir1_low_tick;
uint16_t ir1_low_tickf7;
bool ir1recv7ms = false;
uint16_t ir1_last25;
uint16_t ir1_last36;
uint16_t ir2_low_tick;
uint16_t ir2_low_tickf7;
bool ir2recv7ms = false;
uint16_t ir2_last25;
uint16_t ir2_last36;
void IRAM_ATTR onTimer() { // 中断函数
ir1_last25++;
ir1_last36++;
ir2_last25++;
ir2_last36++;
if (digitalRead(IR1IO) == 1) {
ir1_low_tick = 0;
ir1_low_tickf7 += 1;
} else {
if (ir1recv7ms) {
ir1recv7ms = 0;
if (ir1_low_tickf7 == 25) {
irdata.d2 = 1;
ir1_last25 = 0;
} else if (ir1_low_tickf7 == 36) {
irdata.d1 = 1;
ir1_last36 = 0;
}
}
ir1_low_tick += 1;
}
if (ir1_low_tick == 7) {
ir1recv7ms = true;
ir1_low_tickf7 = 0;
}
if (ir1_last25 > 400) {
irdata.d2 = 0;
}
if (ir1_last36 > 400) {
irdata.d1 = 0;
}
if (digitalRead(IR2IO) == 1) {
ir2_low_tick = 0;
ir2_low_tickf7 += 1;
} else {
if (ir2recv7ms) {
ir2recv7ms = 0;
if (ir2_low_tickf7 == 25) {
irdata.d6 = 1;
ir2_last25 = 0;
} else if (ir2_low_tickf7 == 36) {
irdata.d5 = 1;
ir2_last36 = 0;
}
}
ir2_low_tick += 1;
}
if (ir2_low_tick == 7) {
ir2recv7ms = true;
ir2_low_tickf7 = 0;
}
if (ir2_last25 > 400) {
irdata.d6 = 0;
}
if (ir2_last36 > 400) {
irdata.d5 = 0;
}
}
总结
通过以上的设计和代码实现,我们可以通过红外线实现机器人自动回充。这个方法的原理和实现都相对简单,但实际应用时需要根据环境进行调试和优化,希望这篇文章能对大家有所帮助。如果有任何问题或者建议,欢迎在评论区留言,我们一起探讨学习。
往期文章推荐: