So-net無料ブログ作成

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)