2018年8月11日 星期六

Ardunio:實作紅外線遙控汽車(IR+ L298N)

本實作介紹如何使用紅外線接收模組的接收信號配合L298N電機驅動模組控制馬達正、反轉來完成簡易的紅外線遙控汽車。

  關於紅外線(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的轉速和方向。

  L298N電機驅動模組應用於步進馬達的控制效果如下:

  L298N電機驅動模組應用於直流馬達的控制效果如下:

  車輛控制程式碼:
#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);        
}