So-net無料ブログ作成
検索選択

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の解像度しか持っていないようです・・・。
 なので、かなり離散的な値が出てきてと、書きながら、割り込み時に回数を記録して平均を取ろうと思いました。
 まあ、もう少し頑張んないとろくなものにはならなさそうです。

コメント(3)  トラックバック(0) 

コメント 3

Yaasan

タイマーのカウンタを直読みする方が速くて正確ですよ。
0に戻る周期が必ずあるので、その周期だけオフセットするようにすれば大丈夫です。
by Yaasan (2017-06-04 06:07) 

MECY

お手間をお掛けしています。思っていた以上にめんどうな状況になってますね。繋がるのはいつでもいいのでお気楽に進めていただければと思います。
by MECY (2017-06-04 07:49) 

fujigaya2

コメントありがとうございます。

ゆるゆると今度はタイマーを試してみたいと思います。
by fujigaya2 (2017-06-05 00:27) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0