PICによる赤外線通信1

赤外線リモコン戦車を作るために、PICを使った赤外線通信装置を作成しました。そのときに経験したことを書き留めておきます。

赤外線受信モジュール

電子工作で赤外線送受信を行う場合によく使われるのが、下のような赤外線受信モジュールです。

赤外線受信モジュールTL3818

これは、TL3818という名称の受信モジュールです1。この赤外線受信モジュールには3つの端子があります。それぞれの端子名は図の左から、OUT、GND、VCCです。VCC端子とGND端子はモジュールの電源とGNDです。残りの1つ、OUT端子は受信信号を出力するための端子です。

受信赤外線とOUT信号。TL3818データシートから抜粋。

OUT端子は普段はHigh電圧になっています。そして、約38kHzの周波数で点滅する赤外線がモジュールに照射されるとLow電圧になります。(上の図を参照)

つまり、出力端子の電圧を見れば、送信機から赤外線が照射されているか否かを感知できます。そして、これを上手く使って赤外線送受信を行うことができます。

なお、約38kHzと書いているのは、絶対に38kHzぴったりでなくてもよいためです。38KHzから多少ずれていても、受信できるようです。(実際に、あとで説明する例では38.5kHzで赤外線を送信することになりますが、受信モジュールは信号を受信できています。)

また、製品によっては38kHz以外の周波数で受信するタイプ2もあるようです。

38kHzで赤外線LEDを点滅させる

赤外線LEDを使えば簡単に赤外線を照射できます。これを38kHzで点滅するためにマイコンを使います。今回はPIC12F1822を使うことにしました。

点滅させるだけなら他にも手段はあります。例えば、タイマーICなどで38kHzを発生すればよいです。しかしデータ信号を送信するにはどのみちマイコンなどで制御する必要があります。また、マイコン1つでできるので、回路が簡単になります。

ところで、38kHzを変換すると、

\begin{eqnarray}
38KHz &=& 1sec/38000 \\
&=& 1000*1000 usec / 38000 \\
&=& 26.3 usec
\end{eqnarray}

となります。例えば赤外線LEDをPICのRA5端子でON/OFFする回路にしているなら、

    while (1)
    {
        RA5 = 1;            // 赤外線LEDをON(点灯)
        __delay_us(13);     // 13usec待つ
        RA5 = 0;            // 赤外線LEDをOFF(消灯)
        __delay_us(13);     // 13usec待つ
    }

の様なコードに処理すれば、約26usec周期=約38kHzで赤外線LEDを点滅させることができます。

PWMを使って赤外線LEDを点滅させる

上のコードは古いPICを使って赤外線通信を行う例としてよく見るコードです。PIC12F1822は(ECCPの)PWM機能がありますので、それを使ったほうがもっと楽になります。PWMの出力端子で赤外線LEDをON/OFF回路構成にし、PWM機能を使って赤外線LEDを点滅させます。

PIC12F1822はMPLABのMCCに対応していますので、PWMの周波数を狙った通りに設定することは簡単にできます。まず、MCCをオープンし、内部クロックを適当に8MHzぐらいに設定します。

次にTMR2モジュールを追加し、周期を26.5usecに設定します。

さらにECCPモジュールを追加し、Enhanced PWM機能を使う設定にします。

右下の方に、「PWM Frequency 37.73585kHz」となっていますので、約38kHzの周波数は確保できています。TMR2の周期を26usにすれば、この周波数は38.46154kHzになります。上の設定の方が38kHzに近いので、今回はこの設定を選びました。(また、PICのシステムクロックの周波数を16MHzや32MHzに上げれば、もっと38kHzに近い値にすることもできます。)

しかし、上の設定ではPWM Duty Cycleが0になっています。このままではPWM出力端子はずっと0になってしまい赤外線LEDは消灯したままです。Duty Cycleを0以外の値にすれば、PWM出力端子が発振し始め、赤外線LEDが38kHzで点滅します。つまり、Duty Cycleの値を使って、赤外線LEDの38kHzで点滅を制御することができます。

Duty Cycleの設定は、CCPR Valueを変えることでできます。そこで、以下のようなマクロ関数を用意することにしました3

/**
 * 【赤外線送信のOn】
 * PWMのパルス幅を0以外にする。
 * (制御しやすく、かつ、Duty比30%近くになる値をPWMレジスタに指定している。)
 * さらに、TMR2を0にリセットする。
 * (即座にPWMパルスが始まるようにするために、0にセットする。)
 *
 * 【赤外線送信のOff】
 * PWMのパルス幅を0にする。
 */
/**
 * 赤外線送信のOn
 */
#define IRT_On()       \
    {                  \
        CCPR1L = 0x10; \
        TMR2 = 0;      \
    }
/**
 * 赤外線送信のOff
 */
#define IRT_Off()   \
    {               \
        CCPR1L = 0; \
    }

必要に応じて適宜、IRT_On()又はIRT_Off()を実行し、赤外線LEDを制御することができます。

  1. 実はこのモジュールを私はAliExpressで購入しました。そのため本物のTL3818なのか、互換品なのかは定かではありません。ただTL3818とほぼ同等の動作をするモジュールですし、ここではTL3818ということにさせてください。 ↩︎
  2. さまざまな赤外線モジュールのDATASHEETを見ていたときに、36kHzや40kHzとなっている製品もありました。 ↩︎
  3. PIC12F1822の場合、CCPR1Lレジスタ(8bit)とCCP1CONレジスタのDC1Bフィールド(2bit)でDuty Cycleを制御します。今回はDuty Cycleを厳密に制御する必要はないので、DC1Bは0に固定し、CCPR1Lレジスタの設定のみで制御しています。 ↩︎

コメント