電子工作をしていると、作った機器を無線化したい場合が時々あります。方法としてはBLEや315Mhzの無線、Wifiを使うなどの方法があります。ただ、これらの方法は少し大掛かりになってしまうため、簡単に作れて取り回しの良い、赤外線通信の方法を紹介したいと思います。
この記事では、前編で赤外線通信で使用する38kHzの搬送波を作ります。また、後編では赤外線の送信機と、赤外線の受信機をそれぞれ作ることにします。目次は次のとおりです。
赤外線通信の概要
赤外線通信はTVのリモコンや、Nintendo DS、ガラケーなどの通信に使われている無線通信技術です。赤外線LEDを一定のパターンで光らせることでデータを送信します。
このとき、単に赤外線LEDをON/OFFしてデータを送ることもできますが、通常手法は取られていません。これは太陽光やシーリングライトにも赤外線が含まれており、これらの外光がノイズになって機器が誤動作してしまうためです。
そのため、赤外線通信する場合は38kHzの搬送波で変調してデータを送信します。変調というと難しそうですが、ONのとき赤外線LEDを38kHzで発振させ、OFFのときは赤外線を消灯します。
赤外線ONのときをデータの「1」、OFFのときをデータの「0」に割り当てることもできますが、これだと受信側でのデコードがシビアになります。どういうことかというと、次のようにデータのサンプリングのタイミングを厳密に合わせないと、データのデコードにミスってしまうのです。
そこで、少し冗長ではありますが、次のように最初にON、その後にOFFの期間を設けます。ONに続くOFFの時間が800us未満であればデータ「1」、800us以上であればデータ「0」とします。このようにすることで、受信側では確実にデータをデコードすることができるようになります。
最後にデータの最初と最後を定義するパターンも用意してやります。ここでは、ONの時間が3400us以上続くパターンをヘッダ、OFFの時間が10000us以上のパターンをストップビットとして使用します。
Arduinoで赤外線通信をするために必要な基礎知識はこれでOKです。次は実際にArduinoで38kHzの搬送波を作っていくことにします。
38kHzの搬送波を作る
まずは最初に搬送波を作ります。ここで作る搬送波は38kHzでONとOFFを繰り返す矩形波になります。Arduinoを使ってこの矩形波を作るにはPWM(Pulse Width Modulation)という機能を使います。
PWMを使うには次の4つの手順に従って、それぞれのレジスタにパラメータを設定する必要があります。
- PWMに使うポート(出力ポート)を指定する
- TCCR1AとTCCR1Bのレジスタにパラメータをセットする
- OCR1Aのレジスタで周波数を決める
- OCR1Bでデューティ比を決める
それぞれの手順について、詳細に確認していきましょう。
PWMに使うポートを指定する
ArduinoのPWMで使用できるポートは9番と10番ポートです。ここでは10番ポートからPWMを出力して赤外線LEDを光らせるので、次のようにして10番ポートを出力に設定します。
pinMode(10, OUTPUT );
TCCR1AとTCCR1Bのレジスタにパラメータをセットする
ここがPWM出力のキモになる設定です。TCCRx系のレジスタは、タイマーに使用するレジスタです。タイマーに使えるレジスタはTCCR0A/BとTCCR1A/Bがあるのですが、TCCR0系はArduinoの内部処理(delay関数など)に使われているので、プログラマが使えるのはTCCR1系になります。
TCCR1AとTCCR1Bの設定項目をまとめると下図のようになります。
詳しくは公式のドキュメントを参照してください。
https://avr.jp/user/DS/PDF/megaXX8PA.pdf:image=https://avr.jp/user/DS/PDF/megaXX8PA.pdf
■ 使用ポートの設定
TCCR1Aの4〜7ビット目で使用するポートを宣言します。9番ポートを使う場合は6~7ビットを10に、使用しない場合は00に設定します。10番ポートを使う場合は4~5ビットを10に、使用しない場合は00に設定します。
■ タイマーモードの設定
TCCR1Aの0〜1ビット目とTCCR1Bの3〜4ビット目を使ってタイマーモードを設定します。主な設定項目には次のようなものがあります。ここではPWM出力をするため全ビットを1に設定します。
出力モード | 設定値 |
---|---|
標準 | 0000 |
CTC | 0100 |
高速PWM | 1111 |
■ 分周の設定
TCCR1Bの0〜1ビット目でシステムクロックの分周率を決めます。分周とは、システムクロック周波数を1/n倍して、より周波数の低いクロックを作成する仕組みです。
分周を使うことで、タイマーにシステムクロックよりも低い周波数を使うことができます。クロックを設定値は次の通りで、ここではArduino Unoのシステムクロック16Mhzを8分周して使いたいので「010」に設定します。
分周率 | 設定値 |
---|---|
分周なし | 000 |
分周1/8 | 010 |
分周1/64 | 011 |
分周1/256 | 100 |
分周1/1024 | 101 |
OCR1AとOCR1Bのレジスタにパラメータをセットする
OCR1Aのレジスタにはタイマーの上限値(=リセットする時間)を設定します。この上限値によって、下図のように生成するPWMの周波数が決まります。OCR1Bではデューティー比(PWMがONになっている期間とOFFになっている時間の比)を決めます。タイマーの値がOCR1Bで設定した値よりも小さい場合はON、大きい場合はOFFになります。
赤外線通信では38kHzの搬送波を作りたいので、PWMで作成する波形の周期は1/38kHz=0.00002631578947秒となります。クロックの周期はシステムクロックを8分周しているため、1/(16Mhz/8)=1/2Mhz=0.00000005秒です。したがって、0.00002631578947÷0.00000005=51カウントしたときに、リセットがかかるようにOCR1Aには51を設定します。
また、赤外線通信では電力消費を考えてデューティー比を3:1にします。そのためOCR1BにはOCR1Aで設定した値の1/3(=17)を設定します。
搬送波のプログラム
ここまでで38kHzの搬送波を作る方法がわかりました。これをふまえて、プログラムを作ってみましょう。
void setup() { pinMode(10, OUTPUT ); TCCR1A = B00100011; TCCR1B = B00011010; OCR1AL = F_CPU / 38000L / 8 - 1; OCR1BL = OCR1AL / 3; }
上のプログラムでは10番ポートを出力に設定し、TCCR1A/BのレジスタでPWM出力を行うように設定しています。OCR1Aにはタイマの上限値を設定しています。F_CPUはArduinoで定義されている定数でシステムクロック周波数(Arduino Unoでは16Mhz)が格納されています。また、OCR1Bにはデューティー比が1/3になるように設定しています。
実行して、10番ポートにオシロスコープをあてて出力波形を見てみてください(ここでは赤外線LEDは接続しなくても大丈夫です)。次のように38kHzの矩形波が出力されていれば成功です。
後編では、ここで作成した38kHzの搬送波を使って赤外線の送信機と、赤外線の受信機をそれぞれ作ることにします。後編の記事はコチラ!
nn-hokuson.hatenablog.com
使用したパーツなど
今回のようにPWM出力を確認したいときにはオシロスコープがあると便利です。今回のように、観測したい周波数が100kHz程度でよければ安価な製品もあるので、チェックしてみてください!