« ダイソー「明るいランチャーライト」「単3x2本ハンドライト」 LED通電テスト60日 | トップページ | ダイソーReVOLTES単3 JIS C8708:2019充放電試験 200サイクル目完了 »

2020年1月 8日 (水)

ミスが広まる 1/1023 vs 1/1024

定番回路、「これはあかんやろ」を指摘したんが
液晶表示モジュールを4ビットモードで使ったときの空きピン処理
誰かが始めた間違ったつなぎ方(この場合はチップメーカーのアプリケーション
ノートか)がずっと踏襲されて広まってしまったというのを発見しました。
これをトラ技の記事にしたのが2009年5月号
以後、空きピンをGNDにつないでしまう例、だいぶ少なくなってきたように思います。

で、新年早々こんなのを発見しました。
 ・ラジオペンチ Arduinoを使ったバッテリー放電器
A/D変換データを電圧値にスケーリングする処理がスケッチに書かれています。
ArduinoのanalogRead() は10bit。 0~1023(10進)の値が得られます。
これの処理が間違っていたのです。
ここ↓
//  battV = analogRead(0) * Vcc / 1023.0;       // バッテリー電圧測定(これは間違いで、)
  battV = analogRead(0) * Vcc / 1024.0;       // バッテリー電圧測定(正しくはこっち

10bit値で1/1023と1/1024の違いですので、差は0.1%ほど
わずかですが、原理的に間違っていますんでこれはまずいです。

  ※A/Dコンバータが8bitだとミスによる実際の誤差
   が目につくでしょう。
   1/255 vs 1/256 で差が0.4%ほどになり、
   実値との差に気がつく
   テスターで読んだ値と「微妙に違うなぁ」と。
   しかし、10bitになると気が付きにくい。

  ※もっと極端に2bitだと分かりやすいかと。
   ATmega328PのA/Dは10bit。
   プログラムの処理としては2bit + 8bitに分割して
   レジスターから読み出します。
   この上位2bitのデータを考えてみましょう。

   出てくる数値は 「0 1 2 3」の4種類
   AREFを5Vとすると、1bitが1.25V
     0は0.0V。 そこから電圧を上げて、
     1になると1.25V。
     中間の2が2.50V。
     最大の3が出るのは入力電圧3.75V以上で

   「1/3」して電圧を求めるのは明らかに間違っていて、
   「1/4」が正しいことがわかるでしょう。

   A/Dの結果が2進だから勘違いするのかな。
   BCD出力だと・・・
    100カウント、0~99基準電圧5Vだと 0~4.95Vを表示。
    基準電圧に読み出しデータを乗じて1/100します。
    「1/99」する人はいないかと。
    

※理屈の詳細はラジオペンチさんの記事のコメントをご覧ください。

この「1/1023と1/1024」、調べてみると「1/1023」を使っているプログラム例があちこち
に出てきます。
どこが発端なのかは調べ切れてませんが、ArduinoのanalogRead処理で多いような気がします。

ArduinoではArduinoのアナログ基準電圧入力 も勘違いの処理が広まっているかもです。
正しく使えば、「外部基準電圧とAREFピンの間に抵抗を入れておく」なんてことはしなくてもokですから。

|

« ダイソー「明るいランチャーライト」「単3x2本ハンドライト」 LED通電テスト60日 | トップページ | ダイソーReVOLTES単3 JIS C8708:2019充放電試験 200サイクル目完了 »

Arduino」カテゴリの記事

1023 vs 1024」カテゴリの記事

コメント

どーもです、今年もよろしくお願い致します。

Arduino のリファレンスに、「0から5Vの入力電圧を0から1023の数値に変換する」と書いてあるので、それを忠実にコードにすると1023になるんでしょうね。原文でもそうなってます

http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2113

投稿: radiopench | 2020年1月 8日 (水) 13時30分

radiopench さん、コメントどうもでっす。

ソフト作りの時にその手本は見るけれど・・・原点となるチップ(ATmega328)のデータシートは(ハードウェアの話は面倒なんで)読まない。
やっぱりこれかな。
フルスケールは5Vジャストではなく「5V - 1LSB」だっと。

