DMX受信のステートマシン化と安定受信

はじめに

PIC側を先に起動してからDMX卓をONすると、15秒程度PWM出力が暴れていました。
その後安定したら、全く問題なく普通に動作します。

やはりこの最初の十数秒間のおかしな挙動は、
商品にはできないので、DMXの安定受信を目的に、この部分を修正しました。

今回の回路図

最初に考えた対策

これまでは、フレーミングエラーをみてBreakと断定し、
スタートコードの “0x00” を見てDMX受信をさせていました。

DMX信号のBreak を数回受信してからdmx_ready = 1にして、
そこからDMXを受信することにしました。

DMX卓のON時、
暴れることなくスムーズに受信することもありましたが、
同じように暴れることもありました。
約50%ずつの確率でした。

つまり、これだけでは、完全には解決しませんでした。

DMX受信をステートマシン化

c

#define DMX_WAIT_BREAK  0
#define DMX_WAIT_START  1
#define DMX_RECEIVING   2

として、

Break待ち

Start Code 待ち

データ受信

を明確に分けました。
これで、暴れることは無くなりました!

OERRとの格闘

DMXの安定受信の為に、
OERRつまりオーバーランエラーを確認しました。

すると、しっかりとOERRは起きているように見えました。

RC3をOERR確認用出力として、LEDを繋ぎました。
RA1をISR実行時間の可視化に使いました。
このRC3、RA1に加えてRXを
オシロスコープに繋ぎ、常に状態変化を確認できるようにしました。

OERRが発生したらRC3をHにして、
OERRを可視化しました。

また、RA1をISR入口でH、ISR出口でLにすることで、
ISRの処理時間を見れるようにしました。

オシロスコープで確認しながら、
オフセットSWのIOCをコメントアウトしたり、
for文などの重たい処理をを消したり、
色々と軽くするようにしました。

結局OERRは出続けました。
下の図ではほんの少しだけ黄色がHになっている期間がみえます。

黄色:OERR 青:RX ピンク:ISR

8MHz → 16MHz

これまでは、クロック周波数を8MHzで行っていました。
ISRの処理時間にあまり余裕がないため、
OERRが起こっているのかと考えました。

そこで、ISRの処理時間に余裕を持たせるため、
8MHzから16MHzにしました。

16MHzで、IOC、for文無しで、
OERRは起こりませんでした。

IOCを戻し、for文を戻し…
と1つずつ戻していきましたが、
OERRは起こりませんでした。

途中で発生した別のトラブル

16MHzでOERRが出なくなったとき、
IOCを戻し、オフセットのスイッチを押すと、
いくらフェーダを動かしても、
PWM出力をしなくなりました。

オシロスコープに繋ぎパなしの
RA1を確認したら、
DMXが来ていないのに、
一定周期でISRに入り続けていました(下図)。

黄色:OERR 青:RX ピンク:ISR

よくよく確認したら、
原因はデバッグ中に、
IOCフラグクリア処理を消していました。

コメントアウトだけしていたつもりでも、
消してしまい、これに気付けずにいました。

もちろん、
IOCBF4とIOCIFをしっかり戻して問題はクリアできました。

最終試験

DMXの安定受信を確認するため、
次の試験を行いました。

  • 卓電源ON/OFFを繰り返す
  • フェーダを激しく操作
  • オフセットSWの操作
  • 連続DMX受信

いろいろと行いましたが、
起動時も暴れることなく、
安定して受信させることに成功しました。

黄色:OERR 青:RX ピンク:ISR

黄色(RC3)にはわずかなヒゲが見えますが、
OERR確認用LEDが点灯していないことから、
OERR処理には入っていません。

まとめ

今回、DMX受信が不安定になる原因を調べるため、
受信処理をステートマシン化し、
OERRやISRの動作をオシロスコープで確認しました。

最終的には、

  • DMX受信をステートマシン化
  • OERR発生時の受信状態をリセット
  • クロック周波数を8MHzから16MHzへ変更
  • IOC割り込みフラグのクリア処理を修正

することで、安定してDMXを受信できるようになりました。

今回特に勉強になったのは、
プログラム上では問題なさそうに見えても、
実際の処理時間や割り込みの状態を確認しなければ
分からない不具合があるということでした。

オシロスコープでISRの実行時間まで確認したことで、
原因を一つずつ切り分けることができました。

今回使用したプログラム全体はGitHubで公開しています。
GitHub:stable_dmx_receiver.c

コメント

タイトルとURLをコピーしました