概要

このレッスンでは赤外線通信により、サーボモーターを制御方法を学びます。今回は、Lesson8で使った赤外線送受信機を使い、信号の送受信とサーボモーターの制御に関する一般的な概念を取得することができます。

準備

ハードウェア

ソフトウェア

赤外線送信機を使い、信号を受信機に送信し、サーボモーターを制御します。必要な配線は下記図に従い組立てていってください。

IRREMOTEライブラリを使用してサーボを制御する

  IR Arduinoライブラリからライブラリ情報をダウンロードします。

Arduino IDEからIRremoteデモ例を開き、Arduinoボードにアップロードします。

次に、シリアルモニターを開き、赤外線送信機のボタンをクリックし、赤外線受信機に信号を送信します。下記動画のように、各ボタンを押すとボタンに割り振られたHEXコードが表示されます。

次に、サーボモーターの制御に使用されるボタンのHEXコードを検出します。2つのボタンを使用すると仮定し、1つは時計回りの回転用、もう1つは反時計回りの回転用です。

たとえば時計回りに(▲)を使用し、反時計回りに(▼)を使用するため、HEXコードを取得する必要があります。

コードプログラム

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

#include <IRremote.h>      //IRremoteライブラリをarduinoライブラリにコピーする必要があります
#include <Servo.h>
#define plus 0xFF18E7   //時計回りのボタン
#define minus 0xFF4AB5  //反時計回りのボタン

int RECV_PIN = 3;       //赤外線受信機のピン
Servo servo;
int val;                //回転角度
bool cwRotation, ccwRotation;  //回転の状態

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // 受信機を起動する
  servo.attach(9);     //サーボピン
}

void loop() 
{
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value

    if (results.value == plus)
    {
      cwRotation = !cwRotation;      //回転角度の値を切り替えます
      ccwRotation = false;         //これ以上回転しません
    }

    if (results.value == minus)
    {
      ccwRotation = !ccwRotation;   //toggle the rotation value
      cwRotation = false;            //回転角度の値を切り替えます
    }
  }
  if (cwRotation && (val != 175))  {
    val++;                         //連動ボタン用
  }
  if (ccwRotation && (val != 0))  {
    val--;                         //カウンター連動ボタン用
  }
  servo.write(val);
  delay(20);          //回転速度
}

実行結果

このプログラムは、送信機の(▲)(▼)ボタンを押すことで、モーターが前後進に回転・停止させることができます。また同じボタンを2回押すことで、モーターは停止します。

IRLIBALLライブラリを使用してサーボを制御する

今回は、IRLibAllライブラリーを使用してサーボを制御します。サーボの回転速度と、角度を制御します。

接続

上図に示したように、+ 3.3v、GND、およびピン3に接続された赤外線受信機とサーボが見て取れると思います。サーボの接続に関して赤い線は+5vに、GNDは暗褐色のワイヤはGND、残りのワイヤをピン9に接続しますが、デジタル出力ピンでもかまいません。

IRライブラリIRLibAllのインストール

IRライブラリをインストールするには:

  1. 上のボタンをクリックしてIRライブラリをダウンロードするか、 GithubのIRLib 2.xライブラリから直接ダウンロードします。
  2. ダウンロードが完了したら、ZIPファイルを解凍します。
  3. 解凍すると5つの個別のフォルダーが格納されています。IRLib 2.xには、連動して動作する複数のライブラリが含まれています。
  4. 5つすべてのライブラリをArduino Libraryフォルダーのルートディレクトリにコピーします。標準ではパスは(home)/ Documents / Arduino / Librariesにあります。/ Libraries /フォルダーが表示されない場合は、自分で作成する必要があります。
  5. Arduino IDEを再起動します。

コードをアップロードします

以下、「IRLib2 / examples」フォルダからservo.inoスケッチのバージョンとなっております。OSOYOO Smart Car V1 Remoteで使用できる内容に変更しています。別の操作方法を使用している場合は、dump.inoを使用してさまざまなボタンのコードに関する情報を収集し、適切なプロトコル名とコードでスケッチを変更する必要があります。

#include <IRLibAll.h>
#include <Servo.h> 

//  プロトコルに応じてこれらの値を設定する必要があります
// ここで使用しているリモートコードはAdafruit用です
// ミニリモコン
#define MY_PROTOCOL NEC
#define RIGHT_ARROW   0xFF5AA5 //時計回りに回転する
#define LEFT_ARROW    0xFF10EF //反時計回りに回転する
#define SELECT_BUTTON 0xFF38C7 //サーボの回転位置が中心
#define UP_ARROW      0xFF18E7 //サーボの速度を早くする
#define DOWN_ARROW    0xFF4AB5 //サーボの速度を遅くする
#define BUTTON_0 0xFF9867  //ボタン0〜9を押すと、決まった位置に移動します
#define BUTTON_1 0xFFA25D  // 20度ずつ回転
#define BUTTON_2 0xFF629D
#define BUTTON_3 0xFFE21D
#define BUTTON_4 0xFF22DD
#define BUTTON_5 0xFF02FD
#define BUTTON_6 0xFFC23D
#define BUTTON_7 0xFFE01F
#define BUTTON_8 0xFFA857
#define BUTTON_9 0xFF906F

