SSブログ

DSMainR5のDSJoy部分のバグ [DSmainR5]

 Yaasan様が私の年賀状イラストをPaintChainerでAIに着色してもらったら、わりとちゃんとしていたというとことで、画像を下さったので載せます。ちゃんと私の絵を犬と認識できたということでAI偉い!と思いました。犬の影が赤い(血だまり)のよう見えるのがちょっと気になりますが。
K9CJCTOSW96OPSWJN58PQUAN4UVBI40D_0.jpg
 で、お正月の大型連休に入りましたので、鉄道模型を再開です。
re_DSC02194.jpg
 今回は、クモハ40とクモハ12の複線レイアウトで、S88Masconを2台つないで、子供がやるハードな運転の再現です。・・・少し前から気になっていたバグの部分です。
 DSMainR5にS88Masconを2台つないで両方とも割とハードに加速と減速を続けると、DSMainR5の電源供給が突然途絶えたりErrorLEDが消えたり、と心霊現象が起きます。(いや、単なるバグです)
 で、最新のソフトを使って確認しました。ファームも最新(DSCore(R5.1)R2)です。私の持っているのはDSMainR5なので、電流制限部分はちょっと変更しますが。
 で、この状態では、S88Masconで上記のバグが再現します。
 現象として、線路電源供給がOffしたり電流制限のErrorLEDが点いても、DSMainR5のNanoからの@で始まる状態のシリアル出力では、それにあたる命令がでたというのは確認できないし、もちろんS88MasconでもPowerOff命令は出していませんでした。
 現状ではDSMeister.inoのloop関数内で、DSjoyは100msに一回割り込みをもらって、2個S88Masconをつないでいる場合はここで、2命令を連続でDSCoreに投げます。
 なんとなく以前に言っていたDSCoreに命令を一度に送りすぎるとバグるという現象っぽい、ということでいくつか試してみました。
(1)DSJoyの100ms割り込みを200ms、400msなどに変更してみる。→現象は変わらないので、多分連続送信がダメっぽい。
(2)DSJoyの100ms割り込みでS88Masconの命令を一つだけ送るように変更してみる。つまり、S88Masconを二つ繋いでいると、1周期に200msかかる。→バグらなくなった。
 ということで、DSCoreへの連続送信をやめることで、心霊現象(バグ)は起きなくなりました。
なので、loopをちょっと汚いですが以下のように変更したら、大丈夫になりました。
ソースはこちら。(DSMainR5用です)
 今後、DSOneなどでも同じルーチンを試してみようと思います。
---------------------(抜粋)
//DSJoy用スケジューラ
int dsjoy_int = 0;

void loop()
{
	
//省略
  if( (millis() - gPreviousL6) >= 100)
  {
    if( Sequence.GetRJ45Mode() == RJ45MODE_DSJ)
    {
      // S88  
      if(dsjoy_int == 0)
      {
        reporter.refresh(MAX_S88DECODER);
      }
      
      // データ処理 

      //for( int i = 0; i < MAX_S88DECODER; i++)
      int i = dsjoy_int;
      {
        uint16_t aData = (reporter.getByte(i * 2 + 1) << 8) + reporter.getByte(i * 2 + 0);
        if(i == 0)
        {
          //SerialDS.print("s88_raw:");
          //SerialDS.printHEX(aData);
          //SerialDS.println("");
        }
				
        if( aData != 0xFFFF)
        {
          // S88データをジョイスティックプロファイルに読み替え処理 
          DSJoy.SetData(i, aData);
        }
        //else
        //{
        //	break;
        //}
        i++;
        if(i == MAX_S88DECODER)
        {
          //最大数まで行った
          dsjoy_int = 0;
       	}
        else if(0xffff == (reporter.getByte(i * 2 + 1) << 8) + reporter.getByte(i * 2 + 0))
        {
          //次が接続されていない
          dsjoy_int = 0;
        }
        else
        {
          //次がある
          dsjoy_int ++;
        }
      }
    }

    //Reset task
    gPreviousL6 = millis();
  }
//以下省略
}

---------------------

コメント(4) 

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