2-6.赤外線リモコン送信《Remo》
電気回路と電子工作
《LED仕様》
LED電流(順電流IF) : 300 mA
LED電圧(順電圧VF) : 1.6 V
ESP32-DevKitC端子の出力では電流が弱いことから、トランジスタを用いて小さな電流で大きな電流を制御します。
《トランジスタ仕様》
Base- Emitter Saturation Voltage (VBE) : 1.2 V
DC Current Gain (hFE) : 100
上図のようにトランジスタには、エミッタ、コレクタ、ベースの3本のリード線があり、ベースによりコレクタ〜エミッタ間の電流を制御します。
GPIO32の出力をON/OFF制御することで赤外線LEDをのON/OFF制御します。このため、配線はエミッタにGNDを接続し、コレクタに赤外線LED、ベースに1kΩを介してGPIO32端子を接続します。
接続抵抗を計算
【ベースに接続する抵抗】
①赤外線送信LEDに流したい電流【コレクタ〜エミッタ間電流】
⇨ 300mA
②ベースに流したい電流 300mA / 100(hFE)
⇨ 3 mA
③ベースに設置する抵抗
(3.3 V – 1.2 V) / 3 mA = 0.7 KΩ ⇨ 約 1 KΩ (茶黒赤金)
GPIO32端子からベースに小さな電流を流すことでコレクタ〜エミッタ間の赤外線LEDに流れる電流を制御します。
【LEDに接続する抵抗】
赤外線LEDに接続する抵抗はこちらの通りLEDの順電圧と順電流から同様に算出します。
(5V-1.6V) / (0.3A ) ≒ 10Ω (茶黒黒金)
となりますので、10Ωの抵抗を接続します。
【ESP32-DevKitCの入出力端子はこちらを参照下さい】
LEDのリード線は長く、長さも一定でないので、適切な長さにニッパーで切り揃えてください。また、3つのLEDはリード線を折り曲げて方向を適宜変更して取り付けて下さい。
取り付け後のイメージについては全てのセンサを取り付けたこちらを参考にして下さい。
スケッチ(制御ソフトウェア)
10秒間隔で赤外線リモコン信号を送信するスケッチは以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
// IoT電子工作キット // 2-6.赤外線リモコン送信 const byte IR_S_PIN = 32; // ①GPIO32で送信制御 // ②送信データを設定 unsigned short irData[] ={ 347,172,40, ... ,41,175 }; // ### 【データ書換が必要】 ### // ③起動時の初期設定 void setup() { Serial.begin(115200); Serial.println(); pinMode(IR_S_PIN, OUTPUT); } // ④赤外線リモコン信号を10秒間隔で繰り返し送信する void loop() { irSend (); // ⑤赤外線送信する関数を実行 Serial.println("SndOK"); delay(10000); // ⑥10秒間Wait } // ⑦赤外線送信処理 void irSend () { // ⑧ローカル変数定義 unsigned short irCount = 0; // HIGH,LOWの信号数 unsigned long l_now = 0; // 送信開始時間を保持 unsigned long sndt = 0; // 送信開始からの経過時間 // ⑨HIGH,LOWの信号数を計算 irCount = sizeof(irData) / sizeof(irData[0]); // ⑩送信開始時間を取得 l_now = micros(); // ⑪0,1の信号回数分をFor文でループ for (int i = 0; i < irCount; i++) { // ⑫送信開始からの信号終了時間を計算 sndt += irData[i]; do { // ⑬iが偶数なら赤外線ON、奇数ならOFFのまま // ⑭キャリア周波数38kHz(約26μSec周期の半分)でON時間で送信 digitalWrite(IR_S_PIN, !(i&1)); microWait(13); // ⑮キャリア周波数38kHz(約26μSec周期の半分)でOFF時間で送信 digitalWrite(IR_S_PIN, 0); microWait(13); // ⑯送信開始からの信号終了時間が超えるまでループ } while (long(l_now + (sndt * 10) - micros()) > 0); } } // ⑰マイクロ秒単位で待つ void microWait(signed long waitTime) { unsigned long waitStartMicros = micros(); // ⑱指定されたマイクロ秒が経過するまでWhileでループ処理(待つ) while (micros() - waitStartMicros < waitTime) {}; } |
スケッチで最初に赤外線LEDを制御する端子を①で設定しています。②の送信データは2-5.赤外線リモコン受信のシリアルモニターに表示された「347,172,40,・・・」を行の最後まで取得し、行の最後のカンマ(,)を削除し貼り付けて下さい。
信号あり・なしの継続時間を表した値になりますので、その時間間隔に従って信号あり/なしを交互に送信します。
setup関数はパソコンとのシリアル通信開始と端子設定を行なっています。
loop関数は10秒間隔でリモコン信号を送信する関数irSend(⑦)を⑤で繰り返し呼び出し実行します。
irSend関数内で赤外線リモコン信号を送信しています。まず、②で設定した全データ長を1個のデータ長で割ることで全体の個数(配列数)を⑨で計算しirCountに格納しています。この個数だけ信号あり・なしの数がありますので、その数を⑪のfor文で繰り返し処理します。⑩で信号送信の開始時間を取得し保持しています。
⑪のfor文では信号あり・なしの時間長が取得できますので、do〜while文は⑯で時間経過が終了するまで実行されます。⑬「digitalWrite (IR_S_PIN, !(i&1));」でiが偶数の時にHIGH(1)、iが奇数の時にLOW(0)がdigitalWriteでGPIO32端子をON/OFF制御します。「i&1」はビット演算でiを1とANDを取っていますので、iの最終bitである0or1を取得しています。
「!」はbitを反転を表していて、0は1へ、1は0へ反転させています。このため、iが0の時は「!(i&1)」は1(HIGH)を出力し、iが1の時は「!(i&1)」は0(LOW)を出力します。iが2以降も同様に⑬でHIGHとLOWが順次交互に送信されます。
⑬digitalWriteで設定した状態を「microWait(13);」で13μsそのままWaitして継続する処理をしていて、HIGHならHIGHの状態、LOWならLOWの状態を13μsそのまま維持します。次に⑮「digitalWrite(IR_S_PIN, 0)」はLOWの状態にし13μsそのまま維持します。これはリモコン信号のキャリア周波数が38KHz(26μs周期)で送信しているために13μs毎で信号のON/OFFするために実施しています。(信号ありの場合はHIGH/LOWを13μ秒毎に繰り返し、信号なしの場合はLOWの状態のまま)
このように②で設定したデータを元に⑪のfor文で最後まで処理しリモコン信号を送信しています。