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秒おきに繰り返し送出 } }