mbedからエアコンを操作 その3

先日赤外線通信できたよ!という記事をソースコード付きで書いたところ以下のようなコメントを頂きました。

pwmにLEDを付けてオンオフしたらトランジスタを省略できないでしょうか?

読んだ瞬間おお!と思いました。
要は前までの方法だと信号の"1"と"0"をそのままLEDに出力し、そのLEDのカソードを変調用のPWM波が入力されているトランジスタに接続して変調をしていました。ですが今回の方法ではPWMの出力ピンに直接LEDを接続し、信号の"1"、"0"に合わせてプログラム中でPWMのON/OFFを切り替えるというものです。これならトランジスタとmbedのピンを1本減らせます。

上が今回の回路、下は従来の回路です。このようにトランジスタとピンが省略できました。

図1 今回の回路

図2 従来の回路


mbedの1ピンあたりの最大出力電流は40mAなようなので、その辺には十分注意する必要はありそうです。


ソースコードはこのようになりました。
前回bool型の配列を10,000個用意し50us毎にサンプリングしていましたが、あまりにもメモリの使用量が多かったので配列を3,500個でサンプリング周波数は100usにしました。これでも問題なく動作しました。

  • IR.h
// IR.h
// 2010/12/16 ver1.0
// 2010/12/22 ver1.1 send data from PWM-pin. remove DigitalOut-pin
// IR controller data read and send

#define IR_DATA_COUNT 3500
#define IR_SAMPLING_US 100
#define IR_MOD_FREQ_KHZ 38

// class IR
class IR
{
    private:
        bool data[IR_DATA_COUNT];
            
    public:
        // constructor
        IR(PinName inPin, PinName pwmPin) : IRin(inPin), IRpwm(pwmPin)
        {
            float value;
            value = (1.0 / IR_MOD_FREQ_KHZ) * 1000.0;
        
            IRpwm.period_us(value);
            IRin.mode(PullNone);
        
        }
        
        // getData
        void getData(void)
        {        
            while(1) {
                if(IRin == 0) {
                    for(int i = 0; i < IR_DATA_COUNT; i++) {
                        data[i] = !IRin;
                        wait_us(IR_SAMPLING_US);
                    }
                
                    return;
                }
            }
        }
        
        // sendData
        void sendData(void)
        {        
            for(int i = 0; i < IR_DATA_COUNT; i++) {
                if(data[i] == true) {
                    IRpwm.write(0.5);
                } else {
                    IRpwm.write(0);
                }
                wait_us(IR_SAMPLING_US);
            }
            
            IRpwm.write(0);
        }
        
    protected:
        DigitalIn IRin;
        PwmOut IRpwm;
};
  • main.cpp
#include "mbed.h"
#include "IR.h"

DigitalOut led1(LED1);
DigitalOut led2(LED2);
IR ir(p8, p21);     // (in, pwm)

int main() {
    led1 = 1;
    
    ir.getData();    // リモコンから信号の読み取り
    
    led2 = 1;
    
    while(1) {
        ir.sendData();    //信号の出力
        
        wait(1);    // 1秒おきに繰り返し送出
    }
}