紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
ROS 2机器人自动回充之红外法(附源码原理图)
-
ROS 2机器人自动回充之红外法(附源码原理图)
前言
大家好,我是爱学习的小鱼,今天接着昨天的回充,不过今天使用的是红外回充方法。红外方法比较简单,其原理就像遥控器和空调之间的关系一样,机器人类似于空调,装有两个接收头,机器人充电桩上则装有两个红外发射灯,两个灯会发送不同的波,通过接收到的波的信号不同,则可以区分出充电桩的位置。我手拙花了个简单示意图。
只有机器人上的接收头朝向充电桩的时候,两个接收头才能分别都接收到两个发射头的信号,否则根据情况旋转机器人朝向充电桩即可。
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; } }
总结
通过以上的设计和代码实现,我们可以通过红外线实现机器人自动回充。这个方法的原理和实现都相对简单,但实际应用时需要根据环境进行调试和优化,希望这篇文章能对大家有所帮助。如果有任何问题或者建议,欢迎在评论区留言,我们一起探讨学习。