第一个Arduino小车
这个小车很简单,超声波测量前方距离,Arduino 根据超声波模块接受的距离控制小车前进、后退或者左转右转。也就是说它有自己的“思维”方式,只要打开电源在没有人干预的情况下可以独自在房间里闲逛而不会碰到任何东西。
先来个视频:
相机光圈调大了~~ 只能看个效果,详细接线方式可能看不清楚,呵。。
如果你也对这个有兴趣那么可以和我一起来制作这样一个ROBOT。
材料准备:
1、arduino 板子一个,我使用的是 arduino duemilanove 2009 - ATMega328P,因为我觉得这个性价比最高。Arduino UNO 也可以。
2、 超声波测距模块一个
3、 直流电机 + 轮胎
4、 L298N电机驱动模块 一个 电机驱动最好带光耦的,否则可能会对超声波信号产生干扰
5、万向轮 + 小车底盘 + 杜邦线 + 螺丝、螺母 + 烙铁 + 螺丝刀 + 剪刀等
万向轮可以去淘宝购买
小车底盘是用来固定电机和电路板的,可以选用PVC板自己动手制作也可以买现成的
材料都有了就可以将它们链接起来。接线方式可以从程序的注释中看出来,本来准备用舵机控制超声波模块转向的,后来觉得舵机固定比较麻烦就没用,android程序如下:
#define DEBUG 0 // set to 1 to print to serial monitor, 0 to disable
#include <Servo.h>
Servo headservo; // 头部舵机对象
// Constants
const int EchoPin = 2; //超声波信号输入
const int TrigPin = 3; //超声波控制信号输出
const int leftmotorpin1 = 4; // 直流电机信号输出
const int leftmotorpin2 = 5;
const int rightmotorpin1 = 6;
const int rightmotorpin2 = 7;
const int HeadServopin = 9; // 舵机信号输出 只有9或10接口可利用
const int Sharppin = 11; // 红外输入
const int maxStart = 800; //run dec time
// Variables
int isStart = maxStart; //启动
int currDist = 0; // 距离
boolean running = false;
void setup() {
Serial.begin(9600); // 开始串行监测
//信号输入接口
pinMode(EchoPin, INPUT);
pinMode(Sharppin, INPUT);
//信号输出接口
for (int pinindex = 3; pinindex < 11; pinindex++) {
pinMode(pinindex, OUTPUT); // set pins 3 to 10 as outputs
}
//舵机接口
headservo.attach(HeadServopin);
//启动缓冲活动头部
headservo.write(70);
delay(2000);
headservo.write(20);
delay(2000);
}
void loop() {
if(DEBUG){
Serial.print("running:");
if(running){
Serial.println("true");
}
else{
Serial.println("false");
}
}
if (isStart <= 0) {
if(running){
totalhalt(); // stop!
}
int findsomebody = digitalRead(Sharppin);
if(DEBUG){
Serial.print("findsomebody:");
Serial.println(findsomebody);
}
if(findsomebody > 0) {
isStart = maxStart;
}
delay(4000);
return;
}
isStart--;
delay(100);
if(DEBUG){
Serial.print("isStart: ");
Serial.println(isStart);
}
currDist = MeasuringDistance(); //读取前端距离
if(DEBUG){
Serial.print("Current Distance: ");
Serial.println(currDist);
}
if(currDist > 30) {
nodanger();
}
else if(currDist < 15){
backup();
randTrun();
}
else {
//whichway();
randTrun();
}
}
//测量距离 单位厘米
long MeasuringDistance() {
long duration;
//pinMode(TrigPin, OUTPUT);
digitalWrite(TrigPin, LOW);
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(5);
digitalWrite(TrigPin, LOW);
//pinMode(EchoPin, INPUT);
duration = pulseIn(EchoPin, HIGH);
return duration / 29 / 2;
}
// 前进
void nodanger() {
running = true;
digitalWrite(leftmotorpin1, LOW);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, LOW);
digitalWrite(rightmotorpin2, HIGH);
return;
}
//后退
void backup() {
running = true;
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, LOW);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, LOW);
delay(1000);
}
//选择路线
void whichway() {
running = true;
totalhalt(); // first stop!
headservo.write(20);
delay(1000);
int lDist = MeasuringDistance(); // check left distance
totalhalt(); // 恢复探测头
headservo.write(120); // turn the servo right
delay(1000);
int rDist = MeasuringDistance(); // check right distance
totalhalt(); // 恢复探测头
if(lDist < rDist) {
body_lturn();
}
else{
body_rturn();
}
return;
}
//重新机械调整到初始状态
void totalhalt() {
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, HIGH);
headservo.write(70); // set servo to face forward
running = false;
return;
delay(1000);
}
//左转
void body_lturn() {
running = true;
digitalWrite(leftmotorpin1, LOW);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, LOW);
delay(1500);
totalhalt();
}
//右转
void body_rturn() {
running = true;
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, LOW);
digitalWrite(rightmotorpin1, LOW);
digitalWrite(rightmotorpin2, HIGH);
delay(1500);
totalhalt();
}
void randTrun(){
long randNumber;
randomSeed(analogRead(0));
randNumber = random(0, 10);
if(randNumber > 5) {
body_rturn();
}
else
{
body_lturn();
}
#include <Servo.h>
Servo headservo; // 头部舵机对象
// Constants
const int EchoPin = 2; //超声波信号输入
const int TrigPin = 3; //超声波控制信号输出
const int leftmotorpin1 = 4; // 直流电机信号输出
const int leftmotorpin2 = 5;
const int rightmotorpin1 = 6;
const int rightmotorpin2 = 7;
const int HeadServopin = 9; // 舵机信号输出 只有9或10接口可利用
const int Sharppin = 11; // 红外输入
const int maxStart = 800; //run dec time
// Variables
int isStart = maxStart; //启动
int currDist = 0; // 距离
boolean running = false;
void setup() {
Serial.begin(9600); // 开始串行监测
//信号输入接口
pinMode(EchoPin, INPUT);
pinMode(Sharppin, INPUT);
//信号输出接口
for (int pinindex = 3; pinindex < 11; pinindex++) {
pinMode(pinindex, OUTPUT); // set pins 3 to 10 as outputs
}
//舵机接口
headservo.attach(HeadServopin);
//启动缓冲活动头部
headservo.write(70);
delay(2000);
headservo.write(20);
delay(2000);
}
void loop() {
if(DEBUG){
Serial.print("running:");
if(running){
Serial.println("true");
}
else{
Serial.println("false");
}
}
if (isStart <= 0) {
if(running){
totalhalt(); // stop!
}
int findsomebody = digitalRead(Sharppin);
if(DEBUG){
Serial.print("findsomebody:");
Serial.println(findsomebody);
}
if(findsomebody > 0) {
isStart = maxStart;
}
delay(4000);
return;
}
isStart--;
delay(100);
if(DEBUG){
Serial.print("isStart: ");
Serial.println(isStart);
}
currDist = MeasuringDistance(); //读取前端距离
if(DEBUG){
Serial.print("Current Distance: ");
Serial.println(currDist);
}
if(currDist > 30) {
nodanger();
}
else if(currDist < 15){
backup();
randTrun();
}
else {
//whichway();
randTrun();
}
}
//测量距离 单位厘米
long MeasuringDistance() {
long duration;
//pinMode(TrigPin, OUTPUT);
digitalWrite(TrigPin, LOW);
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(5);
digitalWrite(TrigPin, LOW);
//pinMode(EchoPin, INPUT);
duration = pulseIn(EchoPin, HIGH);
return duration / 29 / 2;
}
// 前进
void nodanger() {
running = true;
digitalWrite(leftmotorpin1, LOW);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, LOW);
digitalWrite(rightmotorpin2, HIGH);
return;
}
//后退
void backup() {
running = true;
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, LOW);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, LOW);
delay(1000);
}
//选择路线
void whichway() {
running = true;
totalhalt(); // first stop!
headservo.write(20);
delay(1000);
int lDist = MeasuringDistance(); // check left distance
totalhalt(); // 恢复探测头
headservo.write(120); // turn the servo right
delay(1000);
int rDist = MeasuringDistance(); // check right distance
totalhalt(); // 恢复探测头
if(lDist < rDist) {
body_lturn();
}
else{
body_rturn();
}
return;
}
//重新机械调整到初始状态
void totalhalt() {
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, HIGH);
headservo.write(70); // set servo to face forward
running = false;
return;
delay(1000);
}
//左转
void body_lturn() {
running = true;
digitalWrite(leftmotorpin1, LOW);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, LOW);
delay(1500);
totalhalt();
}
//右转
void body_rturn() {
running = true;
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, LOW);
digitalWrite(rightmotorpin1, LOW);
digitalWrite(rightmotorpin2, HIGH);
delay(1500);
totalhalt();
}
void randTrun(){
long randNumber;
randomSeed(analogRead(0));
randNumber = random(0, 10);
if(randNumber > 5) {
body_rturn();
}
else
{
body_lturn();
}
}