失敗

2022年4月19日 (火)

Arduino IDEでRaspberry Pi Pico:millisをwordで処理した時の異常

2022年4月14日:Arduino IDEでRaspberry Pi Pico:32bitマイコンがバグを生む
この検証用スケッチを書いてみました。

/*****  millisを使った時間待ち  *****/
// uint32_tではなくwordで
word ms_0;
word ms_1;
void delay2(word dly)
{
ms_0 = (word)millis(); // 開始値
while(1){
digitalWrite(2, HIGH); // テスト用パルス出力
ms_1 = (word)millis(); // 現在値
if((ms_1 - ms_0) >= dly) break; // ★1 時間経過
// if((word)(ms_1 - ms_0) >= dly) break; // ★2
digitalWrite(2, LOW);
}
}

/***** SETUP *****/
void setup() {
Serial.begin(9600); // TX
pinMode(2, OUTPUT); // PD2
pinMode(3, OUTPUT); // PD3
pinMode(LED_BUILTIN, OUTPUT); // LED
}

/***** LOOP *****/
void loop() {
byte f_xLED = 0; // LED点滅用
word cnt = 0; // loopカウンタ
char tx_bff[64]; // 送信文字列
while(1){
f_xLED ^= 1; // LED トグル
digitalWrite(LED_BUILTIN, f_xLED);
delay2(1000); // 1000ms wait
sprintf(tx_bff, "#%4d %5u %5u",
cnt, ms_1, ms_0);
Serial.println(tx_bff); // 改行
cnt++;
if(cnt > 9999) cnt = 0;
}
}

★1 と ★2の違いが重要。
★2は引き算結果を(word)でキャストしています。

Arduino UNOで動いていた<★1>の処理、
これをRaspberry Pi Picoに持ってくると、
  cnt ms_1 ms_0
 # 61 62002 61002
 # 62 63002 62002
 # 63 64002 63002
 # 64 65002 64002 ←ここまで動いて停止

数値の比較ができず(32bitのマイナス値になる)、
時間待ち関数から抜け出せません。

これを<★2>のようにすると、Pi PicoでもArduino UNO
でもオーバーフロー発生部分を無事に通過できます。
こんな具合。
  cnt ms_1 ms_0
 # 63 64002 63002
 # 64 65002 64002 ←ここで止まっていたのが、
 # 65   466 65002  (65536+466=66002) 通過
 # 66  1466  466
 # 67  2466 1466
 # 68  3466 2466

符号なし16bit値同士の減算、オーバーフローが起こっても
16bitならうまく「差」が算出されます。
「466 - 65002」は16進だと「01D2 - FDEA」。
「01D2 - FDEA = FFFF・03E8」となり、不要な上位の
「FFFF」は捨てられて下位の16bit値、「03E8」が出てきます。
16進の03E8は10進で1000。
ちゃんと1000ms待ちが動きます。

それが32bitマイコンだと「暗黙の型変換と符号拡張」 が悪さをして、
「01D2 - FDEA = FFFF・03E8 = -64536」とマイナスの値になって
しまいます。
  ※符号なし16bit = word = uint16_t で比較されるつもりが
   符号付の long = int32_t (32bitマイコンでは int だ) で
   比較が行われるのです。
結果、1000msの経過がチェックできません。
今回の例では、減算値ms_0は65002と固定されています。
ms_1が0~65535の間を変化しても、1000を越える値は出てきません
いつまでたってもこのdelayルーチンから抜け出せないのです。

このスカタンの場合、65秒ほど経てば「あれ? なんかおかしい
と気が付くわけですが、もっと複雑な処理で、異常の出現まで
時間がかかるような場合や、条件が重なった時だけ発生する
ものだと、むちゃ怖いバグになってしまいます。

8bitマイコンで正しく動いていたルーチンを32bitマイコンに
持ってくると、転けてしまって動かない。
よく考えておかないと、こんなことが現実に起こります。
「暗黙の型変換と符号拡張」 、昔のルーチンを借用する時は
どうぞ気をつけてください。

| | コメント (0)

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で処理した時の異常


| | コメント (1)

2022年3月 5日 (土)

プリント基板用リレーのピン番号

真空管のピン配置は1番から右回りに2,3,4・・・
それがDIP ICだと、左下の足が1番で左回りに2,3,4・・
重要なのが、真空管は「BOTTOM VIEW」で下から足を見ます。。
DIP ICになると「TOP VIEW」となって上から見たところ。
昔話になりますが、プリント基板用リレーのピン番号で混乱した
ことありませんか?

