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入力が…あれっ? »
「失敗」カテゴリの記事
- 出窓:鯉のぼりを振れたらというリクエスト(2023.04.26)
- 回路設計はデータシートの熟読から。 スペックをちゃんと調べろ!(2022.09.28)
- Arduino IDEでRaspberry Pi Pico:millisをwordで処理した時の異常(2022.04.19)
- Arduino IDEでRaspberry Pi Pico:32bitマイコンがバグを生む(2022.04.14)
- プリント基板用リレーのピン番号(2022.03.05)
「Arduino」カテゴリの記事
- 初めて買ったArduino UNO・・・今は(2023.05.25)
- 液晶表示コントローラ HD44780で迎撃(2023.05.16)
- Arduino UNOで3相モーターを回す(2023.05.01)
- Arduino サーミスタを使った温度測定で 【ゼロ除算問題】(2023.03.23)
- A/Dコンバータでサーミスタの抵抗値を読む サーミスタをつなぐ場所は?(2023.03.21)
「重箱の隅」カテゴリの記事
- トラ技Jr. 2023年春号(2023.04.12)
- Arduino サーミスタを使った温度測定で 【ゼロ除算問題】(2023.03.23)
- A/Dコンバータでサーミスタの抵抗値を読む サーミスタをつなぐ場所は?(2023.03.21)
- こんなところに「256-1」が(2023.03.08)
- ありゃま。ラズピコがおかしくなった。 PWMを調べたかったのに(2023.02.14)
「ラズパイ・ピコ」カテゴリの記事
- Help me! ラズピコ、Philhower版だとスケッチをアップロードできない(2023.04.12)
- Arduino IDEでのラズピコ開発環境 Philhower版が正解でしょう(2023.04.04)
- ラズピコのピン:自由になりそうだけど定義で固定されている(2023.04.03)
- ラズピコで2chシリアル入出力のテスト(2023.03.30)
- Arduino IDEでのラズピコ開発環境(2023.03.29)
コメント
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分