实验器材
· 组装好的机器人;
· 计算机及编程环境;
·USB 下载线;
· 复眼传感器1个;
· 带桨叶的直流小电机1个;
· 继 电 器 1 个 ;
· 微触开关传感器1个。
实验步骤
这次实验需要为机器人在D3 端口安装一个微触开关传感器,在D2 端口上装上一个 继电器,并且通过它驱动一个直流小电机。同时,摩登7将复眼传感器连接到A0~A4 端 口。在安装复眼传感器的时候请同学们小心接线的顺序,它与摩登7其他的传感器、执行器 稍有不同,虽然占用了5个端口,但是只要为它连接一根+5V的电源线和一根地线就可 以了。
先编写程序,每按下一次微触开关,就让风扇的状态变化一次。比如,如果风扇正 在旋转,那么按下一次开关,就让它立刻停止,反之亦然。对于如何读取微触开关传感器 的状态和如何通过继电器驱动风扇,同学们都应该了然于胸了。但是这里的程序和本书 一开始做过的开关小灯的程序还是有所不同的,摩登7可能需要对按动微触开关的次数进 行计数,才能知道什么时候该驱动风扇转动,什么时候该让它停止。下面给出了一个示例 程序,请大家留意其中是如何处理微触开关的计数的。
const int FanPort=2;
const int SwitchPort=3;
int counter=0;
void setup(){
pinMode(FanPort, OUTPUT);
pinMode(SwitchPort,INPUT);
void loop(){
if(digitalRead(SwitchPort)==HIGH){ counter++;
}
if(counter %2==0){
digitalWrite(FanPort,LOW);
}else(
digitalWrite(FanPort,HIGH);
}
delay(200);
在这个示例程序中,每次按下微触开关就让一个计数变量自动增1。然后,摩登7用了 一个取模的运算“%”,在这里,counter%2 的结果就是这个计数变量除以2的余数是多 少。显然,如果余数是0,那么计数变量就是偶数,否则就是奇数。之后的内容就很直观 了,奇数时摩登7让风扇转动,偶数时停止就可以了。
这个示例看起来似乎很出色,可是实际上这里有一个很大的问题,如果同学们按动按 键的时候有一个很小的抖动,那么会不会被主控器认为是按了两次呢?或者如果按下按 键的时间比较长,是不是也会被认为按了多次?幸运的是,摩登7可以用软件的方法解决这 种抖动或按键时间过长的问题,请同学们自己尝试设计一个改进的算法,让开关能出色地 控制风扇的运行。
解决了风扇的问题,再来看看如何利用复眼传感器找到火源。这个问题可以说是到 目前为止面对的Z富挑战性的问题了,机器人需要在灭火的场地内以合理的方式探索寻 找火源的所在,并且运动到火源近前,它涉及机器人的灭火策略、路径规划、运动控制等多 方面的问题。 但同学们不要畏难,还记得摩登7讲过的分而治之、简化问题的思想吗?这里就先将这 个问题简化。假设现在已经有一个火源就在机器人的探测范围内。摩登7要让机器人的行 为就像是一朵向日葵一样,它需要找到火源的方向并且原地转动,直到复眼中正对前方的 那一只眼睛正对火源方向为止,如图13-5所示。
要解决这个简化的问题,需要对复眼的5个读数进行比较,找到信号Z强的方向应该 就是火源的方向了。随后就可以让机器人根据火源方向的不同,进行速度不同的原地转动。如果火源在Z靠外的位置就可以转得快些,靠内就转得慢些,如果已经是在正中了就 可以停止转动了。假设复眼传感器从左到右分别连接到了主控板的A0~A4 端口,下面 给出了让机器人寻找火源的示例程序,请同学们留意其中是怎么找到Z强信号位置的。
#define COUNTER_CLOCKWISE 0
#define CLOCKWISE 1
…
void turn(int speed,int dir);
void loop(){
int maxValue=0;
int maxPort=A0;
int value;
for(int i=A0;int i
maxPort=i;
}
if(maxPort==A0){
turn(120,CLOCKWISE);
}else if(maxPort==A1){
turn(80,CLOCKWISE);
}else if(maxPort==A2){
turn(0,CLOCKWISE);
}else if(maxPort==A3){
turn(80,COUNTER_CLOCKWISE); }else if(maxPort==A4){
turn(120,COUNTER_CLOCKWISE); }else{
turn(0,CLOCKWISE); }
delay(100);
}
void turn(int speed,int dir){
analogWrite(LeftSpeedPort,speed);
analogWrite(RightSpeedPort,speed);
if(dir==CLOCK){
digitalWrite(LeftDirPort,HIGH); digitalWrite(RightDirPort,LOW);
}else(
digitalWrite(LeftDirPort,LOW);
digitalWrite(RightDirPort,HIGH);
![]() |
| 机器人底盘 Disinfection Robot 消毒机器人 讲解机器人 迎宾机器人 移动机器人底盘 商用机器人 智能垃圾站 智能服务机器人 大屏机器人 雾化消毒机器人 展厅机器人 服务机器人底盘 具身智能教育机器人 智能配送机器人 导览机器人 |