yaboPP电子
项目

如何建立一个机器人测试硬件

2015年11月3日,通过特拉维斯Fagerness

本系列文章的第3部分介绍了如何制造可以沿着直线或墙壁行走并避开障碍物的机器人!

本系列文章的第3部分介绍了如何制造可以沿着直线或墙壁行走并避开障碍物的机器人!

相关文章

如何制造机器人:

第1部分:设计和原理图

第2部分:PCB设计

第4部分:行追随者

第5部分:避免障碍

第6部分:沿墙走机器人

概述

本文是关于我建造一个能做各种事情的机器人的经验的系列文章的第3部分。我认为这将是灵巧的创造一个机器人,很容易与一个焊接烙铁组装,也负担得起。我对我的机器人的要求如下:

  • 很多套件都很贵,所以它一定相对便宜。
  • 它必须容易组装,不需要特殊设备。
  • 它必须易于编程,没有复杂的IDE或程序员。
  • 它必须足够强大,具有可扩展性。
  • 应该只用一个简单的电源。
  • 它应该能够沿着一条线或一堵墙,并避开障碍物。

在本文中,我将讨论如何组装机器人和编写一个机器人库来测试各种电路。

收集组件

我订购了所有的组件,它们都在相当短的时间内到达。它们已经被摆放好,准备组装。

组装机械部件

球者

这个球轮是一个需要组装的工具。它提供了各种大小的选择。这并不太难,所以我没有拍摄任何装配过程的照片。

电动机

发动机也是作为一个套件来的,而且要复杂得多。马达套件提供4种不同的齿轮传动比。我最终选择了38:1作为最大的比例,因为我不想让机器人太慢,但仍然能够处理周围的重量。更高的传动比将是一个不必要的扭矩量。机器人唯一真正的重量是电池。齿轮传动比总是可以调整后组装,但这将是一个有点痛苦。电机转速可以通过改变电机控制器的PWM占空比来调整,所以如果齿轮传动比产生的转速过高,可以用软件降低。

这是套件中所有不同的部件。我用砧板组装,因为小螺丝有滚下桌子的习惯。

完全组装的机器人电机和齿轮。工具箱里有所有需要的东西,包括油脂。我唯一需要的工具就是一把螺丝刀。

附在PCB上,它实际上与丝网很好地对齐!

焊接的组件

我使用了女性头部,以防我想要在以后交换组件。焊接所有的男性头到DIP分离板是有点乏味,但比焊接所有表面安装组件要容易得多!我必须使用一堆头连接在一起,使线路传感器接近地面,以有效。如果我从头开始,我更喜欢一个更干净的方式安装线路传感器。

测试电机

起初,我只是把电机直接连接到2AA电池,看看齿轮是否适当润滑。我还测量了电流,以确保它是在规格。在证明电机可以正反转后,我将它们连接到电机驱动器。我写了一些测试软件让马达前后运行5秒钟。这一下子证明了小女孩、电机控制器和电机之间的联系。当您不需要在第一版PCB上排除连接故障时,这是一个令人愉快的结果!下面的代码以大约一半的功率驱动机器人向前5秒,然后向后5秒。我写了一个叫“机器人”的司机。“Ino”负责转弯和传感器读数。驱动程序见文章结尾。给小女孩编程,下载Teensyduino插件的Arduino平台。编程和使用Arduino完全一样。

在测试期间,我使用了一个跳线作为开关。

它还活着!

#include "robot.h" void setup() {Serial.begin(38400);以“引导”);rbt_init ();rbt_move(前轮驱动,100);延迟(5000);rbt_move(牧师,100);延迟(5000);rbt_move(刹车,0);} void loop() {}

Testing_Hardware_1.zip

测试传感器

为了测试传感器,我写了一个程序,打印传感器的原始值。我发现我不能同时使用墙壁上的传感器否则它们会100%激活。这样做的原因是,红外接收器有一个很宽的角度,它们从邻近的发射器接收信号。我编写了这个库,以便它利用传感器上的enable引脚交替读取每个传感器。墙壁上的传感器也必须稍微向上倾斜一点,否则它们会把地面作为一个物体。

传感器读取功能执行在1ms,提供1kHz的速度处理相当复杂的控制算法,如果需要。测试代码还表明,线传感器必须非常接近地面,以有效地确定颜色之间的差异。如果机器人离地面只有几英寸,线路传感器的最高读数为1000。这实际上可以让机器人在被携带时停止移动。

线传感器非常接近地面,但不接触!

#include "robot.h" void setup() {Serial.begin(38400);以“引导”);rbt_init ();} uint16_t lleft、lmid lright;布尔wleft wmid,怀特;Void loop() {rbt_sns(&lleft,&lmid,&lright,&wleft,&wmid,&wright);系列。打印(“左行:”);并同时lleft);系列。print("Line mid: "); Serial.print(lmid); Serial.print("Line right: "); Serial.print(lright); Serial.print("Wall left: "); Serial.print(wleft); Serial.print("Wall mid: "); Serial.print(wmid); Serial.print("Wall right: "); Serial.println(wright); }

Robot_Assembly_1.zip

结论

在这篇文章中,我展示了组装机器人和分别测试组件的过程。当你第一次得到电路板时,这是很重要的,因为你永远不知道在PCB的设计或制造中可能犯了什么错误。如果您直接进入应用程序设计,您可能会错过一些可能导致问题的东西。在下一篇文章中,我将讨论如何通过纠正一个简单的算法使机器人保持在黑线的中心,从而将机器人变成一个线跟踪者。

