SSブログ

S88 Analogと鉄コレのコントローラをつなぐ(pin change interruptを使う) [S88]

 複数の話題を一緒に書くと、後で探しづらいことに、このごろやっと気づいたので、単発の記事にしていきます。
 S88 Analogですが、鉄コレの101系コントローラとつないで実験をしていますが、あまり芳しくありません。
 いまはこんな感じに繋いでいて、すでに鉄道模型ですらありません。re_DSC01584.jpg
 DS One(DSJoyスケッチ)のS88端子にS88 Analogをつないで、DCC出力にはみるだけ君(DCCパケットの解析をしてくれる基板)をつないでいます。
 鉄コレのコントローラの波形はDU202(常点灯の12Vパルスとモーター駆動用の直流パルスの組み合わせ)と違い、12Vのパルス(周期は50us)のみでの駆動です。
 このため、スピードの検出が少々難しくて、まず、1ms周期のAD変換でスピードに変換してみたところ、ふらついてしまい、吊りかけ音がかなりふらつきます。(音無しのデコーダでは問題ないかもです)。平均化を入れるなどやり方はありますが、余り良くありませんでした。
 次に、今回、パルス幅を割り込みを使って検出してみることにしてみました。Arudinoには割り込みがいくつかありますが、サポートされていない、全てのIOピンに対しての割り込み(Pin Change Interrupt)とかいうのがあるということを調べていて知りました。コントローラからの信号はA3ピンに入れており、ここはArudinoの標準の割り込みでは使えないピンですが、この割り込みなら使用可能です。
 参考にしたページは、こちらこちらです。
 で、めでたく割り込みを使ってパルス幅を正確に検出することはできました。
こんなコードです。
セットアップで
  //pin change interrupt
  PCMSK1 |= (1 << PCINT11);  // A3(D17)ピンからのピンチェンジ割込みを使う
  PCICR  |= (1 << PCIE1);     // PCIE1グループからの割込み許可

割り込みは
//鉄コレコントローラパルス幅計測
ISR(PCINT1_vect)
{
  static int pulse_width_temp = 0;
  //A3(D17)のChangeで割り込みがかかる(はず)
  if(digitalRead(A3)==HIGH)
  {
    //開始
    pulse_width_temp = micros();
  }
  else
  {
    //終了
    A3_pulse_width += micros() - pulse_width_temp;
  }
}

 A3_pulse_widthにパルス幅をある程度溜め込んでから、平均化するようなルーチンです。
 で、パルス幅ですが、50us周期の信号は上記では12us~40usぐらいまでしか測れず、おまけにmicros()は4usの解像度しか持っていないようです・・・。
 なので、かなり離散的な値が出てきてと、書きながら、割り込み時に回数を記録して平均を取ろうと思いました。
 まあ、もう少し頑張んないとろくなものにはならなさそうです。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。