« Arduino IDEでRaspberry Pi Pico:PWMでD/A出力してA/D入力を試す | トップページ | Arduino IDEでRaspberry Pi Pico:A/D入力が…あれっ? »

2022年4月14日 (木)

Arduino IDEでRaspberry Pi Pico:32bitマイコンがバグを生む

Arduino UNOの「int」は16ビット
それがRaspberry Pi Picoになると「int」は32ビットに

Arduino UNOだとついついRAMをケチりたく
なって、255までの数値でOKなら「byte」でと
「スケッチ」を書いてしまいます。
8ビットで済むところをwordやintにするのは
もったいない・・・ はい。ケチです。

そんな考えで作ったプログラムをPicoに持って
くると思わぬ「バグ」が生じます。
  ・Arduino IDEでRaspberry Pi Pico:PWMでD/A出力してA/D入力を試す

このスケッチ中で使っている時間待ちルーチン。
bkdelay」という名で、1ms単位の時間待ちをしている途中、
シリアル入力があったら時間待ちを中断するという機能を
持たせています。
1秒待ちなんかしてる時に、「もぅエエからはよ終わろうぜ
に対処します。

さて、この時間待ち。
割り込みを使わずに管理するとなると、millisを呼び出して
時間経過をチェックするという処理になります。

millisは32bit値で最大1193時間、50日ほどを計時できます。
「そんな長いこと待たへんのんで16bitでエエやん」と
ケチるわけです。  (16bitだと65秒)
その「ケチな考え」が32bit CPUでバグを生んでしまいます。

今回のルーチン。
/***** Break処理付のdelay *****/
// シリアル受信あればdelayを中断
void bkdelay(word dly)
{
word tn, t;
  tn = (word)millis();    // now
  while(1){
   t = (word)millis();    // 経過
   if((word)(t - tn) >= dly) break;
   if(Serial.available())  break; // 受信データ
  }
}

目標待ち時間dlyと経過時間(t - tn)を比較している
んですが、すべて16bit値で計算していました。
  ※Arduino UNOだから。
  ※UNOの時は(word)を付けてなかった。
  ※(t - tn)、符号無しwordだとtとtnの大小が逆に
   なっても差の値は正しく出てきますんで。
ところが、Picoは32bitで内部処理。
16bitで減算して比較するつもりが、32bit値に型変換され
てから比較されるのです。
  ※「暗黙の型変換と符号拡張」というヤツです。
tとtnの大小が逆になったらマイナスになってしまいます。
tnの値によっては、いつまでたってもdlyを越えることが
できません。

ということで、減算式(t - tn)の前に付けた
キャスト演算子(word)
これを忘れると動かないわけです。

※教訓:32bitマイコンはRAMをケチるな!

ちゃうちゃう。
 「暗黙の型変換と符号拡張」に注意!ということで。


※millis時間判定の異常、検証用スケッチの紹介
Arduino IDEでRaspberry Pi Pico:millisをwordで処理した時の異常


|

« Arduino IDEでRaspberry Pi Pico:PWMでD/A出力してA/D入力を試す | トップページ | Arduino IDEでRaspberry Pi Pico:A/D入力が…あれっ? »

失敗」カテゴリの記事

Arduino」カテゴリの記事

重箱の隅」カテゴリの記事

ラズパイ・ピコ」カテゴリの記事

コメント

while(1){
 t = (word)millis();
 if((word)(t - tn) >= dly) break;
 if(Serial.available())  break;
}
とせずに、
 t = (word)millis() - tn;
 if(t >= dly)        break;
 if(Serial.available())  break;
こうすれば(word)のキャストがなくてもOK。

投稿: 居酒屋ガレージ店主(JH3DBO) | 2022年4月14日 (木) 17時33分

コメントを書く



(ウェブ上には掲載しません)




« Arduino IDEでRaspberry Pi Pico:PWMでD/A出力してA/D入力を試す | トップページ | Arduino IDEでRaspberry Pi Pico:A/D入力が…あれっ? »