一. 简介
想去偷窥一下小伙伴们在干嘛,又懒得起身怎么办?有了这个履带摄像头小车就没问题了,它让你有了另外一双眼睛!
你还可以用这个小车来探测一些人无法到达的地方,比如,探测下火星表面什么的。
这个机器人底部用的是Devastator 履带机器人。使用这个机器人平台配上Romeo BLE 控制板,可以轻易使它前进、后退以及转向。小车有多种控制方法,这里我们选择用手机软件GoBLE 来控制。
履带机器人的上方我们装上了一个云台(由舵机控制),它可以用来控制摄像头的左右转向。云台上方还装有一个舵机,这个是用来控制摄像头的上下转动。这个舵机上方固定着摄像头。 这个摄像头(SEN0022)可以用蓝牙传输视频信息到电脑,然后视频就可以直接在电脑上观看了。
二. 连接
1.左边电机连到Romeo BLE的电机控制M2,右边电机连到M1。(注意分清正负线) 2.Romeo BLE上电机控制口旁的电源口是专门用来给电机供电的。连接前先将上面的开关调到OFF,然后把电池连到这个口。 3.把云台的线连到数字口8。 4.把上面的舵机的线连到数字口9。 5.把摄像头装在舵机支架上,也给它连上电源。 6.把摄像头自带的蓝牙接收器连接到电脑上。
三. 程序
参考代码:
- #include <Servo.h>
- #include <Metro.h>
- #include "GoBLE.h"
-
- int speedPin_M1 = 5; //电机1速度控制 M1 Speed Control
- int speedPin_M2 = 6; //电机2速度控制 M2 Speed Control
- int directionPin_M1 = 4; //电机1方向控制 M1 Direction Control
- int directionPin_M2 = 7; //电机2方向控制 M1 Direction Control
-
- Servo base; //云台 base platform servo
- Servo top; //上层舵机 top servo
-
- int basePosition = 90; // 云台起始位置:90,右转:-,左转:+ base servo forward: 90, turn right: -, turn left: +
- int topPosition = 115; // 上层舵机起始位置:115,前倾:-,后仰:+ top servo straight: 115, turn forward: -, turn backward: +
-
- int joystickX, joystickY;
- int buttonState[5];
-
- void setup() {
- Goble.begin(); //启动GoBLE
- Serial.begin(115200);
- top.attach(9); // Top Servo– Digital 9
- base.attach(8); // Base Servo - Digital 8
- top.write(topPosition); //写入起始角度
- base.write(basePosition); //写入起始角度
-
- }
-
- void loop() {
-
- if (Goble.available()) {
-
- joystickX = Goble.readJoystickX();
- joystickY = Goble.readJoystickY();
-
- buttonState[SWITCH_UP] = Goble.readSwitchUp();
- buttonState[SWITCH_DOWN] = Goble.readSwitchDown();
- buttonState[SWITCH_LEFT] = Goble.readSwitchLeft();
- buttonState[SWITCH_RIGHT] = Goble.readSwitchRight();
-
- // Serial.print("Joystick Value: ");
- // Serial.print(joystickX);
- // Serial.print(" ");
- // Serial.println(joystickY);
-
- if (joystickY > 196) {
- Serial.println("turn right");
- carTurnRight(250, 250);
- }
- else if (joystickY < 64) {
- Serial.println("turn left");
- carTurnLeft(250, 250);
- }
- else if (joystickX > 196) {
- Serial.println("move forward");
- carAdvance(500, 500);
- }
- else if (joystickX < 64) {
- Serial.println("move backward");
- carBack(500, 500);
- }
- else {
- carStop();
- }
-
- if (buttonState[SWITCH_LEFT] == PRESSED &&
- buttonState[SWITCH_RIGHT] == RELEASED) {
- Serial.println("servo left");
- Serial.println(basePosition);
- basePosition += 5;
- if (basePosition >= 180) {
- basePosition = 180;
- }
- }
- else if (buttonState[SWITCH_RIGHT] == PRESSED &&
- buttonState[SWITCH_LEFT] == RELEASED) {
- Serial.println("servo right");
- Serial.println(basePosition);
- basePosition -= 5;
- if (basePosition <= 0) {
- basePosition = 0;
- }
- }
- else if (buttonState[SWITCH_UP] == PRESSED &&
- buttonState[SWITCH_DOWN] == RELEASED) {
- Serial.println("servo forward");
- Serial.println(topPosition);
- topPosition -= 5;
- if (topPosition <= 70) {
- topPosition = 75;
- }
- }
- else if (buttonState[SWITCH_DOWN] == PRESSED &&
- buttonState[SWITCH_UP] == RELEASED) {
- Serial.println("servo back");
- Serial.println(topPosition);
- topPosition += 5;
- if (topPosition >= 160) {
- topPosition = 155;
- }
- }
- top.write(topPosition);
- base.write(basePosition);
- }
-
- }
-
- void carStop() { // Motor Stop
- digitalWrite(speedPin_M2, 0);
- digitalWrite(directionPin_M1, LOW);
- digitalWrite(speedPin_M1, 0);
- digitalWrite(directionPin_M2, LOW);
- }
-
- void carTurnLeft(int leftSpeed, int rightSpeed) { //Turn Left
- analogWrite (speedPin_M2, leftSpeed); //PWM Speed Control
- digitalWrite(directionPin_M1, HIGH);
- analogWrite (speedPin_M1, rightSpeed);
- digitalWrite(directionPin_M2, LOW);
- }
-
- void carTurnRight(int leftSpeed, int rightSpeed) { //Turn Right
- analogWrite (speedPin_M2, leftSpeed);
- digitalWrite(directionPin_M1, LOW);
- analogWrite (speedPin_M1, rightSpeed);
- digitalWrite(directionPin_M2, HIGH);
- }
-
- void carBack(int leftSpeed, int rightSpeed) { //Move backward
- analogWrite (speedPin_M2, leftSpeed);
- digitalWrite(directionPin_M1, LOW);
- analogWrite (speedPin_M1, rightSpeed);
- digitalWrite(directionPin_M2, LOW);
- }
- void carAdvance(int leftSpeed, int rightSpeed) { //Move forward
- analogWrite (speedPin_M2, leftSpeed);
- digitalWrite(directionPin_M1, HIGH);
- analogWrite (speedPin_M1, rightSpeed);
- digitalWrite(directionPin_M2, HIGH);
- }
复制代码
代码分析:
GoBLE.h和Metro.h这两个库可以在这里下载:
全局变量和Setup()函数里主要是设置电机、舵机和GoBLE。 说下这两行: int basePosition = 90; int topPosition = 115; 控制摄像头方向的舵机是由角度控制的。通过测试得出上下两个舵机起始位置分别是115和90。如果安装方法有差异的话这两个数字也可能是不一样的。
Loop()函数里面,我们先检测GoBLE的蓝牙信号,并读取遥杆和按钮的数据。在GoBLE中,我们用遥杆来控制小车的移动,用按钮来控制摄像头的方向。 遥杆方面,Y指代的是横向方向,X指代的是竖轴方向。数值都是0到255。我们用64和196这两个数字为界限来判断是否让小车移动或转弯。 按钮方面,上和下用来控制摄像头的前倾和后仰,左和右用来控制左右转向。每次按钮改变的角度是5度,但上舵机角度要保证在75到155之间,下舵机角度要保证在0到180之间。
最后还提供了小车的前进、后退、左转、右转、停止这5个函数。它们都是通过控制两个电机的速度控制口和方向控制口来控制小车的移动的。
四. 视频传输
从这里下载VIDEOVIEW软件: https://www.filewatcher.com/m/VIDEOVIEW.EXE.221184-0.html(链接已失效) 确保蓝牙接收器已经连在电脑上。打开VIDEOVIEW,在Devices找到插上的蓝牙设备,我们就可以看到摄像头传来的图像了。
控制效果视频
|