前回は赤外線を受信・送信するために最低限必要なハードウェア(マイコンボード)を試作しました。
今回は赤外線の送信・受信を実際に行うために必要なプログラムを作成し、マイコンボードに書き込んで動作テストを行ってみます。
-
-
【自作】PICマイコンで赤外線学習リモコンを自作する①:試作基板作成
Youtube動画上げたいな~とか言い出して3本上げたら1年たってました。 三日坊主、極まれり。 Youtube もう一回やる 1年目に3本動画を投稿して力尽き、あれから1年が経過した。。。。 だが今 ...
続きを見る
前回まで
前回まで決めた内容は以下の通り。
概要、構成としては以下のような感じです。
![](https://aisumegane.com/wp-content/uploads/2024/05/image-11-1024x593.png)
機能的な部分は右下の内容で仮確定してハードを作ったので、今回はその内容を実現するプログラムを作っていきます。
プログラムの全体の構成を考える
最初にプログラムの構成を考えてみます。
今回の赤外線学習リモコンでは、ボタンごとに3つの機能があります。
それぞれ別の機能ではありますが、以下の3つについては共通になります。
①操作入力関係:スイッチ押したり、動作を分岐させたり・・・
②表示出力関係:LEDを点灯させたりとか、ディスプレイに文字を表示させたり・・・
③ロジック関係:赤外線信号を受信し、コピー/編集/送信するプログラム
今回は①と③をざっくりまとめてみたいいと思います。
②の表示関係のプログラムはネット上にも情報がたくさんあるので割愛します。
①操作入力関係の処理内容を作成する
最初に①の操作入力関係の処理を作成します。
スイッチが押されたら、それぞれの処理に遷移するようにする
今回は以下の3つの機能を割り当てたので、それぞれの処理ごとに分岐させます。
1:赤外線信号のコピー処理に遷移させる
2:コピーした赤外線信号を送信する処理に遷移させる
3:赤外線信号送信時のサブキャリア周波数※を変更する処理に遷移させる ※後述
スイッチが押されていない場合は、特に処理を行わず、無限ループ内で待機させることにします。
マイコン起動後からの流れ
マイコン起動後からの流れは以下のようにしてみます。
マイコンに電源が入る
↓
マイコン周辺機能を設定するプログラムを動作
↓
無限ループに入り待機
↓
何らかのボタンが押されたら、その処理へ分岐
↓
分岐先での処理が全部完了したら、無限ループに戻り再び待機・・・・
分岐の図
上記で述べた点をざっくり図で表してみます。
無限ループ内では基本的に何もしませんが、スイッチが押されたことを検知する必要があるのでその処理だけいれます。
![](https://aisumegane.com/wp-content/uploads/2024/05/image-16-1024x536.png)
今回は分岐先での動作を複雑にしたくなかったので、1つのスイッチを押しているときはその他のスイッチの入力を無視するようにしました。
今回はスイッチが3つしかないうえに、機能もとてもシンプルなのでこんなもんで良いかと思います。
基本的には無限ループ内で待機、ボタンが押されたらスイッチ文を使って分岐する単純なものにしてみました。
プログラムは最後にまとめて載せました。
③ロジック関係の処理を作成する:赤外線信号のコピー処理の作成
次は①の操作入力があった際、その後の分岐先で実行する処理の内容について作成します。
最初の図の中に書いていますが、今回作成する処理は以下の3つになります。
●赤外線信号をコピーする処理
●コピーした赤外線信号を送信する処理
●赤外線送信時のサブキャリア周波数を変更する処理
まずは赤外線信号をコピーする処理からです。
前座:赤外線通信の内容について
赤外線信号でいろいろ遊ぶ前に、まず赤外線通信についての概要を勉強してみました。
以下の記事で概要をざっくりまとめてみたので、興味があればどうぞ。
今回はこれをベースにして話を進めてみたいと思います。
-
-
【調査】赤外線通信の仕組みを紹介する
今回は家電などのリモコンに使われている、一般的な赤外線通信の仕組みを調べてみたのでまとめます。 赤外線通信を調べる 赤外線通信って一番身近、かつ誰の家にも車にもある(リモコンがあるならどこにでもある) ...
続きを見る
赤外線通信のフォーマットに関する詳細は以下の方のサイトで紹介されていました。
日本向けだとだいたい同じような規格になっているらしいですが、
海外製の機器だと全く異なる通信方式になっている、なんてこともあるらしい。。。
赤外線信号をコピーする方法を選ぶ(2択)
まず最初に赤外線信号をコピーする処理を作成します。
方法はいろいろありますが、個人的に以下の2つに大別できるかなと思います。
①赤外線通信で送られるデータを抽出&コピーし、記憶する
②赤外線通信号をそのままコピーする
学習リモコンは市販品のものもありますが、①の方法をとっているものが多いようです。
概要は以下のようになります。
![](https://aisumegane.com/wp-content/uploads/2024/07/23-1.jpg)
![](https://aisumegane.com/wp-content/uploads/2024/07/30.jpg)
判別後はデータの内容を表す部分の点滅パターンを確認し、抽出&保存します。
![](https://aisumegane.com/wp-content/uploads/2024/07/28-e1721882895977.jpg)
リモコンの赤外線の発光パターンから、どのメーカーのフォーマット(言語)かを判別し、中にあるデータだけをコピーしておく、そんなイメージであっているかなと思います。
この方法のメリット、デメリットは以下のようになります。
・データ(数値)だけを覚えておけばよいので、たくさんの信号を学習できる
・本来は使えないデータ(数値)を、特定の通信フォーマット(言語)で送ることができる ※家電のメンテナンスモードにアクセスする、等
・送信機器の赤外線LEDの発光パターンを識別し、言語を割り出すプログラムが必要
・学習リモコンがあらかじめ照会用に用意している通信フォーマット(知っている言語)ではない信号が来た場合、認識できない
今回は覚える信号は1つしかなく、マイコンもスペックが低いものを使用しているため、(+言語の判定などのプログラム作成が面倒なため)この方法は微妙です。
そこで②の赤外線信号をそのままコピーする方法を使ってみたいと思います。
赤外線信号はメーカーや規格の種類などによって、以下の例のように通信フォーマットが分かれていることは以前の記事で紹介しました。
![](https://aisumegane.com/wp-content/uploads/2024/07/29.jpg)
一見全く異なる信号に見えますが、これを単なるLEDの点滅ととらえるとすべて同じような信号とみなせます。
![](https://aisumegane.com/wp-content/uploads/2024/07/34.jpg)
上の図で示した"単に赤外線LEDがON / OFFしているだけの信号"について、横の時間軸の情報を付け加えると、以下のようになります。
![](https://aisumegane.com/wp-content/uploads/2024/07/35.jpg)
こうしてみると、どんなメーカーも関係なく、ON/OFFと時間の情報だけを持った共通の信号とみなせます。
先ほどは通信フォーマットという枠の中で"データ"と定義されている部分の赤外線LEDの点滅パターンを確認し、中身のデータをコピーしましたが、今回は最初から最後まで、すべての赤外線LEDの点滅を"私が考えるデータ"として、丸々保存します。
この方法のメリット、デメリットは以下のようになります。
・理論上、すべての赤外線通信をコピーすることが可能(通信フォーマットに依存しないため)
・プログラムが比較的単純
・1つのデータにつき、多数のON/OFFと時間のデータを保存する必要があるため、容量が食う
・元の信号に対する再現性がハード依存(どれくらいの時間の分解能でデータを保存できるかは、マイコンに依存してしまうため)
今回は1つの信号しかコピーしないので、容量が食う問題はまあまあ無視できます。
元の信号に対する再現性は今回採用したPIC16F1827のスペック上、問題なさそうでした。
今回は②の赤外線信号をそのままコピーする方法、を採用したいと思います。
赤外線通信(赤外線LEDの点滅パターン)から余計な情報を省く
次は実際に赤外線信号をコピーしていくわけですが、そのまま赤外線信号をマイコンにぶち込むとON/OFFの誤判定が起こります。
これは以前の記事で紹介した、赤外線信号に含まれるサブキャリア周波数でのON/OFFによるものです。
実際に波形を確認してみると以下のような感じです。
(黄色:生の赤外線信号のONの区間、水色:マイコンがONと認識している間はHレベルを出力)
![](https://aisumegane.com/wp-content/uploads/2024/05/RigolDS3-1.jpg)
これだと赤外線LEDが発行している期間もOFFと誤判定し、コピーしたかったON/OFFのパターンではないものを取得してしまいます。
このため前回紹介したコンパレータ回路で一定電圧以下を切り捨てます。
![](https://aisumegane.com/wp-content/uploads/2024/05/image-9.png)
この回路により、2.5Vを基準として、正しいON/OFFになるように波形が修正されます。
![](https://aisumegane.com/wp-content/uploads/2024/07/18.jpg)
この回路を組み合わせてマイコンに赤外線LEDの信号を入れると下記のようになります。
![](https://aisumegane.com/wp-content/uploads/2024/05/RigolDS8.jpg)
サブキャリア周波数による振動の影響を含まない、正しいON/OFFになったことが確認できました。
割込みを使って赤外線信号をコピーする
前置きが長くなってしまいましたが、次は実際に赤外線信号をコピーする処理を作成します。
今回は信号のコピーの方法として、様々な通信フォーマットで送られてくる赤外線信号=赤外線LEDの点滅パターンを、ON / OFF と時間の情報を使って丸ごと記録することにしました。
実際の処理は言葉のまま、時間の情報を配列に保存していくことで実現します。
![](https://aisumegane.com/wp-content/uploads/2024/05/image-23-1024x516.png)
時間を得る方法ですが、これはマイコンのタイマ機能を使います。
タイマ機能はマイコンに搭載された機能の一つで、ひたすら時間を数える機能です。
タイマ機能のイメージは下記になります。
![](https://aisumegane.com/wp-content/uploads/2024/05/image-5-1024x549.png)
上記の図で、XとYは自分で決めることができます。
今回はこのカウントアップの回数を赤外線LEDのON / OFFの区間ごとに数えて記録します。
処理の流れとしては以下のようになります。
1.マイコンのピンにHレベルの入力がされたら(赤外線LEDの点灯を認識したら)、カウントアップを開始
2.マイコンのピンがHレベル→Lレベルに変化したら(赤外線LEDの消灯を認識したら)、それまでのカウント数を保存、
カウント数をリセットして再度0からカウント開始
3.マイコンのピンがLレベル→Hレベルに変化したら(赤外線LEDの点灯を認識したら)、それまでのカウント数を保存、
カウント数をリセットして再度0からカウント開始
以降、2と3を反復
赤外線信号=赤外線LEDの点灯パターンのコピーを始めるときは必ずHレベルなので、送信時はHレベルから始めればあとは反転、反転、反転、、、で信号を再現できます。なので今回はON/OFFの情報は保存しないことにします。
またリモコンなどではボタンを一回押すごとにひとまとまりのデータが連続して送られますが、送信完了すると次にボタンを押されるまで赤外線LEDを消灯させたまま変化しなくなります。(数赤枠がボタンを押したあとの一回の送信、その後はLレベルのまま待機になる)
![](https://aisumegane.com/wp-content/uploads/2024/07/57-e1721887924129.jpg)
よって一定時間以上経過したら、タイムアウト(受信完了)として処理を終了することにします。
処理全体、処理に使う各変数の初期化やタイムアウト処理の実装内容をまとめてみると、以下のようになりました。
![](https://aisumegane.com/wp-content/uploads/2024/07/43.jpg)
受信処理の内容は以上です。
③ロジック関係の処理を作成する:赤外線信号の送信処理の作成
次に取得した赤外線信号のデータを送信する処理を作成します。
送信時の処理は基本的に受信時と逆のことをするだけになります。
具体的には、配列に保存した時間情報をもとにタイマ機能を使用してカウントを行い、
一定時間経過するごとに出力のH / L レベルを反転します。初回は必ずHレベルで出力すれば、元の信号と同じパターンになるはずです。
![](https://aisumegane.com/wp-content/uploads/2024/07/49-e1721888189105.jpg)
出力の反転は受信処理と同じようにタイマ処理を使って行います。
タイマ機能には複数の種類があり、今回使用するPIC16F1827ではCounter/Compare/PWMの3種類が使えます。
今回はある値をセットしたら0になるまでひたすらカウントダウン、0になったら割込み発生、、、、というCompareモードを使用します。
処理の流れとしては以下のようになります。
1.保存した赤外線LEDのON / OFF時間 data[n]をカウントダウンの開始値に設定し、カウントダウンをスタート
この時、マイコンの出力ピンをHレベルで出力する
2.カウントダウンを行い、0に到達したら、マイコンの出力ピンをLレベルへと反転する
この時、保存した赤外線LEDのON / OFF時間 data[n+1]をカウントダウンの開始値に設定し、カウントダウンを再度スタート
3.カウントダウンを行い、0に到達したら、マイコンの出力ピンをHレベルへと反転する
この時、保存した赤外線LEDのON / OFF時間 data[n+2]をカウントダウンの開始値に設定し、カウントダウンを再度スタート
以降、2と3を反復
ここまでで送信処理終了、と言いたいところなのですが、一つ問題があります。
今回出力する送信データは、ただのHまたはL信号となっており、以前の記事で紹介したサブキャリア周波数による変調が入っていません。
(受信処理において、データを正しく受信するためにコンパレータ回路を用いてキャリア周波数の成分をなくしたため)
そのためサブキャリア周波数による成分(ギザギザの振動)を追加し、以下のように出力信号を修正する必要があります。
![](https://aisumegane.com/wp-content/uploads/2024/07/49-1-e1721889253721.jpg)
サブキャリア周波数の成分の追加する方法ですが、これにはマイコンのタイマ機能のモードの一つであるPWMモードを使用します。
マイコンでタイマ機能を利用したPWMを行うイメージは、以下のようになります。
![](https://aisumegane.com/wp-content/uploads/2024/05/image-7-1024x599.png)
※別の記事の画像を使いまわしているので平均電圧云々の話が出ていますが、それは無視してパルス幅が変わることだけイメージできれば問題ないです。
マイコンのタイマ機能のカウントアップ値が一定値に到達したら、出力を反転する、そんなイメージです。
以前の記事で紹介しましたが、サブキャリア周波数はだいたい38kHz周辺になります。dutyは 30% くらいです。
指定した条件でPWM出力ができるようにマイコンの設定を行います。
あとはデータがHレベルになった時だけPWM出力を行い、そのほかはLレベルで固定するようにすれば、元の信号と同じものが再現できます。
受信した信号はサブキャリアによって振動した際0Vまで落ち切っていませんが、これは受信回路の問題なので、実際には0Vまで落として出力してOKです。
(受信側の信号がなまって2.5Vぐらいまでしか下がっていない状態で再びHレベルになるので、ギザギザの波形になります。)
送信処理全体・処理に使う各変数の初期化など、実装内容をまとめてみると以下のようになります。
一番下の”PORT 送信信号”が、実際マイコンから出る出力=作成したマイコンボード上の赤外線LEDの点滅になります。
![](https://aisumegane.com/wp-content/uploads/2024/05/image-21-1024x554.png)
③ロジック関係の処理を作成する:サブキャリア周波数変更処理の作成
最後にサブキャリア周波数の変更処理を作成します。
先ほどサブキャリア周波数でデータのHの区間をPWMして出力する処理を説明しましたが、今回はこのサブキャリア周波数も変えられるようにします。
以前の記事で赤外線送信はサブキャリア周波数が送信側と受信側であっていないと信号のやり取りができないことを紹介しました。
なのでサブキャリア周波数が固定だと、その周波数を利用した機器でしか信号の送信ができなくなります。
今回は信号の受信方法として、通信フォーマットを無視してコピーできる理論上最強のタイプにしたので、送信処理についてもなんでも対応できるものにしたいです。
よって以下のような処理を追加したいと思います。
1.デフォルトのサブキャリア周波数を 38kHz に設定しておく
2.周波数変更ボタンが押されたら、サブキャリア周波数を 1kHz 上げる
3.53kHz まで到達したら、38kHzにリセットする
具体的な処理の内容ですが、PWMのサブキャリア周波数を変更し、それに応じてdutyが30%になるように変更する、といった方法をとってみました。
周波数変更処理の実装内容をまとめてみると、以下のようになります。
![](https://aisumegane.com/wp-content/uploads/2024/05/image-22-1024x603.png)
実装&テスト
今回はPICマイコンなのでMPLAB Xでデバッグ、PICKIT3で書き込みを行ってデバッグを行いました。
環境整備等は以下の記事で紹介しています。
-
-
【PIC】MPLABで作成したプログラムをPICKIT3で書き込む方法を紹介する
あまり新しい情報がなかったのでまとめてみました。 開発環境(ソフト)->開発環境(ハード)->プロジェクトの作成->実際に書き込みの順で書いてあります。 多少参考になるかもしれん。 環境整備とかからち ...
続きを見る
余談ですが、書き込みの時4.75V程度にすると書き込み失敗がないみたいです。
純正品が販売されてないのでAlliexpressで購入したパチモンを使ってますが、5V付近になると出力が安定しないみたいでしょっちゅうエラー出るんですよね・・・
赤外線信号の受信処理のテスト
話を戻しますがいざ検証。
果たしで受信できるか・・・・
![](https://aisumegane.com/wp-content/uploads/2024/05/a6d2c6b7acdb33ab5efcfe9620ae94cf.jpg)
受信できてそう。
黄色い波形が生の赤外線信号をコンパレータ回路でフィルタリングした後のデータです。
受信が完了したら青色の波形がL➡Hになるようにプログラムを組んでいます。
赤外線信号の送信が完了してから受信完了となるまで、微妙な長さの遅延があるのが気になるところです。
ただ正直受信はデータを取り込んでるだけなので、パッと見マイコン内のデータがどうなっているのか、いまいちわかりません。
送信してみないと何とも言えなそうです。
赤外線信号の送信処理のテスト
次はマイコン内部に保存した信号を出力してみます。
果たして正しく送信できるか・・・・
![](https://aisumegane.com/wp-content/uploads/2024/05/76d83e021afc17408ce681ad2527be7a.jpg)
ウム。送信成功。
できている!!!、送信できているぞッ!!!!
通信のプロトコルとか何にも勉強してないけど、見た目だけならそれっぽくできているぞぉ!!!!!
黄色い波形が保存したデータを吐き出したもの、ピンク色の波形がサブキャリアによって刻んだ後の波形になります。
適当に試作した基板なのでノイズの影響がマイコンに影響しているのか、へんなヒゲがいっぱい立ってますが・・・
![](https://aisumegane.com/wp-content/uploads/2024/05/ab5c3488702d2ecb470d2eb1cd3ef92c.jpg)
波形の再現はできているので、ヨシ!!
とりあえず意図した動作はできてそうですが、問題点もありました。
一回送信した後に、長周期のゴミデータが出力されます(波形の右側)。
おそらく信号の受信完了までの間で無限にカウントをしてデータを受信してしまっているのかもしれません。
受信完了の反転がイマイチなのかもしれない。。。。
0.1秒程度で送信は完了するはずなんですが、なぞに10秒くらいかかるので、この辺は解決しないと使い勝手が悪そうです。
この後実際に家電に向けて送信してみましたが、ちゃんと動作はしました。(ただし少し遅延あり)
まとめ
今回は叡智な丸暗記という方法で、通信のフォーマットを無視して赤外線信号を学習できるプログラムを作ってみました。
結果としては、(動いたので)OK。
バグについては致命的とまでは言いませんが、送信のたびに10秒程度待たなければならず使い勝手が悪いため、何とか解決してみます。
それでは、また。
次は試作した基板をプリント基板に再度設計しなおして、業者に発注します。
-
-
【自作】PICマイコンで赤外線学習リモコンを自作する③:基板設計・組み立て
前回までで試作したマイコンボードを用いたソフトの作成・デバッグが完了しました。 完全にバグは消えていませんが・・・・・ 今回は試作した基板を参考に、から完成形の基板を作っていきたいと思います。 基板を ...
続きを見る
ソースコード
まだつくり途中なのでピン配置等違いますが、最終的に整理します。
もし作ってみたい方がいましたら、copydata.c、senddata.cは多少参考になる、、、かもしれません。
(だいぶソースが汚いので読みにくいと思います・・・・)
基板データ、筐体データ等もまとめてドライブに上げる予定なので、最終的には電子工作キットみたいな具合にまとめたいな~と野望を抱いております。