麦轮小车

—— 如何造一辆可遥控的麦克纳姆轮小车。

嵌入式系统的课程要求我们设计小车底盘,于是我造了一辆麦克纳姆轮的小车。


原理#

麦克纳姆轮:

麦轮驱动的特点是可以全方向平滑移动,适应狭小/不利转弯的地形;缺点是功率损耗大、贵、加工难、维护麻烦,寿命也相较短。

转向原理:

元件清单#

名称参考链接
麦克纳姆轮小车底盘(带 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 手柄遥控。

总结#

小车总体能实现基本功能,但蓝牙的遥控有距离限制,也无法做得相对平滑。靠以后的算法慢慢优化了。

参考与致谢#



文章作者:Power Lin
原文地址:https://wiki-power.com
版权声明:文章采用 CC BY-NC-SA 4.0 协议,转载请注明出处。

Last updated on