Unoを使って赤外線リモコン のバックアップ(No.3)

更新


公開メモ

概要

Arduino から赤外線リモコンでいろいろ動かしたい

やりたいこと:

  • Arduino に赤外線受信機と赤外線LEDを接続する
  • リモコンからのコマンドを赤外線受信機で読み取ってコマンドを覚えさせる
  • LED からコマンドを送って、テレビ、電灯、その他をマイコンから制御する

目次

開発環境を整える

  1. amazon で以下を購入
    • Arduino UNO (っぽいなにか)を購入
    • Arduino UNO 用のアクリルケースを購入
    • アクリルケースに不良があったので交換してもらう
  2. 秋月で以下を購入
    • 960 nm の LED
    • 赤外線リモコン用センサー
  3. Arduino UNO を USB で PC に接続
    • デバイスマネージャーで [ポート(COM と LPT)] を見ながら繋ぐ
    • USB-SERIAL CH340 (COM7) が増えたのを確認
  4. Windows 10 の Microsoft Store で Arduino IDE をインストール&起動
    • [ツール]-[ボード] で Arduino UNO を選択
    • [ツール]-[ボード] で COM7 を選択
    • コードを何も変更せずに [スケッチ]-[マイコンボードに書き込む] する
    • IDE に 「ボードへの書き込みが完了しました。」と表示され、ボード上の "L" とマークされた LED が点灯する

ここまでで開発環境が整ったことになる。

マイコン機能をどう使うか勉強する

Arduino UNO 仕様

http://arduinopid.web.fc2.com/b2.html が参考になる

ピンの上げ下げ

13 番ピンがボード上の "L" とマークされた LED につながっている。

LANG:C
#define LED_L 13        // オンボード LED

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_L, OUTPUT);

  digitalWrite(LED_L, HIGH);
  delay(1000);             // 1000 ミリ秒 = 1 秒
  digitalWrite(LED_L, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
}

コードをこう変えて Ctrl+U を押したら、プログラムの書き込み終了後、1秒だけ LED が灯って消えた。

プログラムは ROM へ書き込まれているので、ボード上のタクトスイッチ(リセットボタン)を押すとまたプログラムが最初から実行されて、1秒だけ LED が点灯する。

繰り返し処理

LANG:C
#define LED_L 13        // オンボード LED

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_L, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(LED_L, HIGH);
  delay(1000);             // 1000 ミリ秒 = 1 秒
  digitalWrite(LED_L, LOW);
  delay(1000);             // 1000 ミリ秒 = 1 秒
}

こうすると、1秒ごとについたり消えたりする。

シリアル:ボードから PC へ

LANG:C
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);       // 9600 ボー
  Serial.println("Hello!");
}

void loop() {
  // put your main code here, to run repeatedly:
}

[ツール]-[シリアルモニタ] を見ると、ちゃんとメッセージが届いていることを確認できる。

シリアル:PC からボードへ

https://garretlab.web.fc2.com/arduino_reference/language/functions/communication/serial/serialEvent.html

arduino uno では int は 2 バイトだそうだ。

LANG:C
#define LED_L 13
#define CHAR_EOL 10
#define SERIAL_BUFFER_LEN 256

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_L , OUTPUT);  // オンボード LED
  
  Serial.begin(9600);       // 9600 ボー
}

volatile char serialBuffer[SERIAL_BUFFER_LEN];
volatile unsigned char serial_wp = 0;
void serialEvent() {
  // loop() 呼出し後にシリアルデータが届いていたら呼ばれる
  char c = Serial.read();
  if( c == CHAR_EOL ) {
    serialBuffer[serial_wp] = 0;
    serial_wp = 255;
  } else {
    serialBuffer[serial_wp] = c;
    serial_wp++;
  }
}

unsigned led = 0;
void loop() {
  // put your main code here, to run repeatedly:

  if(serial_wp == 255){ // 1行届いた
    serial_wp = 0;

    led = !led;         // LED を反転
    digitalWrite(LED_L, led);
  }
}

1行何か送るたびに LED がついたり消えたりする。

赤外線受信機をつなぐ

ちょっと手抜きをして赤外線受信機の

  • 電源を 8 番ピンに
  • GNDを 9 番ピンに
  • 信号出力を 10 番ピンに

繋いだ。

LANG:C
#define LED_L 13        // オンボード LED
#define RECV_POW 4      // 赤外線受信機 電源
#define RECV_GND 3      // 赤外線受信機 GND
#define RECV_SIG 2      // 赤外線受信機 信号出力

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_L , OUTPUT);
  
  pinMode(RECV_GND, OUTPUT);
  digitalWrite(RECV_GND, LOW);
  pinMode(RECV_POW, OUTPUT);
  digitalWrite(RECV_POW, HIGH);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(LED_L, digitalRead(RECV_SIG));
}

赤外線リモコンを赤外線受信機に向けて適当なボタンを押すとボード上の LED が明滅することを確認できる。

赤外線受信機は 37kHz で明滅する波長 960 nm 程度の赤外線を受信したときに信号を LOW にする。

必要ないかもしれないけれど、このつなぎ方だと 10 番ピンを LOW にすることで赤外線受信機を off にできる。

外部割込み

2番ピンと 3番ピン しか割り込み入力として利用できないらしいので注意が必要。

setup にて、

  attachInterrupt(digitalPinToInterrupt(RECV_SIG), receiverEvent, CHANGE);

とするだけで、RECV_SIG ピン (2番) が変更されたら receiverEvent が呼ばれるらしい。

http://elm-chan.org/docs/ir_format.html

によるとリモコンコマンドは大体 500us ごとに 0, 1 が切り替わるらしい。


Counter: 9671 (from 2010/06/03), today: 2, yesterday: 0