例えばオムロンのG5V-1リレー。
カタログから外観をピックアップ。
Aa1_20220305123801
その端子配列がこれ。
Aa2_20220305123801
BOTTOM VIEWで記されています。
ICのTOP VIEWに慣れてきた頃に、BOTTOM VIEWの絵が出てくると
ちょいと混乱します。 (・・・混乱しました)

G5V-1のコイルには極性がないので間違って反対にしてもリレーは
駆動します。
しかし、A接点とB接点が逆になって「あれれ?」な状態に。
   手組みの試作だと修正できるので良いのですが、
   ピン番を勘違いしてプリント基板を起こしちゃ
   うとアウト!

サーフェスマウント端子のリレーを使ったときに気が付いたのが
端子配置の表現。
   ※使ったのはオムロンG6Kという2回路の小型リレー。

足が下に出たプリント基板用端子のリレーはBOTTOM VIEWで示されて
います。
ところがサーフェスマウント端子になると、ICと同じようにTOP VIEW
なっています。
どちらも同じなのですが、きちんとピン番号を確認せず「ぱっと見」で
組んでしまうと「あらら」。
みなさん、勘違いしたことありませんか?

これがプリント基板用端子のG6Kリレー。

Aa3_20220305123901

ピン番号はこれまでどおりにBOTTOM VIEWで描いてあります。

Aa5

サーフェスマウント端子になると・・・

Aa4_20220305124002

ピン番号の表記の方法がTOP VIEWに。

Aa6

同じ品種のリレーでも、実装方法の区別でピン番表記の向きが
異なります。
  ※表記の上下方向が変わるだけで、同じものですよ。

G6Kのコイルには極性があるの、誤って上下を逆に見てしまうと
リレーが動きません。
  ※でも、このリレーの場合、A接、B接は大丈夫。


※似たような話
GP-IBコントローラ TMS9914のピン名称


| | コメント (2)

2021年6月30日 (水)

混ざる・・・熱収縮チューブがぁぁ

現場に持って行った「熱収縮チューブ」を入れた箱。
いわゆるタッパー。
仕切りが付いていて4つに分かれています。
それが・・・ 何かの拍子、横から縦になったのでしょうね。
混ざってしまいました。

N1_20210630113901

過去にはこんなことも。
   ・15kΩと51kΩが混ざる
「茶緑橙」 と 「緑茶橙」 の逆襲!
   ・コネクタ・ピンのオスとメス

今回のスカタンはタッパーの仕切りとフタの位置。
微妙に隙間が空いているのです。
そこを通って、熱収縮チューブが内部で移動。
みごとに混ざってしまいました。

どのくらいの間隔か・・・
   撮影が難しい。
中央の十字に赤マークを入れてフタをして。
押さえたときと離した時でこれだけの差。
Newimage1
   ↑
  GIFです。 クリックしてみて。

この隙間が原因でした。

| | コメント (11)

2021年2月 2日 (火)

ダイソーのUVレジン液、UV-EPROM消去用紫外線ではなかなか固まらない・・・

カラーLEDの集光用に小さな「レンズ」が欲しかったので、
ダイソーのUVレジン液を買ってきました。
11_20210202142701

「紫外線なら固まるやろ」っと思いながらUV-EPROM消去器
(いわゆる殺菌灯をタイマーで点灯)の中に入れました。
   ※これ使うのひさしぶり

ところが・・・固まらない。
10分ほどして取り出してみたら、固化したのは表面だけ。
裏返したりしながら、結局、1時間ほどかかってやっと硬化。

調べてみたら、硬化する適切な波長が違うんですな。
殺菌灯は「水銀蒸気」の放電で波長253.7nm
レジンを硬化させるには365~375nmあたりっと書かれています。

今度使う時は、それ用のをちゃんと用意しますわ。


※検索
紫外線パワーLEDでUVEPROMは消去できるか?: エアーバリアブル ブログ(2012/10/06)
EPROMの消去に成功 | 電脳伝説(2016年5月11日 )
E17殺菌電球を光らせるのにはコツが必要でした | kohacraftのblog
悠々趣味の日々: 簡単にできるEPROMイレーサの製作

ストロボでマイコンが暴走した!?(プロセッサ誌1989-6)


| | コメント (3)

2020年11月30日 (月)

引っ張られて短絡・・・2.5φプラグ

2.5φのプラグ・ジャックで信号を受けていた装置。
「なんかおかしい」と。
何本かあるケーブル、そのうちの1本がプラグのところで
短絡してました。

上側は正常。
11_20201130164601
下がアウト。
向きを変えて拡大。
12_20201130164601

