這個小車很簡單,超聲波測量前方距離,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();
}
}
