Show page source of ギタコン試作2 #110330

[[PageOutline(start=3)]]


== ギタコンの自作 試作2
[ギタコン試作1]で出たいくつかの問題を修正します。
(ギタコン作成のための環境構築が既に終わっているので、ここから先は楽ちんです)




=== 試作1の問題点一覧
 1. 最初のキーアサイン時に、なぜかLEFTが自動設定されて、上入力が入りっぱなしになる
 2. 反応が悪い(反応が遅い)
 3. チャタリングする
 4. ボタン(スイッチ)が小さすぎて、使いにくい (これは試作3で対応します)
 5. ボタンが足らない (これも試作3で対応します)
 6. ピックをスティックにしたい (これも試作3で対応します)
 7. 配線が操作の邪魔 (試作4で対応します)
 6. コントローラーを動かしてのwailingができない (試作4で対応します)
 7. 筐体が無い (試作5で対応します)

ここでは、1~3について改善をしていきます。

=== 最初のキーアサイン時の動作異常を改善する
「最初のキーアサイン時に、なぜかLEFTが自動設定されて、上入力が入りっぱなしになる」現象について。
これが発生する理由は、Joystick Libraryの仕様上、軸入力(X,Y,Z)が全部(中央値ではなく)0で初期化されるためです。
X軸の入力における0は左を、Y軸の入力における0は上を意味するため、
キーアサインの変更を始めた瞬間にまずX軸入力(0=左)が取り込まれてLEFTがアサインされ、
その後Y軸入力(0=上)に反応して上が入り続けます。

# 左も入りっぱなしになっていますが、キーアサインの画面で左を入力しても意味がない


この現象は、Joystick Libraryに「軸入力は使わない」ことを(Joysick_クラスのコンストラクタで)宣言することで、発生させなくすることができます。

具体的には、以下のようにします。

JoystickButton.ino のスケッチを開いて、14行目あたりを
{{{
Joystick_ Joystick();
}}}
から
{{{ html
<pre>
Joystick_ Joystick(<font color="red">
  JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD,
  4, 0,                 // Buttons, Hat Switch Count <font color="red">ボタンの数を4から6に増やす</font>
  false, false, false,  // X,Y,Z Axis
  false, false, false,  // Rx, Ry, Rz Axis
  false, false,         // rudder, throttle
  false, false, false   // accelerator, break, steering</font>
);
</pre>
}}}
に変更します。 
これで、「ボタンを4つ使い、それ以外の軸入力は使わないジョイパッド」として動作するようになるため、
先の問題は発生しなくなります。

スケッチを修正したら、「検証」と「マイコンボードに書き込む」ことをお忘れなく。

また、このスケッチはこれまでとは別のファイル名で「名前を付けて保存」しておくのが良いです。
(これからの試作でこのスケッチをどんどん修正していくので、サンプルファイルとは別のファイルとして保存しておくべきです)


なお、一度スケッチをArduino Microに書き込んでしまうと、以後はCOMポートがPCに認識されなくなり、
書き込みに失敗するようになります。そのため、書き込みのタイミング(マイコンボードに書き込んでいます、と表示されたタイミング)でAruduino Microのリセットボタンを2連打してください。
するとしばらくの間だけCOMポートがPCに認識され、書き込みができるようになります。
ただ、この時にCOMポートの番号が以前と変わるようですので、一度リセットボタンを2連打してポート番号を確認してから
「ツール」 - 「シリアルポート」 を設定し直して、そのあとでもう1度リセットボタンを2連打して、書き込みを実行するとよいでしょう。

=== 反応が悪いのを改善する
試作1のギタコンを使ってみてすぐにわかることは、ボタンの反応が悪いこと。

こうなる理由は簡単で、Arduino Microでのボタンのスキャン間隔が50msになっていることです。
(3フレーム描画する毎に1回、ボタンの入力をチェックしているような状態)

これも、スケッチの修正で対応できます。先ほど使ったスケッチを開いて、最後にある

{{{
  delay(50);
}}}
を、
{{{ html
<pre>
  delay(<font color="red">1</font>);
</pre>
}}}
にします。これで、1ms毎にボタンがスキャンされるようになりました。簡単ですね。

=== チャタリングを改善する

チャタリングとは、簡単に言うと、ごく短時間の間にスイッチのON/OFFが連続して入ってしまう現象のことを指します。