液晶4ビット駆動の話もそうだし(これはPICの参考本が悪い)、ハードの元となる日立HD44780のデータシートを見れば「4ビット動作のとき、この4本は使われませんので、オープンにしてください」と書いてあるのに従わないんだから。

Arefピンの話も、元となるソースを見れば処理が分かるのに・・・

投稿: 居酒屋ガレージ店主(JH3DBO) | 2020年1月 8日 (水) 16時48分

Arduinoでの解説、英文のほうはずいぶん追記されていますね。
https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/

・・・this yields a resolution between readings of: 5 volts / 1024 units・・・
っと「1/1024」が出てきます。

投稿: 居酒屋ガレージ店主(JH3DBO) | 2020年1月 9日 (木) 09時18分

ArduinoのA/D変換 1023 vs 1024、ちょっと検索
  (ラジオペンチさんところに記したのも含む)
・1/1023で計算(間違っている)
https://qiita.com/nyagato_00/items/2937a11630109a3db6e1
https://iot.keicode.com/arduino/arduino-analogread.php
https://deviceplus.jp/hobby/arduino_f07/
https://omoroya.com/arduino-extra-edition-05/
https://www.denshi.club/cookbook/stem/maker-uno-stem-6.html
https://www.denshi.club/cookbook/sensor/temp/l.html
http://easylabo.com/2015/04/arduino/8336/
https://novicengineering.com/%E3%80%90arduino%E3%80%91map%E9%96%A2%E6%95%B0/

※map()での数値範囲をミスってるところがあります。
  map(ad, 0, 1024, 0, 256)というふうにしないと。
  map(ad, 0, 1023, 0, 255)では、10bit A/Dの中央値512で
  8bitの中央値128が得られません。

※電圧計算で、Arduinoの電源電圧や内部基準電圧の値を5.0V、1.1Vと
決め打ちしているのが目に付きます。
ほんとにそうか、計ったことありますかな?
私とこのUNOは5.033V。 5Vより0.7%ほど高い。
電圧測定という課題で、基準を決め打ちするのは問題でしょう。
1/1023の処理とともに、テスターでの実測値とArduinoでの測定値
との差が気にならないのか心配です。 (計って比べてない?)

・正しく1/1024で
https://n.mtng.org/ele/arduino/tutorial008.html
https://hsh.s2jp.com/2011/09/arduino-voltmeter/
https://ogapsan.com/archives/150
https://yoshipc.net/arduino-temp/
http://maicommon.ciao.jp/ss/Arduino_g/AnSr/index.htm
https://nekosan0.bake-neko.net/structure_analog_in.html
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14183208509
http://tyk-systems.com/arduinobasic/arduinobasic.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2020年5月 3日 (日) 14時16分

メモ:コメント先
https://novicengineering.com/%E3%80%90arduino%E3%80%91map%E9%96%A2%E6%95%B0/

投稿: 居酒屋ガレージ店主(JH3DBO) | 2020年5月14日 (木) 13時30分

「map関数」も「1023 vs 1024」です。
・2020年5月17日:Arduino なんとかして誤用を正したい:A/Dの1/1023とmap関数
http://igarage.cocolog-nifty.com/blog/2020/05/post-115911.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2020年6月 6日 (土) 09時37分

★書籍でもやってる「1/1023」と「map(x, 0, 1023, 0, 255)」
http://igarage.cocolog-nifty.com/blog/2020/09/post-e67167.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2020年9月 9日 (水) 09時25分

トラ技2021年9月号別冊付録「PIC開発マニュアル2021」でも「1/1023」。
http://igarage.cocolog-nifty.com/blog/2021/08/post-cc3d63.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年8月 6日 (金) 09時31分

EDNは12bit A/Dで「1/4095」をやってます。
『測定電圧=(A-Dコンバーターの変換結果÷4095)×VREF+ 式1』
https://ednjapan.com/edn/articles/2004/06/news004.html
ビット数が増えても考え方はいっしょ。
割る値は12bitなら4096。

投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年8月 7日 (土) 21時55分

16bitのLTC2461。 「1/65535」してます。
 data = i2c.read_word_data(addr,0x01)
 data16 = swap16(int(hex(data),16))
 print (round((Vref * data16 / 65535 ),5))

https://www.denshi.club/pc/raspi/5raspberry-pi-zeroiot35a-d10-2.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年8月 7日 (土) 22時14分

