麦轮小车
—— 如何造一辆可遥控的麦克纳姆轮小车。
嵌入式系统的课程要求我们设计小车底盘,于是我造了一辆麦克纳姆轮的小车。
原理
麦克纳姆轮:
麦轮驱动的特点是可以全方向平滑移动,适应狭小/不利转弯的地形;缺点是功率损耗大、贵、加工难、维护麻烦,寿命也相较短。
转向原理:
元件清单
名称 | 参考链接 |
---|---|
麦克纳姆轮小车底盘(带 TT 电机) | 链接 |
Arduino UNO | 无 |
L293D 电机驱动 | 无 |
HC-06 蓝牙 | 无 |
9g 舵机 | 无 |
HC-SR04 超声波 | 无 |
11.1V 锂电池 | 无 |
代码实现
小车主控用的是 Arduino UNO.
项目文件:My-Arduino-projects / 麦轮小车
L293D 库文件:AFMotor.rar
代码:
//by YX Lin
#include <AFMotor.h> //L293D 驱动库文件
#include <Servo.h>//舵机库文件
#define SR04_Trig 11
#define SR04_Echo 12
int distance = 0;
int delay_time = 300;
int micro_delay_time = 100;
int pos = 0;
int motor_speed = 200;
AF_DCMotor motor1(1);
AF_DCMotor motor2(4);
AF_DCMotor motor3(3);
AF_DCMotor motor4(2);
Servo myservo;
void setup() {
Serial.begin(9600);
myservo.attach(2);
motor1.setSpeed(motor_speed);
motor2.setSpeed(motor_speed);
motor3.setSpeed(motor_speed);
motor4.setSpeed(motor_speed);
pinMode(SR04_Trig, OUTPUT);
pinMode(SR04_Echo, INPUT);
//serve();
}
void loop() {
if (Serial.available()) {
Serial.println("Hello");
char x = Serial.read();
if (x == 'W') move_forward();
if (x == 'S') move_backward();
if (x == 'D') move_right();
if (x == 'A') move_left();
if (x == 'E') right_front();
if (x == 'Q') left_front();
if (x == 'C') rotate_right();
if (x == 'Z') rotate_left();
if (x == 'X') off();
if (x == 'F') serve();
if (x == 'V')sr04(); //超声波测距
Serial.println("ok");
}
delay(5);
}
void move_forward() {
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
delay(delay_time);
off();
}
void move_backward() {
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor3.run(BACKWARD);
motor4.run(BACKWARD);
delay(delay_time);
off();
}
void move_right() {
motor1.run(FORWARD);
motor2.run(BACKWARD);
motor3.run(FORWARD);
motor4.run(BACKWARD);
delay(delay_time);
off();
}
void move_left() {
motor1.run(BACKWARD);
motor2.run(FORWARD);
motor3.run(BACKWARD);
motor4.run(FORWARD);
delay(delay_time);
off();
}
void right_front() {
motor1.run(FORWARD);
motor2.run(RELEASE);
motor3.run(FORWARD);
motor4.run(RELEASE);
delay(delay_time);
off();
}
void left_front() {
motor1.run(RELEASE);
motor2.run(FORWARD);
motor3.run(RELEASE);
motor4.run(FORWARD);
delay(delay_time);
off();
}
void rotate_right() {
motor1.run(FORWARD);
motor2.run(BACKWARD);
motor3.run(BACKWARD);
motor4.run(FORWARD);
delay(micro_delay_time);
off();
}
void rotate_left() {
motor1.run(BACKWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(BACKWARD);
delay(micro_delay_time);
off();
}
void off() {
motor1.run(RELEASE);
motor2.run(RELEASE);
motor3.run(RELEASE);
motor4.run(RELEASE);
}
void serve() {
for (pos = 0; pos <= 180; pos += 5) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 5) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
void sr04() {
digitalWrite(SR04_Trig, LOW); //给 Trig 发送一个低电平
delayMicroseconds(2); //等待 2 微妙
digitalWrite(SR04_Trig, HIGH); //给 Trig 发送一个高电平
delayMicroseconds(10); //等待 10 微妙
digitalWrite(SR04_Trig, LOW); //给 Trig 发送一个低电平
distance = ((float(pulseIn(SR04_Echo, HIGH)) * 17 ) / 100); //把回波时间换算成毫米,并减去距离差值
if (distance < 9999 && distance > 0) {
Serial.print("测距:");
Serial.println(distance);
} else {
Serial.println("距离过大");
}
}
蓝牙遥控:下载 Arduino bluetooth controller 这个 App,按代码设置相应的键位,就可以遥控了。
FAQ
Q:项目后期有跟进吗? A:有,我打算寒假把代码移植到 STM32 上面,并实现用 PS2 手柄遥控。
总结
小车总体能实现基本功能,但蓝牙的遥控有距离限制,也无法做得相对平滑。靠以后的算法慢慢优化了。
参考与致谢
原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。