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入力が…あれっ? »
「失敗」カテゴリの記事
- アマゾンで買ったユニバーサル基板:失敗だぁ(2024.09.13)
- 工具は使ってみなきゃ使い勝手が分からない(2023.09.08)
- 危険じゃないけど、ちょっと待てっ! ポカリ入りめんつゆ(2023.07.03)
- 出窓:鯉のぼりを振れたらというリクエスト(2023.04.26)
- 回路設計はデータシートの熟読から。 スペックをちゃんと調べろ!(2022.09.28)
「Arduino」カテゴリの記事
- 液晶表示:CG-RAMの表示がちょいと違う(2024.09.12)
- ひさしぶりのバージョンアップ:チャートレコーダ(2024.07.02)
- 最適化処理のせいで悩んだぞ 呪文volatile再び(2024.06.06)
- 数値をBCD出力(表示)するルーチン #3(2024.05.03)
- ダイソー SHOOTING LIGHT:撮影用ライト LEDの輝度変化を探る #2(2024.05.03)
「重箱の隅」カテゴリの記事
- リターンパスの無いオペアンプ入力回路(2024.05.31)
- サーミスタでの温度測定、「inf」の出現に耐えられるか?(2024.05.13)
- I2C液晶のアクセス、割り込みで処理しないようにすると(2024.04.12)
- トラ技2024年5月号に「3.3/65535」(2024.04.07)
- I2C液晶のアクセス、割り込み処理で遅れる原因らしきもの(2024.04.07)
「ラズパイ・ピコ」カテゴリの記事
- トラ技2024年5月号に「3.3/65535」(2024.04.07)
- ラズピコだと1/65535が出現(2024.03.30)
- Help me! ラズピコ、Philhower版だとスケッチをアップロードできない(2023.04.12)
- Arduino IDEでのラズピコ開発環境 Philhower版が正解でしょう(2023.04.04)
- ラズピコのピン:自由になりそうだけど定義で固定されている(2023.04.03)
コメント
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分