概要

このレッスンでは、赤外線送受信機を使用してDCモーターを制御します。UNOボードをMCUボード(マイクロコントローラ)として、L298Nチップを搭載したXモータードライバーを使いDCモーターの制御を学びます。ここでは、ロボットを走行させるための基本となる車輪を前後進に回転させます。

部品表

ソフトウェアの準備

Arduino IDE(バージョン1.6.8以降)

Arduinoライブラリ: IRremote.h

接続

下記図に従って、Unoボード、バッテリーボックス、OSOYOO MODEL Xモーターダーバーモジュールを接続します。


OSOYOO UNOとOSOYOO MODEL Xモータードライバーユニットを下記のように接続します。

Uno R3 ボード OSOYOO MODEL Xモータードライバーユニット
D2 IN1
D4 IN2
D5 ENA
D6 ENB

下記図のように、赤外線受信機のSピンをD3ピン、GNDをGND、VCCを5Vに接続します。

コードプログラム

上記の操作が完了したら、USBケーブルを使用してArduinoボードをコンピューターに接続します。緑の電源LED(PWRのラベル)が点灯します。ArduinoIDEを開き、プロジェクトに対応するボードとポートタイプを選択し、Arduinoに次のスケッチをロードします。

#include <IRremote.h>
#define IN1  2   //K1、K2モーター進行方向
#define IN2  4     //K1、K2モーター進行方向
#define ENA  5    // モーター速度をENAで制御できるようにするには、PWMピンである必要があります
#define ENB  6    // モーター速度をENAで制御できるようにするには、PWMピンである必要があります
#define IRPIN 3 //赤外線受信機の信号ピンはUNOボードのピン3に接続します

#define IR_ADVANCE       0x00FF18E7       //送信器の「▲」ボタンコード
#define IR_BACK          0x00FF4AB5       //送信器の「▼」ボタンコード
enum DN
{ 
  GO_ADVANCE, //前進
  GO_BACK,//後進
  DEF
}Drive_Num=DEF;
IRrecv IR(IRPIN);  //   受信機の信号コードを送信器から取得します
decode_results IRresults;   
bool stopFlag = true;//停止方法を設定
bool JogFlag = false;
uint16_t JogTimeCnt = 0;
uint32_t JogTime=0;
/*motor control*/
void go_back(int t)  //モーターは時計回りに回転(前進)
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  delay(t);
}
void go_ahead(int t) //モーターは反時計回りに回転(後進)
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  delay(t);
}
void go_stop() //モーターブレーキ-(停止)
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
}

/*set motor speed */
void set_motorspeed(int lspeed,int rspeed) //モーター速度を変更する
{
  analogWrite(ENA,lspeed);//lspeed:0-255
  analogWrite(ENB,rspeed);//rspeed:0-255   
}
/**************detect IR code***************/
void do_IR_Tick()
{
  if(IR.decode(&IRresults))
  {
    if(IRresults.value==IR_ADVANCE)
    {
      Drive_Num=GO_ADVANCE;
    }
    else if(IRresults.value==IR_BACK)
    {
        Drive_Num=GO_BACK;
    }
    IRresults.value = 0;
    IR.resume();
  }
}
/**************car control**************/
void do_Drive_Tick()
{
    switch (Drive_Num) 
    {
      case GO_ADVANCE:
            set_motorspeed(255,255);go_ahead(20);JogFlag = true;JogTimeCnt = 3;JogTime=millis();break;//if GO_ADVANCE code is detected, then go advance
           case GO_BACK:
            set_motorspeed(255,255);go_back(20);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_BACK code is detected, then backward
      default:break;
    }
    Drive_Num=DEF;
   //keep current moving mode for  100 millis seconds
    if(millis()-JogTime>=100)
    {
      JogTime=millis();
      if(JogFlag == true) 
      {
        stopFlag = false;
        if(JogTimeCnt <= 0) 
        {
          JogFlag = false; stopFlag = true;
        }
        JogTimeCnt--;
      }
      if(stopFlag == true) 
      {
        JogTimeCnt=0;
        go_stop();
      }
    }
}
void setup() {
  /******L298N******/
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(ENA, OUTPUT);  
  pinMode(ENB, OUTPUT);
 
  pinMode(IRPIN, INPUT); 
  digitalWrite(IRPIN, HIGH);  
  IR.enableIRIn();
}

void loop() {
  do_IR_Tick();
  do_Drive_Tick();
}

実行結果

アップロードが完了後、数秒間を空けてから、18650個の電池を電池ケースに入れ電源を入れます。