机器人图书馆

robot.h
#ifndef _ROBOT_H #define _ROBOT_H #include "Arduino.h" /*DRV8835*/ const int BPHASE = 5;const int phasase = 3;const int AEN = 4;const int BEN = 6;const int DRV_MODE = 2;#define MOTOR_REV LOW #define MOTOR_FWD HIGH /*反射传感器接口*/ const int OUT1 = 33;const int OUT2 = 32;const int OUT3 = 31;/*墙壁传感器接口*/ const int WALL_LEFT_EN = 15;const int WALL_LEFT = 14; const int WALL_RIGHT_EN = 19; const int WALL_RIGHT = 18; const int WALL_MID_EN = 17; const int WALL_MID = 16; /*robot interface*/ typedef enum{ LEFT, RIGHT, FWD, REV, BRAKE, }direction_t; void rbt_move(direction_t new_dir, uint8_t speed); void rbt_sns( uint16_t *line_left, uint16_t *line_mid, uint16_t *line_right, boolean *wall_left, boolean *wall_mid, boolean *wall_right); void rbt_init(); #endif /*_ROBOT_H*/

Robot_Assembly.zip

robot.ino
#include "robot.h" void rbt_init() {pinMode(BPHASE, OUTPUT);pinMode (APHASE、输出);pinMode(为、输出);pinMode(本、输出);pinMode (DRV_MODE、输出);pinMode (WALL_LEFT_EN、输出);pinMode (WALL_MID_EN、输出);pinMode (WALL_RIGHT_EN、输出);pinMode (WALL_LEFT、输入);pinMode (WALL_MID、输入); pinMode(WALL_RIGHT, INPUT); digitalWrite(WALL_LEFT_EN,LOW); digitalWrite(WALL_MID_EN,LOW); digitalWrite(WALL_RIGHT_EN,LOW); /*simplified drive mode*/ digitalWrite(DRV_MODE, HIGH); } void rbt_move(direction_t new_dir, uint8_t speed) { if(speed) { switch(new_dir){ case LEFT: digitalWrite(BPHASE,MOTOR_FWD); digitalWrite(APHASE,MOTOR_FWD); analogWrite(AEN,speed); analogWrite(BEN,speed-speed/2); break; case RIGHT: digitalWrite(BPHASE,MOTOR_FWD); digitalWrite(APHASE,MOTOR_FWD); analogWrite(AEN,speed-speed/2); analogWrite(BEN,speed); break; case FWD: digitalWrite(BPHASE,MOTOR_FWD); digitalWrite(APHASE,MOTOR_FWD); analogWrite(AEN,speed); analogWrite(BEN,speed); break; case REV: digitalWrite(BPHASE,MOTOR_REV); digitalWrite(APHASE,MOTOR_REV); analogWrite(AEN,speed); analogWrite(BEN,speed); break; default: analogWrite(AEN,0); analogWrite(BEN,0); break; } } else { analogWrite(AEN,0); analogWrite(BEN,0); } } /*function takes 1ms to run*/ #define LOOP_ITER_CNT 2 void rbt_sns( uint16_t *line_left, uint16_t *line_mid, uint16_t *line_right, boolean *wall_left, boolean *wall_mid, boolean *wall_right) { *line_left=0; *line_mid=0; *line_right=0; uint16_t usec_timer=0; /*line sensor*/ /*charge lines*/ pinMode(OUT1, OUTPUT); pinMode(OUT2, OUTPUT); pinMode(OUT3, OUTPUT); digitalWrite(OUT1,HIGH); digitalWrite(OUT2,HIGH); digitalWrite(OUT3,HIGH); delayMicroseconds(3); /*set to Hi-Z to let cap discharge*/ pinMode(OUT1, INPUT); pinMode(OUT2, INPUT); pinMode(OUT3, INPUT); /*enable first wall sensor*/ digitalWrite(WALL_LEFT_EN,HIGH); while(1){ /*each loop is about 2us at 48MHz*/ usec_timer+=LOOP_ITER_CNT; /*increment counts for line sensors every us to track the decay of the capacitor*/ if(digitalRead(OUT1) == 1) { (*line_left)+=LOOP_ITER_CNT; } if(digitalRead(OUT2) == 1) { (*line_mid)+=LOOP_ITER_CNT; } if(digitalRead(OUT3) == 1) { (*line_right)+=LOOP_ITER_CNT; } /*take turns reading wall sensors because they interfere with each other*/ if(usec_timer == 300) { *wall_left = (digitalRead(WALL_LEFT) ? false:true); digitalWrite(WALL_LEFT_EN,LOW); } if(usec_timer == 400) { digitalWrite(WALL_MID_EN,HIGH); } if(usec_timer == 700) { *wall_mid = (digitalRead(WALL_MID) ? false:true); digitalWrite(WALL_MID_EN,LOW); } if(usec_timer == 700) { digitalWrite(WALL_RIGHT_EN,HIGH); } if(usec_timer>=1000) { *wall_right = (digitalRead(WALL_RIGHT) ? false:true); digitalWrite(WALL_MID_EN,LOW); return; } } }

Robot_Assembly_2.zip

系列的下一篇文章:如何建立一个机器人-直线跟随器