青・白とも外装が引っ張られて、銅線がむき出しに。
U字状のクランプのところで、白線が短絡。
乱暴に扱う機器じゃないんで油断したわけで、
ちゃんと熱収縮チューブを入れてれば防げたかも。


| | コメント (3)

2017年12月 7日 (木)

ラミネートフィルム

ラミネートしたことありますか?
保存する紙書類などを、フィルム中央にきちんと
セットしてからラミネータに食わすわけですが、
上下左右(上は綴じ代になるんでフタされている)
きちんとセットするのが意外と面倒です。

フィルムの上下左右にもう少し余裕があればなぁ、
なんて思いませんか?
余裕があれば、紙書類を挟み込む作業を手抜き
(配置精度が緩くなる)できます。

で、ちょいとフィルムの大きさを調べてみました。
A3サイズで。

A3の用紙の大きさは「297 x 420mm」。

そして、ナカバヤシ、アイリスオーヤマ、アスクル
などで売られている標準的なフィルムが「303 x 426mm」。
縦横ともA3用紙に比べ「6mm」大きいだけです。
つまり「±3mm」が配置精度の要求値。

これがなかなか厳しいわけでして、酔っ払って
作業していると、何度もやり直しなくちゃならず、
面倒くさいわけです。

ところが・・・
ホームセンター・コーナンで売っている「LEFELEX」
ブランドのA3ラミネートフィルムは「307 x 430mm
という大きさなんです.。
A3用紙より「10mm」大きい。
精度が「±5mm」に緩和されます。

11

青いのが「ナカバヤシ」製。
下のが「コーナン・LIFELEX」の。
紙のはさみこみ精度を手抜きできる、この差は大きいです。

| | コメント (0) | トラックバック (0)

2017年11月 6日 (月)

液晶表示器「焼き鈍し」

直流印加のために焼き付いてしまった液晶 、加熱で改善
されるのではないかという情報をいただいたので、試して
みました。
  ・山本式液晶再生法

ツールは、段ボール箱と発泡スチロールで作った保温ケース
の中に、発熱体として60W電球(x2)を仕込んだもの。
アルミ板の下に電球を置き、内部をファンで撹拌してます。

11

アルミのケースに入れてあるのは温調機。
設定温度をPID制御で維持してくれます。
センサーはサーミスタ。

12

制御温度目標値「50度」にして、液晶の乗ったカウンタを投入。
カウンタは通電状態(液晶駆動)。
2時間30分、加熱。

結果・・・  
13

あきませんでした。  (写真はまだ暖かい時)
冷えてくると、ちょいましになりますが、加熱前と
変わりません。

液晶駆動せずでの(電源オフ状態で)加熱、明日、試して
みます。

| | コメント (6) | トラックバック (0)

2017年11月 2日 (木)

液晶表示器の「焼き付き」

「ブラウン管」じゃないんですから焼き付きなんて
おこりません。
でも、似たような状況に。

ものはこれ↓
液晶表示カウンタ:2010年01月30日
スタティック駆動している7セグメント表示の液晶

6桁の7seg液晶。
C-MOSの専用ドライバ「4543」 で駆動しています。
COM端子のクロック周波数は約40Hz。

C-MOSのゲートICで発振して、FFで1/2してデュー
ティー50%のCOM端子駆動方形波を作っています。

このカウンタ、電池で動くようにしています。
電源オンしっぱなしで、とある実験に使っていました。
ところが、実験は終わったのに、カウンタの電源を
オフしなかったんです。
これが失敗原因。

そのため・・・
   電池消耗
   クロック発振停止
   回路の消費電流ほぼゼロに
   COM端子出力、H/Lどちらかに固定
   ドライバのセグメント出力がH/L固定
   液晶のCOM端子とセグメント端子間に直流が印加
   直流が加わった液晶セグメントが「焼き付け」

こんな具合になっちゃいました。
リセットしてゼロ表示。
しかし、中央のGセグメントが「もや~」っと。
11

斜めから見ると。
「0」が「8」のように見えます。
13

電源オフすると。
カウント停止して放置した時の数値が
ぼんやりと浮かんでいます。
12

クロック停止検出回路を設けて、セグメント駆動
を全オフにというのがまっとうな設計だったようです。
  (回路は全部ロジックICで組んでます)。

電源をオンして交流駆動し続けても、元に戻りませんね。
もやったセグメントだけ、逆電圧をかけたら戻るかな?
(回路につないだ状態ではむつかしそう)

※関連
C-MOS 2相パルスカウンタの入力部回路
パルスの数を数えたい
29年前に製作したツール

| | コメント (5) | トラックバック (0)