具体的には・・・例えばスイッチを押してONにしたときの動作を考えてください。
金属の接点がつながって電流が流れるようになりスイッチがONになる・・・のですが、
このスイッチがつながる瞬間に、物理的に金属が振動して、ごく短い時間(数ms~数十ms)の間だけ、ONとOFFが数回切り替わってしまうのです。
人間はこの切り変わりが速すぎて気づきませんが、コンピュータはこの変化を検出して、コントローラーの入力としてのON/OFFを切り替えてしまいます。

ここまでの説明でお分かりかと思いますが、チャタリングが (入力がシビアな音ゲーで使う) ギタコンで発生するのは、致命的ですよね。

[[Thumb(chattering01.png, size=368x240, caption=理想的なスイッチの動作。スイッチをONにした瞬間に、その状態が反映される。)]] 
[[Thumb(chattering02.png, size=380x339, caption=現実のスイッチの動作。スイッチをONにした後しばらくの間、状態がふらつく。)]] 


# ちなみに、試作1で使ったタクトスイッチの場合、この振動時間は最大5msとのことです。([http://akizukidenshi.com/download/ds/cosland/DTS-6-V.PDF 同タクトスイッチの仕様書]より。)

さて、それでは、この問題をどのように解決すればよいのでしょうか。

ソフトウェアでの解決策と、ハードウェアでの解決策があります。

ソフトウェアでの解決策は、「ボタンの状態が切り替わったら、以後数msの間は、万が一状態変化があっても無視する」ようにすることです。
これはArduino Micro側でスケッチを修正して対策してもよいし、DTXMania本体のソースコードを修正して対策してもよいです。

[[Thumb(chattering03.png, size=356x167, caption=チャタリングの改善例。スイッチをONにした後しばらくの間、状態変化をわざと無視する。)]] 


以下、Arduino Micro側のスケッチでチャタリング対策をした例を挙げます。具体的には、あるボタンの状態が変化したら(OFF→ONになったなど)、10msの間は状態を変化させないようにしています。(私はどう頑張っても20msより速くボタンを連打することができませんでした。そのため、その半分の10msで閾値を設定しておけば大丈夫かなと思いました。まる。)

{{{ html
<pre>
(中略)

// Last state of the button
int lastButtonState[4] = {0,0,0,0};
<font color="red">unsigned long lastButtonChangedTime[4] = {0,0,0,0};</font>

void loop() {

  // Read pin values
  for (int index = 0; index &lt; 4; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
<font color="red">      unsigned long t = millis();

      if (t &gt; lastButtonChangedTime[index] + 10)
      {</font>
        Joystick.setButton(index, currentButtonState);
        lastButtonState[index] = currentButtonState;
<font color="red">        lastButtonChangedTime[index] = t;
      }</font>
    }
  }

  delay(1);
}

</pre>
}}}



なお、ハードウェアでの解決策は・・・RSフリップフロップ回路の追加やシュミットトリガ回路や・・・なんですが、「簡単さを最優先にしてギタコンを作る」というコンセプトから外れるため、ここでは説明を省略します。

なお、通常よく使われるチャタリング対策は、「ON/OFFの状態が安定するまで待つ」というものです。この場合、安定するまでの時間が入力遅延となります。一般的な用途では数十ms程度の入力遅延が許容されることが多いため、その方法で問題が出ないのですが、ギタコンでのチャタリング対策としては当然ながら使えません。ご注意ください。(例えば、「ハードウェアでの解決策」の例で挙げた「シュミットトリガ回路」は、遅延が発生します)

[[Thumb(chattering04.png, size=355x211, caption=一般的なチャタリングの改善例。入力遅延を許容する前提での方法。)]] 


=== まとめ
試作2では、以下の改善を行いました。

 1. 最初のキーアサイン時に、なぜかLEFTが自動設定されて、上入力が入りっぱなしになる問題を修正
 2. 反応が悪い(反応が遅い) 問題を修正
 3. チャタリングする問題を修正。

試作2のスケッチ全体をダウンロードできるようにしました。ご活用ください。
[[LinkAttach(gtcon-03_.zip)]]

=== ご参考
チャタリングについては、[http://www.kumikomi.net/archives/2009/05/ioledrs-232.php?page=3 この辺]や[http://www.geocities.jp/zattouka/GarageHouse/micon/circuit/Chattering.htm この辺]が参考になりました。