馬達驅動模組接線 L298N
|
|
L298N
|
Arduino
|
ENA
|
~6
|
IN1
|
7
|
IN2
|
8
|
IN3
|
12
|
IN4
|
13
|
ENB
|
~11
|
OUT1
|
右馬達 紅線
|
OUT2
|
右馬達 黑線
|
OUT3
|
左馬達 黑線
|
OUT4
|
左馬達 紅線
|
VCC
|
外接 9V方型電池 正極
|
GND
|
外接 9V方型電池 負極
及 Arduino GND
|
伺服馬達接線
|
|
伺服馬達
|
Arduino
|
棕色線
|
GND
|
紅色線
|
5V
|
黃色線
|
~9
|
超音波模組接線
|
|
超音波
|
Arduino
|
Vcc
|
5V
|
Trig
|
4
|
Echo
|
~5
|
GND
|
GND
|
接線完成後,首先來處理自走車的馬達程式
馬達轉向控制表
|
||||||
輪子
|
L298N
|
前進
|
後退
|
左轉
|
右轉
|
停止
|
右輪
|
IN1
|
LOW
|
HIGH
|
LOW
|
||
IN2
|
HIGH
|
LOW
|
LOW
|
|||
左輪
|
IN3
|
LOW
|
HIGH
|
LOW
|
||
IN4
|
HIGH
|
LOW
|
LOW
|
利用 digitalWrite(腳位 , HIGH or LOW ) 可以控制高低電位,自走車前進時程式寫法如下:
//右輪馬達
digitalWrite(In1,LOW);digitalWrite(In2,HIGH);
// 左輪馬達
digitalWrite(In3,LOW);
digitalWrite(In4,HIGH);
此外自走車轉彎的方式有幾種方式,例如當右輪往前進,左輪後退時可以達到快速左轉
//右輪馬達 往前
digitalWrite(In1,LOW);digitalWrite(In2,HIGH);
// 左輪馬達 往後
digitalWrite(In3,HIGH);
digitalWrite(In4,LOW);
也可以透過改變左右兩輪行進的速度,控制自走車逐漸改變行進方向,比如自走車在前進狀態時,左輪轉速 小於右輪時,自走車會逐漸左轉彎.
analogWrite(ENA,rightSpeed)
;
analogWrite(ENB,leftSpeed) ;
避障自走車的運作邏輯說明如下,自走車往前進,超音波感測器隨時偵測前方路況,當偵測到前方30cm前有障礙物時,自走車停止,伺服馬達向右轉,偵測右方再向左轉偵測左方.
若是右方障礙物較遠,自走車往右轉,若左方障礙物較遠,自走車往左轉,如果前方,右方,左方30cm內都有障礙物,自走車會先後退,再右轉.
/* motoTest04
* 馬達測試程式 第四版 測試 OKanalogWrite(ENB,leftSpeed) ;
* 功能: 前進 後退 右轉彎 左轉彎 停止 避障功能,
* 前方30cm有障礙物,車子停止,偵測兩方路況,決定左轉彎或是右轉彎
* *
* 改進:轉彎弧度與馬力輸出設定調整到兩輪能直線前進
*/
#include <Servo.h>
#define In1 7 //右馬達
#define In2 8
#define ENA 6
#define In3 12 //左馬達
#define In4 13
#define ENB 11
#define trigPin 4 // 超音波Pin
#define echoPin 5
#define servoPin 9 // 伺服馬達 Pin
unsigned long d // 前方障礙物距離
const int leftSpeed = 115 ; //左輪轉速,經過實際測試,若左右輪轉速相同時,自走車無法走直線. P
const int rightSpeed =135; //右輪轉速
Servo servo ;
void setup() {
// put your setup code here, to run once:
//馬達腳位設定
pinMode(In1,OUTPUT); //右馬達
pinMode(In2,OUTPUT);
pinMode(In3,OUTPUT); //左馬達
pinMode(In4,OUTPUT);
pinMode(ENA,OUTPUT);
pinMode(ENB,OUTPUT);
// 超音波腳位設定
pinMode(trigPin,OUTPUT) ;
pinMode(echoPin,INPUT) ;
//超音波初始化
servo.attach(servoPin) ;
servo.write(85) ; //因為組裝的緣故,經測試,伺服馬達在85度時方能在正前方
delay(1000) ;
forward(); //自走車開始前進
}
// 超音波距離偵測,傳回 cm
unsigned long ping_d() {
digitalWrite(trigPin,HIGH) ;
delayMicroseconds(1000) ;
digitalWrite(trigPin,LOW);
return ( pulseIn(echoPin,HIGH)/58) ;
}
// 後退函數 ok
void backward() {
// 右馬達
digitalWrite(In1,HIGH);
digitalWrite(In2,LOW);
analogWrite(ENA,rightSpeed) ;
// 左馬達
digitalWrite(In3,HIGH);
digitalWrite(In4,LOW);
analogWrite(ENB,leftSpeed) ;
}
// 前進函數 OK
void forward() {
// 右馬達
digitalWrite(In1,LOW);
digitalWrite(In2,HIGH);
analogWrite(ENA,rightSpeed) ;
// 左馬達
digitalWrite(In3,LOW);
digitalWrite(In4,HIGH);
analogWrite(ENB,leftSpeed) ;
}
// 左轉彎函數 turnLeft ok
void turnLeft(){
// 右馬達 前進
digitalWrite(In1,LOW);
digitalWrite(In2,HIGH);
analogWrite(ENA,rightSpeed) ;
// 左馬達 後退
digitalWrite(In3,HIGH);
digitalWrite(In4,LOW);
analogWrite(ENB,leftSpeed) ;
}
// 右轉彎函數 turnRight ok
void turnRight(){
// 右馬達 前進
digitalWrite(In1,HIGH);
digitalWrite(In2,LOW);
analogWrite(ENA,rightSpeed) ;
// 左馬達 後退
digitalWrite(In3,LOW);
digitalWrite(In4,HIGH);
analogWrite(ENB,leftSpeed) ;
}
//停止函數 OK
void motoStop(){
// 右馬達 前進
digitalWrite(In1,LOW);
digitalWrite(In2,LOW);
analogWrite(ENA,rightSpeed) ;
// 左馬達 後退
digitalWrite(In3,LOW);
digitalWrite(In4,LOW);
analogWrite(ENB,leftSpeed) ;
}
void loop() {
// put your main code here, to run repeatedly:
int left_d, right_d ; //紀錄左,右邊障礙物距離
d = ping_d() ; //偵測前方障礙物距離
// 如果前方30cm處有障礙物,自走車需要進入判斷模式,決定行進方式
if( d<=30) {
motoStop() ; //自走車停止前進
servo.write(20) ; // 伺服馬達轉向右邊
delay(500) ;
right_d = ping_d() ; // 取得右邊障礙物距離
delay(20) ;
servo.write(150) ; // 伺服馬達轉向左邊
delay(500) ;
left_d = ping_d() ; // 取得左邊障礙物的距離
servo.write(85) ; // 轉動伺服馬達,使超音波回到正前方
// 如果左邊空間大 且 障礙物距離超過30cm以上 ---> 左轉彎後繼續前進
if( (left_d>right_d) && (left_d>30)) { //左邊有空間
turnLeft() ;
delay(350) ;
forward() ;
} else if( (right_d>=left_d) && (right_d>30)) { // 右邊空間大且右邊障礙物距離大於30cm以上 -->右轉彎後前進
turnRight() ;
delay(350) ;
forward() ;
} else { // 前,左,右障礙物距離都小於30公分 --->後退->轉彎->前進
backward() ;
delay(1500) ;
turnRight() ;
delay(350) ;
forward() ;
}
} // end if d<=30
delay(30) ;
}