コメント先↓
https://www.jh4vaj.com/archives/28146

投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年8月 7日 (土) 22時33分

ミスが広まる 1/1023 vs 1/1024

こんなの見つけました。

https://www.ti.com/jp/lit/an/jaja085/jaja085.pdf?ts=1629266491845&ref_url=https%253A%252F%252Fwww.google.com%252F

「この中の、12ページ 5.7 ADCのビット(20)」ですが、「2^n-1」で割ってます。

私は、昔から「1/1024」派ですが・・・。数学が不得意なソフトやさんには、「1/1023」派が多い様な気がします。

投稿: 河合 | 2021年8月19日 (木) 09時51分

式(20)の「Vtfullscale」、これが「Vref」そのものじゃなく「Vref - 1LSB」なら「2^n - 1」でok。
これで合ってます。
ただ、件のpdfには「Vtfullscale」の定義が出てこないみたい。

記事の中、例題で示した「2bit A/D」の話。
基準電圧5Vで「2bit A/D」だと、1LSBが1.25V。
「Vref - 1LSB」が3.75V(これ以上の電圧でフルスケール)で、これを「4 - 1」で割って出てくる1LSBは1.25V。
「Vref / 4」も「(Vref - 1LSB) / 3」も同じ答えということで。

Vinを求めるのに、10bitのA/Dだと、
「A/D値 × Vref / 1023」の1/1023がおかしいということで、
「A/D値 × (Vref - 1LSB) / 1023」と
「A/D値 × Vref / 1024」は同じ値になって、この2式は正しいわけです。
1/1023していれば単純に誤りということではなく、Vrefの扱いも見ておかなくてはなりません。

※追記しました

投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年8月19日 (木) 16時02分

引き続き「1/1023」を探索
・YS電子工作ラボ
http://www.ys-labo.com/pic/pic%20chips/pic%20chips%20contets/061001%20Internal%20ADconverter.html

(1)printf(lcd_data,"Vin=%4.3f V",3.968*((float)AdValue/1023)); //10ビット値を電圧値に換算 ←Vref=3.968Vと
  4.000Vジャストにしてという目論見だったのだろうか?
  4.096Vにすると、10bit A/Dの1LSBが4mVになって、
  (12bit A/Dだとちょうど1mV)キリの良い値にはなるんですが。
実測値のA/Dが「829」で表示された計算値が「3.215V」。
1/1024での計算だと「3.212V」に。
実際の入力電圧をテスターで計っていれば、微妙な差に気が付いたかも。
こういったとき、半値や1/4値を見れば「むむっ?」となるはずなんですが。

(2)Vin = (float)ADread/4095*5.0;  ←12bit A/Dでも1/4095
(3)Volt =(float)AdcValue/1024*3.3; ←これは正しく1/1024で

16文字×2行の液晶表示モジュール、4bitモードでD0~D3をGNDにしてるし。
※R/W=Lなんで「ちょっと気持ち悪いぞ」でという評価で。
  例えばスリーステート出力バッファICのHC540や541、イネーブルを禁止しているからと、
  出力端子をGNDにつないでいる状態です。
  これ、気持ち悪くないですかという、液晶モジュールの使い方です。

投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年8月21日 (土) 10時14分

『1/1023 vs 1/1024』問題 analogReadを2bitにして確かめてみる
http://igarage.cocolog-nifty.com/blog/2022/11/post-bed4a2.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2022年11月12日 (土) 16時21分

サーミスタによる温度測定、【1023 vs 1024 問題】が【ゼロ除算問題】に。

A/Dコンバータでサーミスタの抵抗値を読む サーミスタをつなぐ場所は?
http://igarage.cocolog-nifty.com/blog/2023/03/post-ad45c1.html

Arduino サーミスタを使った温度測定で 【ゼロ除算問題】
http://igarage.cocolog-nifty.com/blog/2023/03/post-4bb96a.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2023年3月25日 (土) 10時41分

コメントを書く



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




« ダイソー「明るいランチャーライト」「単3x2本ハンドライト」 LED通電テスト60日 | トップページ | ダイソーReVOLTES単3 JIS C8708:2019充放電試験 200サイクル目完了 »