- 追加された行はこの色です。
- 削除された行はこの色です。
[[Arduino勉強会]]
#contents
2014/05/03からのアクセス回数 &counter;
** 赤外線リモコンのフォーマット [#r63ad23a]
赤外線リモコンには、以下の3つのフォーマットがありますが、ここではNEC方式を使用します。
(([[赤外線リモコンの通信フォーマット>http://elm-chan.org/docs/ir_format.html]]を参考にしました))
- NEC(現ルネサスエレクトロニクス)フォーマット
- AEHA(家製協)フォーマット
- SONYフォーマット
*** NECフォーマットについて [#b7be1649]
最もよく使われているNECフォーマットを使って実験することにします。
NECフォーマットでは、ビット情報は38KHz(1/3duty)で送信され、Frameと呼ばれるデータ単位
に続いてRepeatと呼ばれるFrameの終わりを表すデータがボタンが押されている間繰り返されます。
Frameは、以下の形式を持っています。データが1の時には、0.56msのON, 1.69msのOFFを送り、
データが0の場合には、0.56msのON, 1.69msのOFFを送ります。
- Leader(9msのON, 4.5msのOFF)
- Customer Code(16bitのカスタマコードをLSBから順に送信)
- Data(8bit)
- Dataのビット反転値(8bit)
- Stopビット
** Arduinoを使ってNECフォーマットのデータを送る [#sedc3517]
38KHzでオン・オフを繰り返すには、digitalWriteでは時間がかかるため、PORTDに直接ビットをセットします。
このため使用可能なデジタルピンは、0から7番までとなっています。
Arduinoを使って赤外線リモコンを送信する例題は、いくつかありましたが、今回参考にさせて頂いたのは、以下の3サイトです。
- Arduinoで遊ぶページの [[赤外線リモコンの実験>http://garretlab.web.fc2.com/arduino/lab/infrared_controller/index.html]]
- 戸田よろず研究所の[[赤外線リモコンの複製2(38 kHzをソフトウェアで制御)>http://tyk-systems.com/ircopy2/ircopy2.html]]
- セミコロンラボの[[Arduinoで赤外線リモコン送信>http://www.cjpr.sakura.ne.jp/arduino/irrcsend.html]]
ここでは、Arduinoで遊ぶページをメインに参考にさせて頂き、東芝REGZAの電源オン・オフを試みます。
*** リモコン側のブレッドボード [#q5ebb4dd]
ちょっと乱暴ですが、動作を確認するだけなので、赤外線LEDの線の長い方を直接2番と短い方をGNDに接続して試してみます。
今回使った赤外線LEDは、スイッチサイエンスの
[[SIR-34ST3F>http://www.switch-science.com/catalog/1484/]]
です。
&ref(IR_Send_Bread.png);
*** リモコン側のスケッチ [#hcac2606]
使用するスケッチは、以下の様にします。
#pre{{
class IrControlNecFormat {
public:
// constructor
IrControlNecFormat(byte ledPin, byte custom0, byte custom1);
void sendCommand(byte data);
private:
byte _ledPinMask; // the pin mask which the LED is connected
byte _custom0; // custom code
byte _custom1; // custom code'
void sendData(byte date);
void on(int num);
};
IrControlNecFormat::IrControlNecFormat(byte ledPin, byte custom0, byte custom1) {
_ledPinMask = 1 << ledPin;
_custom0 = custom0;
_custom1 = custom1;
pinMode(ledPin, OUTPUT); // set the ledPin as an OUTPUT
}
void IrControlNecFormat::sendCommand(byte data){
on(346); // leader code(ON)
delayMicroseconds(4500); // leader code(OFF)
sendData(_custom0); // custom code
sendData(_custom1); // custom code
sendData(data); // data
sendData(~data); // ~data
on(22); // stop bit
}
void IrControlNecFormat::sendData(byte data) {
for(int i = 0; i < 8; i++) {
on(22);
int delayU_Sec = ( data & 0x01 ) ? 1690 : 565;
delayMicroseconds( delayU_Sec );
data = data >> 1;
}
}
void IrControlNecFormat::on(int num) {
for(int i = 0; i < num; i++) {
PORTD |= _ledPinMask;
delayMicroseconds(9);
PORTD &= ~_ledPinMask;
delayMicroseconds(17);
}
}
// 赤外線LEDを2番ピンとGNDに接続
// 東芝REGZAのカスタマコードは、 0x40, 0xBF
IrControlNecFormat controller(2, 0x40, 0xBF);
void setup() {
}
void loop() {
// REGZAの電源コードは、0x12
controller.sendCommand(0x12);
// 5秒間隔でオン・オフを繰り返す
delay(5000);
}
}}
スケッチの以下の部分で2番ピンにカスタマコードとして、0x40, 0xBFとして、IrControlNecFormatクラスのインスタンスを生成します。
#pre{{
IrControlNecFormat controller(2, 0x40, 0xBF);
}}
これで、東芝REGZAのコントロールができるcontrollerができます。
これに、0x12(電源のコード)をsendCommandで送ると電源のオン・オフを繰り返します。
*** 実際に動かしてみる。 [#x5795c9f]
ブレッドボードを組み立てて、LEDをテレビに向けてリセットスイッチを押してみて下さい。
5秒間隔でオン・オフを繰り返します。((どうもREGZAでは電源オフで上手くできないことがあります))
&ref(IR_Send_Setting.png);
*** 他の操作方法 [#y823a5e1]
上記のスケッチのカスタマコードとコードを変えるといろんな処理ができるようになります。
以下のPDFに各種テレビのカスタムコードとデータの意味がまとめられています。
- [[NECフォーマット 赤外線リモコン コード表>http://www.ne.jp/asahi/o-family/extdisk/ATBextension/ATBIRrecvNEC/ATBIRrecvNEClst.pdf]]
** 赤外線受信機 [#f876ebf3]
赤外線リモコンのコードが公開されていない場合には、どうしたらよいのでしょう。
今回は、スイッチサイエンスの
[[RPM6938リモコン受光モジュール>http://www.switch-science.com/catalog/list/?keyword=RPM6938]]
を使って実験してみます。
&ref(RPM6938_master_10.jpg);
ピンの配置は、データシートから引用します。丸い突起のある面の左からRout, GND, Vccとなっています。
&ref(IR_Receiver.png);
*** 赤外線受光器のブレッドボード [#y6ebc8dd]
以下の様にブレッドボードを組み立てます。受光モジュールが同じものがなかったので、形の似たもので表示しています。
&ref(IR_Rec_Bread.png);
*** 赤外線コード解析 [#p18333c5]
Arduinoで遊ぶページの[[赤外線リモコンコード解析(NECフォーマット)>http://garretlab.web.fc2.com/arduino/make/infrared_sensor_nec_format/]]
に紹介されている赤外線リモコン解析スケッチが重宝します。
以下に引用して表示します。
#pre{{
#define COUNT_NUM 68
const int pin = 2; /* 赤外線センサの出力を接続するデジタルピン */
unsigned long time[COUNT_NUM]; /* 時刻を格納する配列 */
void setup () {
pinMode(pin, INPUT);
Serial.begin(9600);
}
void loop () {
int repeat = 0;
int mode; /* 読み取るデータを決める */
char str[64];
/* 68回データを読み取る */
mode = HIGH; /* 最初はHIGH */
for (int i = 0; i < COUNT_NUM; i++) {
while(digitalRead(pin) == mode) { /* 状態が変わるまで待つ */
;
}
time[i] = micros(); /* 時刻を記録する */
if (mode == HIGH) { /* onとoffが交互に来るので,待つべき状態を変える */
mode = LOW;
} else {
mode = HIGH;
}
/* リーダコードのoffが2.25msだと次にストップビットが来て終了 */
/* 3000ms以下かどうかで判定 */
if ((i == 3) && ((time[2] - time[1])) < 3000) {
repeat = 1;
break;
}
}
/* データの出力 */
Serial.print("--------- BEGIN ---------\n");
sprintf(str, "Leader:\n HIGH %dms\n", (time[1] - time[0]));
Serial.print(str);
sprintf(str, " LOW %4dms\n\n", (time[2] - time[1]));
Serial.print(str);
if(repeat) {
Serial.println("Repeat");
} else {
Serial.println("Custom Code:");
print_data(2);
print_data(18);
Serial.println("");
Serial.println("Data:");
print_data(34);
print_data(50);
Serial.print("--------- END ---------\n\n");
}
}
void print_data(int start) {
int code = 0;
char str[32];
sprintf(str, " ");
for (int i = 0; i < 8; i++) {
if ((time[2 * i + start + 2] - time[2 * i + start]) > 1500) {
code |= 1 << i;
sprintf(&str[2 * (i + 1)], "1 ");
} else {
sprintf(&str[2 * (i + 1)], "0 ");
}
}
sprintf(&str[17], ", %02x", code);
Serial.println(str);
}
}}
*** 赤外線コード解析を動かしてみる [#f59e8621]
それでは、赤外線コード解析スケッチを動かしてみます。
&ref(IR_Recv_Setting.png);
シリアルモニターを起動し、テレビ(REGZA)の電源ボタンを押すと以下の様に返ってきます。
&ref(IR_Recv_monitor.png);
最初に作った通り、カスタマコード0x40, 0xBFとデータ0x12が受信されていることが確認できます。
これを使えば、他のリモコンの解析もできます。
*** 再確認 [#jd87e4b7]
小出さまのご質問で、再度実験をしてみました。
もしかしてCPUのクロックが影響しているのかと思い、今回はDuemilanoveを使いました。
&ref(confirm.png);
起動直後は、きちんと動いていましたが、蛍光灯の明かりを消すと急に以下の様にシリアスコンソールに
表示されました。
#pre{{
--------- BEGIN ---------
Leader:
HIGH 2152ms
LOW 324ms
Repeat
--------- BEGIN ---------
Leader:
HIGH 80ms
LOW 2572ms
Repeat
}}
出力を遡ってみると、東芝のリモコンを押したときには、きちんとCustom Codeの出力でていました。
#pre{{
--------- BEGIN ---------
Leader:
HIGH 72ms
LOW -18344ms
Custom Code:
1 1 1 1 1 1 1 1, ff
0 1 0 1 1 1 1 0, 7a
Data:
1 0 0 0 0 1 0 0, 21
0 0 0 1 0 1 0 0, 28
--------- END ---------
}}
** コメント [#n42e613d]
#vote(おもしろかった[14],そうでもない[0],わかりずらい[0])
#vote(おもしろかった[22],そうでもない[0],わかりずらい[3])
皆様のご意見、ご希望をお待ちしております。勉強会で分からなかったこと等、お気軽に問い合わせて下さい。
スパム防止に画像の文字列も入力してください。
- たいへん興味深く、赤外線コード解析作製したのですが、東芝のリモコンを入力しても際限なくスクロールしていきます。受信されてないのか?同期が取れてないのでしょうか? -- [[小出]] &new{2015-07-10 (金) 08:22:36};
- 小出さま、「再確認」を見てください。状況によってはシリアル画面が流れることがありましたが、Leaderの検出がずっと出ているみたいです。キーを押したときの情報がないか探してみてください。 -- [[竹本 浩]] &new{2015-07-10 (金) 21:19:08};
- ありがとうございます。調べてみます。arduino興味深いんですが まだまだ始めたばかりでして。 -- [[小出]] &new{2015-07-11 (土) 09:42:28};
- Leader が流れるので 箱の中に入れたりしたのですが、電池2本で動作するよう3.3Vのmini使ってまして、センサーの電圧も不足してますね。お恥ずかしい限りです。 -- [[小出]] &new{2015-07-13 (月) 08:24:53};
#comment_kcaptcha