【ワレコの電子工作】ATmega328P用自作汎用I/Oボードでサーボモーターを赤外線リモコン制御Arduino IDEで【PCBWay発注基板】

この記事は約17分で読めます。
スポンサーリンク

ワレコ

ワテの場合、飽きっぽい性格だが電子工作は昔から好きだ。

最近はArduino UNOやAVRマイコンを独学で勉強している。

でも分からない事があると挫折しそうになるが、「継続は力なり」「千里の道も一歩から」などの諺を胸に刻んで諦めずに続けている。

さて、先日PCBWayさんに製作依頼したATmega328P用の自作汎用I/O基板は中々使い易い。

前回記事ではその基板を使ってLEDチカチカ実験に成功した。

【ワレコの電子工作】ATmega328P用自作汎用I/OボードでLEDチカチカ - Arduino IDEとMicrochip Studioで【PCBWay発注基板】
ワレコ 2022年もArduino UNOやAVRマイコンを使って色んなヘンテコな物を作りたい。 まずは自作オーディオ機器のボリュームをリモコン化したいのだ。 さて、下に示す前回記事ではAVRマイコン(AT...

当記事では、その汎用I/O基板を使ってサーボモーターを赤外線リモコン制御に成功したので、その作業手順を紹介したい。

では、本題に入ろう。

スポンサーリンク
スポンサーリンク

ATmega328P自作汎用I/O基板にブレッドボードを組み合わせる

サーボモーター実験をするに当たり、下写真に示すようにワテ自作ATmega328P汎用I/O基板(緑色)とブレッドボードを一枚のアクリル板に固定した。

写真 ATmega328P汎用I/Oボードとブレッドボードをアクリル板に固定

上写真のように一枚のアクリル板にATmega328P汎用I/Oボードとブレッドボードを固定したので、配線作業がやり易くなった。

基板の固定に使ったのはタカチ電機工業AST3-20Bだ。高さ20mmで付属M3ネジで基板をM3ナットに固定出来る。

さらに、下写真に示すようにATMEL-ICEの裏側とアクリル板にマジックテープを貼り付けた。

写真 ATMEL-ICEの裏側とアクリル板にマジックテープを貼り付けた

マジックテープは面ファスナーとも呼ばれるがオス・メスセットのヤツを買うと良い。

上写真のようにマジックテープを貼ると、下写真のようにATMEL-ICEが固定出来る。

写真 ATMEL-ICEをマジックテープでアクリル板に張り付けた

ATMEL-ICEを別の実験に使う時にはマジックテープを剥がせば良いので汎用性が高い。

サンハヤト製のブレッドボードは高品質

ちなみに今回使ったのはサンハヤト製のブレッドボードだ。

ワテの場合、今まではブレッドボードは秋月電子などで買った海外製の安っすいやつを数枚使っていた。今も使っているが。

サンハヤト SAD-101 ニューブレッドボード

ワテ推薦

KKHMF 5個 400穴 ミニブレッドボード 実験用ボード ジャンパーワイヤ 電源レール 84*54MM [並行輸入品]
サンハヤト SAD-101 ニューブレッドボード安っすいミニブレッドボード

まあ一枚200円くらいのその安っすいブレッドボードでも今のところ問題無く使えてはいるのだが、でも安かろう悪かろうの典型なのだ。

具体的には、ジャンパーワイヤーが抜き差しし辛いし、ジャンパーワイヤーを挿し込む時の力加減も一定ではなくて、ブレッドボードごとにバラツキも多い。まあそのジャンパーワイヤーも同じく海外製の安物だから先端が曲がっていて差し込む時に引っ掛かるとか、先端が酸化しているなど更に使い辛いのだ。

で、サンハヤトのブレッドボードがネット情報では非常に評判が良い事は前々から知っていた。でも一枚500円くらいなので外国製よりも二倍以上の値段なのだ。

でも今回試しにサンヤハト製ブレッドボードとジャンパーワイヤーを買ってみた。

サンハヤト ジャンプワイヤキット SKS-100 単線タイプでよく使用する短めジャンプワイヤのセット品
サンハヤト ジャンプワイヤキット SKS-100 単線タイプでよく使用する短めジャンプワイヤのセット品
サンハヤト ジャンプワイヤ SPP-50 50ミリ
サンハヤト ジャンプワイヤ SPP-50 50ミリ
サンハヤト ジャンプワイヤ SPP-70 70ミリ
サンハヤト ジャンプワイヤ SPP-70 70ミリ
サンハヤト ジャンプワイヤ SPP-100 100ミリ
サンハヤト ジャンプワイヤ SPP-100 100ミリ
サンハヤト ジャンプワイヤ SPP-150 150ミリ
サンハヤト ジャンプワイヤ SPP-150 150ミリ
サンハヤト ジャンプワイヤ SPP-200 200ミリ
サンハヤト ジャンプワイヤ SPP-200 200ミリ

実際にサンハヤト製ブレッドボードを使ってみるとネットの評判通りでとても使い易い。ジャンパーワイヤーの品質も良くブレッドボードに差し込む時のスムーズな感触、でもしっかりと電気的な接触が取れている安心感を指先に感じる。

もっと早くサンハヤトのブレッドボードを買っておけば良かったw

なお、サンハヤト製ブレッドボードはa,b,c,d,e,fとg,h,i,j,k,lの各6行ある。

一方、一般的な海外製のブレッドボードはa,b,c,d,eとf,g,h,i,jの各5行なのだ。

そう言う点でもサンハヤト製のブレッドボードは使い勝手が良いのだ。

秋月製USBシリアル変換モジュールを接続可能

下写真のようにAE-UM232R(秋月製USBシリアル変換モジュール)搭載基板(青、これもワテ設計)を6pinのピンヘッダでATmega328P汎用I/O基板に接続出来る。

写真 AE-UM232R(秋月製USBシリアル変換モジュール)搭載基板(青)を6pinのピンヘッダでATmega328P汎用I/O基板に接続

上写真のように接続しておくと、Arduino IDEのシリアルモニタ画面に文字列を送信する事が出来る。

LCDモジュールも接続可能

下写真のように秋月で買った2行のLCDモジュール(2×7=14pin)を2列ピンヘッダを使って接続可能にした。

写真 ATmega328P自作汎用I/O基板にはLCDモジュールも接続可能

なおLCDモジュールとATmega328Pとの接続はしていないので、必要に応じて配線を追加する必要がある。

具体的には半田付けしても良いし、あるいはジャンパーワイヤーで仮配線しても良い。

サーボモーターを赤外線リモコン制御する実験

と言う訳で、ワテ自作のATmega328P用汎用I/Oボードは328Pマイコンを単体で使う実験にはとっても使い易いぞ(自画自賛w)。

さて、下写真のようにサーボモーター、赤外線受信モジュール、緑LEDをブレッドボードに配線した。

写真 ATmega328Pマイコン単体で使ってサーボモーターを赤外線リモコン制御する実験

緑LEDは先日行ったLEDチカチカ実験の名残なので無くても良い。LEDは328Pの28番ピンに接続して、抵抗を通してGNDに接続している。

ブレッドボード上の黒い四角い部品が赤外線受信モジュールだ。使い方は簡単で三本の端子があり+5V, GNDを与えて出力信号を白いジャンパーワイヤーで328Pの27番ピンに接続している。

サーボモーターも三本の端子があり、+5V, GNDを与えて制御信号は黄色のジャンパーワイヤーで328Pの4番ピンに接続している。

なお、ここで使っている28番ピン、27番ピン、4番ピンなどは必ずしもこのピンで無くても良い。

下図に示すATmega328Pのピンマッピングで空いているやつを使えば良いようだ。

図 ATmega328Pのピンマッピング

現状では、28本のピンのうち以下のピンはそれぞれの用途に使われている。

1番ピン = RESET
2番ピン = シリアル通信用(RX)
3番ピン = シリアル通信用(TX)
7番ピン = GND
8番ピン = 5V
9番ピン = Crystal
10番ピン = Crystal
17番ピン = MOSI
18番ピン = MISO
19番ピン = SCK
20番ピン = 5V(AVCC=Analog VCC)
21番ピン = 5V(AREF=Analog Reference)
22番ピン = GND

なので、それ以外のピンなら自由に使っても良いようだ。

でもピンには種類があるようで、Analog InputやDigital Pinなどの名前が付いている。

例えば28番ピンはAnalog Input 5のようだが、LEDチカチカ実験ではその28番ピンをデジタルのHighやLowの出力に使えているのだが、それでもいいのかな?

つまりAnalog InputピンはDigital 入出力にも使えるのかな?

その辺りは今後調査したい。

赤外線リモコン受信&サーボモーター回転角度制御Arduinoスケッチ

さて、赤外線リモコンを受信して、受信したリモコンコードに応じてサーボモーターの回転角度を変化させるArduinoスケッチ(プログラムの事)を下に示す。

//#include "Stepper.h"
#include "IRremote.h"
#include <Servo.h>;

// 変数など
//int pinReceiver = 6;  // IR receiver 入力をArduino Digital Pin 6(=PD6=12番ピン)に設定
int pinReceiver = 18;  //27  PC4 (AI 4 / D18)
#define IR_CODE_MINUS   0xFFE01F    //  16769055  -ボタン
#define IR_CODE_PLUS    0xFFA857    //  16754775  +ボタン 
#define IR_CODE_0       0xFF6897    //  16738455  0
#define IR_CODE_1       0xFF30CF    //  16724175  1
#define IR_CODE_2       0xFF18E7    //  16718055  2
#define IR_CODE_3       0xFF7A85    //  16743045  3
#define IR_CODE_4       0xFF10EF    //  16716015  4
#define IR_CODE_5       0xFF38C7    //  16726215  5
#define IR_CODE_6       0xFF5AA5    //  16734885  6
#define IR_CODE_7       0xFF42BD    //  16728765  7
#define IR_CODE_8       0xFF4AB5    //  16730805  8
#define IR_CODE_9       0xFF52AD    //  16732845  9
#define IR_CODE_100PLUS     0xFF9867  //  16750695  100+ 
#define IR_CODE_200PLUS     0xFFB04F  //  16756815  200+
#define IR_CODE_EQ          0xFF906F  //  16748655  EQ
#define IR_CODE_PREV        0xFF22DD  //  16720605  <<
#define IR_CODE_NEXT        0xFF02FD  //  16712445  >>
#define IR_CODE_PLAY_PAUSE  0xFFC23D  //  16761405  PLAY/PAUSE
#define IR_CODE_CH_MINUS    0xFFA25D  //  16753245  CH-
#define IR_CODE_CH          0xFF629D  //  16736925  CH
#define IR_CODE_CH_PLUS     0xFFE21D  //  16769565  CH+

Servo myServo; // create a servo object
int const potPin = A0; // analog pin used to connect the potentiometer
int potVal;   // variable to read the value from the analog pin
int angle;    // variable to hold the angle for the servo motor



// モーターや赤外レシーバーの宣言
IRrecv irrecv(pinReceiver);     // create instance of 'irrecv'
decode_results results;         // create instance of 'decode_results'

void setup()
{
  irrecv.enableIRIn();          // Start the receiver
  Serial.begin(115200);         //
  Serial.println("setup out");  //
  myServo.attach(2);/// 9);     //ServoモーターをDigital Pin 2(=PD2=4番ピン)に設定
}

void loop()
{
  if (irrecv.decode(&results)) // IR signal受信チェック
  {
    Serial.println("if irrecv in");     // 追加した
    Serial.print("results.value=");     // 追加した
    Serial.println(results.value, HEX); // 追加した
    Serial.println(results.value);      // 追加した

    switch (results.value)
    {
      case IR_CODE_MINUS:   angle -= 10; myServo.write(angle); Serial.println("IR_CODE_MINUS"); break;
      case IR_CODE_PLUS:    angle += 10; myServo.write(angle); Serial.println("IR_CODE_PLUS "); break;
      case IR_CODE_0:       angle =   0; myServo.write(angle); Serial.println("IR_CODE_0    "); break;
      case IR_CODE_1:       angle =  20; myServo.write(angle); Serial.println("IR_CODE_1    "); break;
      case IR_CODE_2:       angle =  40; myServo.write(angle); Serial.println("IR_CODE_2    "); break;
      case IR_CODE_3:       angle =  60; myServo.write(angle); Serial.println("IR_CODE_3    "); break;
      case IR_CODE_4:       angle =  80; myServo.write(angle); Serial.println("IR_CODE_4    "); break;
      case IR_CODE_5:       angle = 100; myServo.write(angle); Serial.println("IR_CODE_5    "); break;
      case IR_CODE_6:       angle = 120; myServo.write(angle); Serial.println("IR_CODE_6    "); break;
      case IR_CODE_7:       angle = 140; myServo.write(angle); Serial.println("IR_CODE_7    "); break;
      case IR_CODE_8:       angle = 160; myServo.write(angle); Serial.println("IR_CODE_8    "); break;
      case IR_CODE_9:       angle = 180; myServo.write(angle); Serial.println("IR_CODE_9    "); break;
      case IR_CODE_100PLUS: angle += 30; myServo.write(angle); Serial.println("IR_CODE_100PLUS"); break;
      case IR_CODE_200PLUS: angle += 60; myServo.write(angle); Serial.println("IR_CODE_200PLUS"); break;
      case IR_CODE_EQ:          Serial.println("IR_CODE_EQ       "); break;
      case IR_CODE_PREV:        Serial.println("IR_CODE_PREV     "); break;
      case IR_CODE_NEXT:        Serial.println("IR_CODE_NEXT     "); break;
      case IR_CODE_PLAY_PAUSE:  Serial.println("IR_CODE_PLAY_PAUSE"); break;
      case IR_CODE_CH_MINUS:    Serial.println("IR_CODE_CH_MINUS "); break;
      case IR_CODE_CH:          Serial.println("IR_CODE_CH       "); break;
      case IR_CODE_CH_PLUS:     Serial.println("IR_CODE_CH_PLUS  "); break;
      default:
        Serial.println("default");
        break;
    }

    if (angle < 0) {
      angle = 0;
    }
    if (angle > 179) {
      angle = 179;
    }
    irrecv.resume(); // receive the next value
  }
}

コード 赤外線リモコン受信とサーボモーター回転角度制御Arduinoスケッチ

このコードは昨年、同じ実験をArduino UNOを使って行った時に使ったものと殆ど同じだ。

【ワレコの電子工作】Arduino UNOを使って赤外線リモコンでサーボモーター制御成功
ワレコ Arduino UNOを使ってサーボモーターのリモコン制御に成功した。 これで自作オーディオ機器のボリュームをリモコン化する目途が立ったぞ。 前回記事はこちら↴ Arduino UNO...

赤外線リモコンの反応が今一つ良くない

と言う事で赤外線リモコンでサーボモーター制御に成功したのだが、使っているリモコン送信機の出力が弱いようで、送信機と受信モジュールまでの距離が2メートル以上くらい離れると三回に一回くらいしか受信出来ない。

なので、もう少しパワーの強いリモコン送信機を入手するか、あるいは、現在使っているリモコン送信機の出力をパワーアップするなどの改造を試みたいと思っている。

まとめ

ワレコ

ようやくArduino UNO、素のAVRマイコンをある程度は使いこなせるようになった。

でも、まだまだ知らない事が多いので、引き続き勉強や実験を続けたい。

当記事ではワテ設計のATmega328Pマイコン用汎用I/O基板を使って赤外線リモコンでサーボモーターを制御する実験を紹介した。

ワテの場合はArduino UNOを最初に買ってLEDチカチカをやった。

Arduino UNOはUSBでパソコンと接続するだけで使えるので五分も有ればLEDチカチカ出来るだろう。

次にやったのはArduino UNOに搭載されているATmega328Pマイコンを単体で使う実験だ。

その時にはATMEL-ICEも買った。

ATMEL-ICEはライター兼デバッガーの機能があり、素のAVRマイコンのプログラミングにはとても使い易い。少々値段が高かったが、思い切って買って良かった。

あるいは下写真のような安価なヤツもある。

ワテはこの製品は持っていないのだが、たぶんATMEL-ICEと類似の機能を持っているのかな?

(続く)

スポンサーリンク
コメント募集

この記事に関して何か質問とか補足など有りましたら、このページ下部にあるコメント欄からお知らせ下さい。

ArduinoAVRDIYHobbyエレクトロニクス半田付け
スポンサーリンク
warekoをフォローする
スポンサーリンク
われこ われこ

コメント