2014年10月16日木曜日

Arduinoでエアコン制御 3 (送信編)

送信方法の考察


候補を挙げる。

①loop()関数のdelayを絶妙に調整して送信する。△
 今回は採用しない(つもり)。
 メインのループに厳密なタイミングを求められないのは受信の際わかった。
 累積する誤差との戦いになるだろう。
 あちこちの部分でdelayを細かく設定する事になると思われる。

②PWMを利用する。
 独立した一定の波を基準にする為、調整はその周波数だけで済むはずである。
 ポーリングで少々気まぐれに処理時間が変わろうとも出力はきれいに揃うはずである。
 とはいえその周波数が微妙かもしれない…。
 望みの周波数の整数倍に近いほど有用であるが、16[MHz]動作のATmegaを高速PWMモードで分周比8とすると7.81[kHz]?
 送りたい信号は(0.4*2[ms]で)1.2~1.25[kHz]で微妙に巧くない。
 周波数を上げると有用性を減じさせる…。
 やらない(かも)。

③シリアルポートを利用する。×
 今回は偶々0.4[ms]の山(谷)が用意できれば良い為、2400[bps]で送信できないだろうか。
 (もう少し正確に言えば測定値が0.42[ms]あたりである為かなりイイ線である)
 データをデータとして送れば良い為、構造がシンプルになるのではないか。
 ただし出力はActive-Lowでビットは反転される為、送信前に反転させて出力にはトランジスタ(のnot回路)を介さなければならない。(まあ大した事ではない)
 ATtinyに手を出したとしても"SoftwareSerial"というライブラリで解決できそうだし、ATmegaであれば微妙なビットレートも設定できる(?)のだろうと思っている。

 シリアル通信の規格上スタートビット、ストップビットが8[bit]毎の情報の前後に乗ってしまう。
 レジスタを操作したところでストップビットを1か2[bit]のいずれかから選べるのみである。
 (例えばストップビットを無しにできるのなら、信号は"10"か"00"のいずれかであり必ず偶数個目が0になる為、スタートビットが0で発信されるようにして最後を切り捨てた7[bit]長のデータを送ろうとも思ったのだが…)
 最もシンプルな手段だと思ったが仕方ない…残念である。

④555でPWMを用意する。
 Arduino――ATmegaだけで完結しそうなので積極的に採用する理由は無い。
 まず、面白そう勉強になりそうなのでやってみる。
 またマイコンの16[MHz]を分周したPWMでは今回の件にマッチしない。

PWMを用いる場合

どういう手法が一般的なのかはわからないが、想定できるアイデアは下。

[a]PWM信号の立上り等を契機に1単位毎の情報を送る。
 この場合は当然PWM自体に情報を乗せられない。
 tone関数である程度の精度のHighが出力できるだろうと思われる。
 情報1単位の長さを若干短く設定しておいて後続への影響を吸収させる。
 どうもPWMの状態を示すフラグがありそうで、それを監視して即情報を送ればどうか。

[b]PWM信号以外の契機を用意して、厳密なタイミングはPWMに補正してもらう。
 つまりmicros関数を監視して若干早めのタイミングでデューティー比を変更させてはどうか。
 ただしanalogWriteはPWMの1周期を待たずにデューティー比を変えてしまう為使えない。
 それはレジスタを直接設定すればできそうである。

いずれにしてもPWM信号の1周期に対して充分に早くloop()が回っていればそれで良い。

ただ①は…なんと表現したら良いのか――質量があるような感がある。
考えてみれば結局、PWM契機から情報を出力するまでが充分に安定していてくれないといけない。
比べて②は結構(0.5周期分程度?)ぶれたところで結果には影響しなさそうである。

シリアルポートを用いる場合

こちらのアイデアには分岐は無い。
2400[bps]としたときエアコンが1と解する情報は"01"、0と解する情報は"0001"で表現できる。
このおかげで1ばかりの時と0ばかりの時で長さが変わってしまう。
もし8bitずつ増減するなら都合がよかったが、Check sumがある為に単純にいかない。
リピートを含めた情報全てを大きな変数に入れるしかないと思われる。

また温度や風向き等のビットをセットした後、上の変換を掛けなければならない。
とりあえずはExcelで変換してお膳立てをしてやろうと思うが、変換処理をマイコンでやらせるべきかどうか…

結論

①のソフトウェア的な解決が結局一番汎用性が高い。またやり方は非常にわかりやすい。
 他に部品を必要としない為よりローコストでもある。
 反面、ソースは長く見づらくなるだろうし、ある程度いい加減なタイミングでも良い場合にしか使えない。
②のArduino――ATmegaのクロックに依存する方法は周波数が合えば強力。
 合わない場合は無理にやってもあまり意味がないと思う。
③は今回に関しては結局一番の悪手。要望と仕様のミスマッチを理解していなかった。
④が一番素直な解法かもしれない。
 足りない部分を他で補う。絶妙なタイミング調整で頭を悩ませる必要はない。
 ただし100円程度とはいえ追加の部品(IC等)が出てしまう。

とりあえず今回の件に関しては今のところ、
④[555]>>>>>>>>>①[ソフトウェア]>>>>>>>>>>>>>(②[16MHzPWM])
③[シリアル通信]―×

0 件のコメント :

コメントを投稿