2015年9月9日水曜日

シーケンス入力用のデバイス コーディング完了

一通り単体でテストしてみたので全部まとめてプログラミングしてみた。

https://github.com/ryood/RhythmMachine/blob/master/Atmel%20Stduio/Sequencer_I2C_Slave/Sequencer_I2C_Slave/Sequencer_I2C_Slave.c

ブレッドボード図
※AVRはATMega88Vです。


チャタリング対策


タクトスイッチとロータリーエンコーダーの軸の押し下げのスイッチは、タイマーを使って20m秒後の状態と比較して変化がなければチャタリングではないと判断しているが、時々読みこぼすことがあるみたいなのでオシロで動作状態を見てみた。

スイッチの状態を読み取ったあと、Timer0をオーバー・フロー割り込みさせるモードでワンショットで起動している。
// Timer0を起動
TCCR0B = 0x05; // プリスケーラ-:1024, 1/(8MHz/1024)=128us
TCNT0 = 100; // 128us*(256-100)=19.968ms
TCNT0が255を超えたときオーバー・フロー割り込みがかかるので、TCNT0=0だと
128us * (256 - 0) = 32.768ms
TCNT0 = 255だと
128us * (256 - 255) = 0.128ms
になる。(実際はその他の処理が入るのでもう少し長くなる)

TCNT0 = 0の場合

赤色はLEDの列の一番左、黄色はPD0(タクトスイッチの一番左)

黄色がH->Lの変化する地点から、赤色がL→Hに変化する地点の差を目盛りで読み取ると、だいたい32ms

TCNT0 = 255の場合

同様に差を読み取るとだいたい200us=0.2msだ。

Timer0による遅延は想定通り動いているようだ。

読みこぼしの原因は、コードのその他の部分に何かバグがあるかもしれないし、スイッチ自体の動作不良かも?


I2Cの送信データ



No. Sign Size(bit) Name 説明 備考
1 unsigned 16 SEQUENCE Sequence 1..16 1バイト目のLSBがシーケンス1
2バイト目のLSBがシーケンス9
2 unsigned 8 POT1 Pot1のADC読み取り値 0..255
3 unsigned 8 POT2 Pot2のADC読み取り値 0..255
4 unsigned 8 RE ロータリーエンコーダーの値 0..255
5 unsigned 8 RE_SW ロータリーエンコーダーのSWの押し下げ状態。 0: 開放 1:押し下げ

Masterから送信要求があれば、毎回上記6バイトを送信する。

基板上で入力した値は、基板上で視認できるようにしたつもりだ。(POTはつまみの位置で)


はんだ付けはとても疲れるのでぼちぼち進めたいとおもいます。

割り込みとRTOS


今回ぐらいの規模なら割込みを逐一処理しても大丈夫だったが(と言って、ロータリーエンコーダーの処理はポーリングで行っていますが)、これ以上複雑になってくるとRTOSを使った方が良さそうな気もする。

スイッチの押し下げ状態の割込みにはAVRのPin Change Interruptを使ったが、これもTimer割込みで処理しようとすると割込みルーチンの中の処理がかなり複雑になってくる。

FreeRTOSという無償のRTOSがあって、ちょっと調べた感じではスケジューリングに特化していて軽量コンパクトな作りになっているようだ。

音源の波形生成みたいなタイミングにシビアなシステムには使いにくいが、UIの制御みたいなのにはありかも。もっと複雑なことをしたくなった場合は考えてみようと思います。