關於紅外線(Infrared,IR)的通訊請參考上一篇學習文章:Ardunio:實作紅外線(Infrared,IR)代碼擷取。本篇的重點落在L289N電機驅動模組上。L298N是一種高電壓、大電流電機驅動晶片,採用15腳封裝。主要特點是工作電壓高,最高工作電壓可達46V;輸出電流大,瞬間峰值電流可達3A,持續工作電流為2A;額定功率25W。內含兩個H橋的高電壓大電流全橋式驅動器,可以用來驅動直流馬達和步進馬達、繼電器線圈等電感性負載。
使用L298N晶片驅動馬達,該晶片可以驅動一台兩相步進馬達或四相步進馬達,也可以驅動兩台直流馬達。本實作使用的L298N電機驅動模組是2路的H橋驅動,所以可以同時驅動兩個馬達。
車輛控制程式碼:
- 致能 ENA 之後,從IN1 IN2輸入PWM信號驅動馬達1的轉速和方向。
- 致能 ENB之後,可從IN3 IN4輸入PWM信號驅動馬達2的轉速和方向。
#include <IRremote.h> const int negR=4; const int posR=5; const int negL=6; const int posL=7; const int pwmR=9; const int pwmL=10; const int Rled=2; const int Lled=8; int Rspeed=200; int Lspeed=200; long FOR=0xFF18E7; long BACK=0xFF4AB5; long RIGHT=0xFF5AA5; long LEFT=0xFF10EF; long PAUSE=0xFF38C7; long key7=0xFF42BD; long key9=0xFF52AD; long AddSpeed=0xFFA857; long DecSpeed=0xFFE01F; int RECV_PIN = 3; // 使用數位腳位3接收紅外線訊號 IRrecv irrecv(RECV_PIN); // 初始化紅外線訊號輸入 decode_results results; // 儲存訊號 boolean status[2]={0,0}; const int led[2]={12,11}; int i; void setup() { pinMode(posR,OUTPUT); pinMode(negR,OUTPUT); pinMode(posL,OUTPUT); pinMode(negL,OUTPUT); pinMode(Rled,OUTPUT); pinMode(Lled,OUTPUT); pinMode(led[0],OUTPUT); pinMode(led[1],OUTPUT); digitalWrite(Rled,LOW); digitalWrite(Lled,LOW); for(i=0;i<2;i++) digitalWrite(led[i],LOW); irrecv.blink13(true); // 收到紅外線訊號腳位13的LED閃爍 irrecv.enableIRIn(); // 致能接收 } void loop() { if (irrecv.decode(&results)) // 開始紅外線訊號解碼 { irrecv.resume(); // 準備接收下一個訊號 if(results.value==FOR){ forward(Rspeed,Lspeed); digitalWrite(Rled,1); digitalWrite(Lled,1); } else if(results.value==BACK) back(Rspeed,Lspeed); else if(results.value==RIGHT) { right(Rspeed,Lspeed); status[1]=~status[1]; digitalWrite(Rled,1); } else if(results.value==LEFT) { left(Rspeed,Lspeed); status[0]=~status[0]; digitalWrite(Lled,1); } else if(results.value==PAUSE) { pause(0,0); for(i=0;i<2;i++) { status[i]=0; digitalWrite(led[i],1); } digitalWrite(Rled,LOW); digitalWrite(Lled,LOW); } //加速 else if(results.value==AddSpeed) { pause(0,0); if (Rspeed<300){ Rspeed=Rspeed+10; Lspeed=Lspeed+10; } } //減速 else if(results.value==DecSpeed) { pause(0,0); if (Rspeed>=150){ Rspeed=Rspeed-10; Lspeed=Lspeed-10; } } } for(i=0;i<2;i++) { if(status[i]!=0) { digitalWrite(led[i],HIGH); delay(200); digitalWrite(led[i],LOW); delay(200); } } } void forward(byte RmotorSpeed, byte LmotorSpeed) { analogWrite(pwmR,RmotorSpeed); analogWrite(pwmL,LmotorSpeed); digitalWrite(posR,HIGH); digitalWrite(negR,LOW); digitalWrite(posL,LOW); digitalWrite(negL,HIGH); } void back(byte RmotorSpeed, byte LmotorSpeed) { analogWrite(pwmR,RmotorSpeed); analogWrite(pwmL,LmotorSpeed); digitalWrite(posR,LOW); digitalWrite(negR,HIGH); digitalWrite(posL,HIGH); digitalWrite(negL,LOW); } void pause(byte RmotorSpeed, byte LmotorSpeed) { analogWrite(pwmR,RmotorSpeed); analogWrite(pwmL,LmotorSpeed); digitalWrite(posR,LOW); digitalWrite(negR,LOW); digitalWrite(posL,LOW); digitalWrite(negL,LOW); } void right(byte RmotorSpeed, byte LmotorSpeed) { analogWrite(pwmR,RmotorSpeed); analogWrite(pwmL,LmotorSpeed); digitalWrite(posR,LOW); digitalWrite(negR,LOW); digitalWrite(posL,LOW); digitalWrite(negL,HIGH); } void left(byte RmotorSpeed, byte LmotorSpeed) { analogWrite(pwmR,RmotorSpeed); analogWrite(pwmL,LmotorSpeed); digitalWrite(posR,HIGH); digitalWrite(negR,LOW); digitalWrite(posL,LOW); digitalWrite(negL,LOW); }