IRrecv myReceiver(2); //受信機のピン番号
IRdecode myDecoder;

Servo myServo;  // サーボを制御するサーボオブジェクトを作成する
int16_t pos;         // サーボ位置を保存する変数を設定する
int16_t Speed;       // 左/右ボタンが押されるたびに移動する度数
uint32_t Previous;//NEC繰り返しコードを処理します

void setup() { 
  myServo.attach(9);      // ピン9のサーボをサーボオブジェクトに接続します
  pos = 90;               // 中間点90度から開始
  Speed = 3;              // 左/右を押すたびにサーボが3度移動します
  myServo.write(pos);     // 初期位置を設定
  myReceiver.enableIRIn(); // 受信機を起動する
} 
  
void loop() 
{ 
    if (myReceiver.getResults()) {
       myDecoder.decode();
       if(myDecoder.protocolNum==MY_PROTOCOL) {
         if(myDecoder.value==0xFFFFFFFF)
           myDecoder.value=Previous;
         switch(myDecoder.value) {
            case LEFT_ARROW:    pos=min(180,pos+Speed); break;
            case RIGHT_ARROW:   pos=max(0,pos-Speed); break;
            case SELECT_BUTTON: pos=90; break;
            case UP_ARROW:      Speed=min(10, Speed+1); break;
            case DOWN_ARROW:    Speed=max(1, Speed-1); break;
            case BUTTON_0:      pos=0*20; break;
            case BUTTON_1:      pos=1*20; break;
            case BUTTON_2:      pos=2*20; break;
            case BUTTON_3:      pos=3*20; break;
            case BUTTON_4:      pos=4*20; break;
            case BUTTON_5:      pos=5*20; break;
            case BUTTON_6:      pos=6*20; break;
            case BUTTON_7:      pos=7*20; break;
            case BUTTON_8:      pos=8*20; break;
            case BUTTON_9:      pos=9*20; break;
         }
         myServo.write(pos); // 変数 'pos'の位置に移動するようサーボに指示する
         Previous=myDecoder.value;
       }
       myReceiver.enableIRIn();
    }
}

ATmega32u4ベースに関する独自のシステム

ここに示している例はArduino UnoまたはMegaで問題なく動作しますが、Arduino Leonardo、Arduino Micro、Arduino Yun、または他のATmega32u4ベースのシステムを使用している場合は、IRLibの内容を変更する必要があります。

IRLibは、Arduinoに組み込まれたハードウェアタイマーを使用して50µsごとに割り込みを発生させ、入力ピンをポーリング(複数の機器やソフトウェアを円滑に連携させる制御方式の一つ)して変更があったかどうかを確認させます。標準ではTIMER2を使用します。Arduinoサーボライブラリは、TIMER1を使用したハードウェア割り込みにも使用しています。ただし、ATmega32u4プロセッサにはTIMER2がないため、そのプロセッサを使用するシステムではIRLibのデフォルトはTIMER1になります。そこでデフォルトのタイマーを変更する必要があります。「IRLibProtocols / IRLibHardware.h」の56行目以下には、次のようなものがあります。

#elif defined(__AVR_ATmega32U4__)
  #ifdef CORE_TEENSY
    // it's Teensy 2.0
    //#define IR_SEND_TIMER1  14
    //#define IR_SEND_TIMER3  9
    #define IR_SEND_TIMER4_HS 10
  #else
  /* it's probably Leonardo */
    #define IR_SEND_TIMER1    9
    //#define IR_SEND_TIMER3  5
    //#define IR_SEND_TIMER4_HS 13
  #endif

上記のようにコメントアウトするには、#define IR_SEND_TIMER1の前に//を置く必要があります。次にTIMER3またはTIMER4_HSのいずれかの前にあるスラッシュを削除します。これらの定義は「IR_SEND_TIMERxx」ということに注意してください。ファイルの後半で、この値をコピーして、受信タイマーとして使用していきます。Leonardoを使用しており、IRLibの赤外線信号を送信する場合は、これらの定義後に数値をメモする必要があります。受信機の任意のデジタル入力ピンにフック(利用者が独自の処理を追加できるようにする仕組み)できますが、IRLibでは、使用しているタイマーに応じて特定の出力ピンを使用する必要があります。これについては、送信に関するセクションの後半で説明します。

実行結果

スケッチをアップロードして、左右の矢印ボタンを押してみてください。サーボが左右に回転します。エンターボタンを押すと、サーボが中央にきます。上矢印ボタンまたは下矢印ボタンを押しても、目に見える効果はありませんが、左または右に押す動きの速度が変わります。0から9までの番号ボタンを押すことで、20°間隔でサーボを10の異なる位置に回転します。

サーボが動作が安定しない場合は電源に問題がある可能性が高いです。一部のUSBポートは、Arduinoに接続しているサーボを動かすのに必要な電流が不足しているので、外部から5ボルト電源を追加する必要もあります。