Arduino

2023年1月13日 (金)

Arduino UNOで0.00~40.00mA定電流負荷回路

過去、あれこれと定電流回路を紹介してますが、
今回のは電流は少なめ。
2023年1月 2日:PWMでD/A変換:アナログマルチプレクサの応用で
2023年1月 7日:PWMでD/A変換:アナログマルチプレクサの応用、解決方法

この続きで、「4~20mA電流ループ・インターフェース」回路用の
実験用定電流回路です。

計測系での4~20mA電流ループ・インターフェース、こんな
つなぎ方があります。

・装置側が電源を持っていて、計器側は
 その電流をちょっともらって回路を動かし、
 結果を4~20mAの電流にして返す構成。
 2線でつなげます。
C21_20230113101901
ちょっとの電流で動かせる圧力センサーとか
温度センサーなど。

・計器側の電流消費が大きい時は、装置側から
 電源を供給。
 3線接続。
C22_20230113101901

・計器側は自分で電源を持っていて、
 測定値を4~20mAで出力。
 制御装置からの供給だと4線で接続。
C23_20230113102001

こんな回路のテストには4~20mAの電流発生器
あるいは定電流負荷回路が必要になります。
  ※中華製のが安く出ているようですが・・・

計器の真似を(装置側から電源をもらって動作)
しようとしてもよかったんですが、汎用的に
使える吸い込み型の定電流回路=定電流負荷
にして、
  「PWM+LPFによるDACの能力」
を確かめてみました。
  ※電流ループだと、電流の向きさえ合わ
   せれば定電流回路はどこにでもつなげる。

吸い込み型の定電流回路、基本はこんなの。
C13_20230113102101

ボリュームやポテンショ、あるいはスイッチで
Vp電圧を操作して、「Vp÷Rs」で電流を決める
という方法です。

設定した電流を読む方法が、
 ・ループの途中に電流計を入れる。
 ・Rs両端の電圧から電流値を計算。
と、いうのが普通。

今回は、
  PWM+LPFで出したVp電圧と、検出抵抗Rs値を信じて、
  PWMのデューティを変えて電流値を可変出力。
という方法を使いました。

ブロック図で示すとこんな具合。

C14_20230113102301

校正モードで設定するのは、デューティ100%
(MPXのVref選択入力がいつもH)のフルスケール電流値。
これを「0.01mA」単位の読みで(別の神様電流計で計測)
設定します。
  ※今回はフルスケールで12bitあたりを狙っています。

校正時、デューティ100%で仮に40.00mAが出てきたと
すると、PWMでのデューティ設定範囲は「0~3999」
にします。
つまり、デューティ0/4000~3999/4000が範囲。

デューティ比がそのまま「mA」値になり、
「00.00~39.99mA」と0.01mA単位で設定できるはず・・・
そんな目論見です。

そして、0.00mA→0.01mA→0.02mA→という最小桁を
安定して可変する出力というのもやってみたかった
制御で、そのために
 ・オフセット電圧の小さなオペアンプを選ぶ。
 ・バイアス電流も小さいの。
 ・±電源で動作させる。 ぜいたくに。

使ったケースは
2022年8月24日:パルスジェネレータを作ってみた:箱に入れた
での、ダイソー・100円(税別)樹脂ケースです。

C12_20230113102501

FLUKEを電流計モードにして操作してらほんとにぴったし。
エエ感じにできました。
手動操作だから PWM+LPF でも時間遅れは気になりません。
  ※セトリング時間、なに?それ?のモード

C11_20230113102501

「0.01mA」桁の操作がそのままテスターの読みに
出ます。
電流の読みを見ながらポテンショを左右に微調という
操作とは違う感覚です。

Rsを小さくすれば電流値を大きくできます。
今は20Ωで40mAですが、2Ωなら400mA。0.2Ωなら4Aに。

  ※電流を大きくしようとすると、FETのゲート
   駆動電圧を高くする必要があるかもです。
   オペアンプの+電源が+5Vでは間に合わないかも。

※関連
2021年4月4日:オペアンプとMOS-FETを使った定電流負荷回路
2020年8月27日:オペアンプとMOS FETを使った定電流回路・・・電子負荷回路・・・
2020年3月12日:定電流回路の電流検出抵抗を試す
2020年1月24日:メモ:4-20mA電流ループ用ICとデジタルアイソレータ


※現時点の回路
Cc31

・手持ち部品の関係でロータリーエンコーダはBOURNS
 のを使用。
・2回路入りオペアンプを使ったのも手持ち部品の関係。

※スケッチ zip圧縮
  ダウンロード - cl40ma1.zip

※温度変化の様子
2022年7月6日:デジタルテスター「FLUKE 87IV」の赤外線通信ユニット完成
でFLUKEテスターからのデータ吸い上げができるようになった
ので、定電流回路の温度変化を調べてみました。
使ったのはこの→2017年11月6日:液晶表示器「焼き鈍し」
での保温箱。
この中に定電流回路を置いて通電開始。
「電球」で段ボール箱内を温めます。

結果・・・
Cap074
定電流回路の設定を20.00mA。 (供給電圧は24Vで)
その時のテスターでの読みが20.003mA。
箱内を50℃まで上げると19.983mAに。
20.003mA→0.02mA下がりました。
30℃の温度上昇で電流がざっと0.1%下降。
1℃に直すと「33PPM/℃」。
基準電圧の変動なのか電流検出抵抗RsとかLPFの
分圧抵抗の変動なのか。
もうちょい調査が必要です。

| | コメント (2)

2023年1月 9日 (月)

Arduino UNO, Tips and Tricks:analogRead()を捨てちゃうぞ

Arduino UNOでのアナログ入力(A/D値の読み出し)、
通常はこんな感じかと。

・setup()内で
  analogReference(DEFAULT);  // 使う基準電圧を設定
                 // DEFAULTはAVCCの+5V電源
・loop()で
  d = analogRead(A0);  // A0ピンからアナログ入力
              // UNOだとA0~A5の6つから選択

読み出したd値をシリアル出力したり、加工して何かの操作に
使うという具合です。

しかし、analogRead()は結果が出てくるまで時間がかかり、
約100μs待たされます。
時間にきびしい処理の中では使うのはちょっと・・・
となってしまいます。

もし、使うアナログ入力が単一チャンネルで固定して良いのなら、
時間のかかるanalogRead()は捨てちゃいましょう

Arduino UNOのマイコン、ATmega328Pのレジスタを直接操作
して、固定チャンネルの連続変換動作で初期化します
すると、待ち時間無しで(A/D変換完了を待たずに)いつでも最新の
A/D値を読み出せます。

スケッチ例を示します。

//  A/D値読み出し実験  A0ピンが入力
// 読み出し中、PB5をonしてタイミングをチェック
#define PB5_H (PORTB |= (1 << PB5)) // LED on ※1
#define PB5_L (PORTB &= ~(1 << PB5)) // LED off

/***** SETUP *****/
void setup() {
pinMode(13, OUTPUT); // PB5 基板上LED ※1
Serial.begin(9600); // シリアル出力

// A/D入力
// ↓通常の記述
// analogReference(DEFAULT); // ArefはAVCCアナログ+5V電源 ※2
// ↓直接レジスタを操作 ※3
ADMUX = 0b01000000; // VREF設定
// ||| ++++--- MUX3~0 ch0 PC0を入力に ★
// ||+-------- ADLAR 右詰め (LSBがD0)
// ++--------- REFS AVCCから(+5V)
ADCSRB = 0b00000000;
// ||| +++--- ADTS 連続変換モード ★
// ||+-------- IPR
// |+--------- ACME
// +---------- BIN
ADCSRA = 0b11100111;
// |||||+++--- CLK 1/128 125kHz
// ||||+------ ADIE 割り込みしない
// |||+------- ADIF
// ||+-------- ADATE 自動トリガする ★
// |+-------- ADSC 変換開始 ★
// +---------- ADEN A/Dイネーブル ★
}

/***** LOOP *****/
void loop() {
word ad_10; // 10bit A/Dデータ
PB5_H; // LED on ※1
// ↓通常の記述
// ad_10 = analogRead(A0); // A0からアナログ入力 ※2
// ↓直接レジスタを操作
ad_10 = ADC; // 10bit直接 ※3
PB5_L; // LED off
Serial.println(ad_10); // 読んだA/D値をシリアル出力
delay(1000); // 1秒待ち
}

※1:タイミングチェック用パルス オシロで確認
※2:通常の記述
※3:レジスタを直接操作

通常の記述だと読み出しに時間がかかります。
約0.1ms。
C01_20230109143101

それが、直接記述だとこんな命令に変換されます。
  sbi 0x05, 5    ;PB5_H
  lds r18, 0x0078  ;ad_10 = ADC
  lds r19, 0x0079  ;ADCL、ADCHの順で
  cbi 0x05, 5    ;PB5_L

勝手に変換が行われるので、待ち時間なく、ADCレジスタを読むだけ。
実行時間はこれだけ。
C02_20230109143101
   ※シリアル出力データが出てくるのはず~っと後。

単一チャンネルだからできる技。
多チャンネルだと入力マルチプレクサを切り替えてから
変換を始め、そして変換完了を待つという動作になりますので
どうしても時間がかかります。

忙しい処理の中でアナログ値を読みたい(ボリュームの角度で
何かをしたいなど)時に使ってみてください。

| | コメント (0)

2023年1月 7日 (土)

PWMでD/A変換:アナログマルチプレクサの応用、解決方法

2023年1月2日:PWMでD/A変換:アナログマルチプレクサの応用で

では、ATmega328PのAREF端子をオペアンプで
バッファして取り出した1.1V基準電圧を、
4053マルチプレクサに入れたところの電圧波形が
おかしいのに気付きました。

M10

X0入力とX1入力を切り替えるとき、一瞬の
短絡が起きているのではないかという推測
です。
おそらくこれが原因だろうと。

その解決策として、こんな回路にしてみました。
コンデンサを付加できる基準電圧ICを使います。
  ※PWMでのD/Aコンバータ、今まで使って
   きたのはこの方式だった。

53_01
この「電圧出力」で、定電流負荷回路をこしらえて
みました。
  ※4~20mAの電流インターフェース
   計装回路を試験するため。
最小桁を0.01mAにして0.00mA~40.00mAまで可変。
およそ12bitの分解能です。

これまでだと負荷電流を電流計で計って表示という
手法が多いんですが、今回はロータリーエンコーダ
の1クリックで0.01mAをup/downします。

電流計としてつないだモニター用テスターの目盛が
0.01mA単位で反応するのはなかなか小気味いいもの
です。
ポテンショを回して表示値を落ち着かせるのではなく、
思った数値で止められるのがエエです。

※気遣い点
・安定性の良い基準電圧ICを。(高価でも)
   初期精度はキャリブレーションでカバー。
・基準電圧ICの出力にコンデンサをつないでも
 OKなものを。
・電流制御オペアンプは、低オフセット品を。
・電流検出抵抗もエエものを。
・0mA近くの制御ため、単電源はあきらめ±電源で。

  ※全体の回路はまた今度

定電流負荷だけじゃなく、定電圧回路の電圧設定にも使え
るかと。

※関連
2019年9月14日:良かれと思って付けたコンデンサが・・・
  ◆AD680発振!


| | コメント (0)

2023年1月 2日 (月)

PWMでD/A変換:アナログマルチプレクサの応用で

2020年8月13日:Arduino、analogWriteは捨てちゃえ。ちゃんとしたPWMを使おう
ということで、過去、PWMを使ったDAC(D/A変換回路)を
さまざまなツールで使っています。

例えば、
JIS C8708による充放電サイクル試験回路(トランジスタ技術2010年2月号)
2020年4月10日:JIS C8708:2019対応ニッケル水素電池充放電実験回路(回路図とプログラム)
2022年4月14日:Arduino IDEでRaspberry Pi Pico:PWMでD/A出力してA/D入力を試す
2022年4月15日:Arduino IDEでRaspberry Pi Pico:A/D入力が…あれっ?

これらでは、PWM波からDC電圧を作るのに、
基準電圧ICを使っています。
Vref値とGND間をPWM波でマルチプレックスし、
LPFを通すことで直流に。
デューティ比に比例したDC電圧を得ています。

この応用ということで、Arduino UNOのマイコン
ATmega328PのAREF電圧を取り出した使った実験も
しています。

例えば、この記事。
2022年10月5日:サーミスタ103JTで計った温度をシリアル出力

サーミスタの抵抗値を見るのに、AREF電圧を取り出して
A/D変換します。
  ※これはMPXとは関係なしの用例。

次のこの記事では、AREFをオペアンプでバッファして
PWMし、LPFを通してD/A変換しています。
2022年4月22日:Arduino UNOのA/D入力:PWMでD/A出力してA/D入力を試す

ここで問題に気が付きました。
「なんじゃこれは?」の信号が見えたのです。

こんな模式図を描いてみました。

M10

AREFをオペアンプでバッファして取り出します。
ATmega328Pに関してはこれでうまく基準電圧が
取り出せます。

そのオペアンプ出力を直にマルチプレクサの入力に
つないでいます。
外付け基準電圧ICを使った時のようにコンデンサを
入れたいところなのですが、発振の可能性があるので、
オペアンプの出力にコンデンサは入れられません。

たまたま、このPWM→D/A変換部の波形を見た所、
こんな信号になっていました。

M201m

AREF電圧を出力しているオペアンプ、そこにPWM波に
同期した負パルス(▼マーク位置)が出ているのです。
出力インピーダンスは低いはずなので、MPXの切換
ノイズが飛び込んでいるわけではありません。

そこで、こんな回路を使って実験してみました。
プラス側のIN1入力は1kΩで+5Vに。
マイナス側は1kΩでGNDに。

M12_20230102152301

すると・・・・
まず、1ゲートタイプのマルチプレクサ TC7W53
M302m

3回路入った74HC4053の場合。
M301m

MPXパルスが変化したエッジでIN0、IN1に瞬間的な
電流が流れている様子が見えています。

AREF電圧をバッファした通常速度のオペアンプでは、
この短いパルス(150nsくらい)を抑えきることができない
のでしょう。

なぜこんなことが起こるのか・・・
TC7W53の内部回路を見ると分かってきます。

M11_20230102152501
IN0とIN1の切換には、2直にしたインバータが
入っています。
IN1側がその後段につながっているので、IN0から
遅れて切換されます。
その一瞬、COM端子につながるOUT0とOUT1を通して
IN0とIN1が短絡するのです。
IN0はGNDにつながっていますので、オペアンプ出力を
つないでいるIN1が一瞬だけGNDに引っ張られることに
なってしまいます。
それがオペアンプ出力に現れた負パルスの原因です。

  ※観察のためIN0とIN1に1kΩの抵抗を入
   れましたが、IN0、IN1とGND間に0.01uF以上、
   0.1uF程度のコンデンサを入れると短絡パルス
   は見えなくなります。
   基準電圧ICを使った時のパスコンは有効という
   ことがわかります。

対策案
・ATmega328PのAREFをオペアンプでバッファして
 基準電圧を得るのはOKだが、それをPWM制御する
 マルチプレクサにつなぐのは×。
・PWMするマルチプレクサでD/A変換する時は、
 パスコンを付加できる基準電圧ICを使う。

こんなところでしょう。
  ※見えなくなるけど、それでも、短絡は発生してる。
   ノイズ発生の要因になるか。

※注1
基準電圧ICに付加するパスコン、こんなことも
ありますので。
2019年9月14日:良かれと思って付けたコンデンサが・・・
  ※AD680・・・発振!

※どうなんだろう
多チャンネル入力A/Dコンバータ、たいていの場合
マルチプレクサが入力。
チャンネル切換時に今回のようなことが起こる心配
は無いのか?
入力に入れたCRフィルタが役立つかも。

※ブレッドボードで実験
002_20230103102701
クロック源はATmega328Pを使ったパルスジェネレータ
拡大。
003_20230103102701


| | コメント (0)

2022年12月27日 (火)

クリック有りのロータリーエンコーダ

2022年8月24日:パルスジェネレータを作ってみた:箱に入れた
で使ったのはアルプス製のロータリーエンコーダ
   ・EC12E2420801(秋月)
そして、この記事では、
2020年9月12日:ロータリーエンコーダーの2相パルスをピン変化割り込みで取り込む
   ・Bourns ECW1J-B24-BC0024L

今回の工作、アルプス製の手持ちを切らしてしまったんで、
ボーンズのを使ってゴソゴソしてました。
Bs11
ところが・・・
「パルスジェネレータ」で使ったエンコーダの入力処理、
  ・2020年9月16日:ロータリーエンコーダーの2相パルスをタイマー割り込みで
だと、ボーンズのでは取りこぼしが生じるのです。

なんで? っとオシロの出番。
  ※動作実績のあるモノ(ソフトもハードも)
   がアウト!って、けっこう精神的ダメージ。

※状態
・待機状態でA、B信号ともオフで、1クリックで
 A相にLパルスが出るのはアルプスと同じ。
・アルプスのに比べてチャタリングが大きい。
   これは1000PFコンデンサをGND間に入れる
   ことで解決できる。
・しかし・・・このパルス幅が短い。
   前の記事に出した波形を見なおしたら、
   そうなっている。
・現在のチャタリング除去は、0.5ms周期の割り込み
 で4回安定。=2ms
・ところが、高速に回すと1ms近くまで
 パルス幅が短く。
・パルス抜けの原因はこれ。

2020年9月12日 の実験では、ボーンズのを
  「クリック無し状態に改造」
してあれこれしていたので、短パルスの出現に気が付か
なかったのでしょう。
1ms近くまで短くなった波形をオシロで観察していた
のに、です。

今朝、試すとこんな波形が出ました。
E11_m

チャタリング+バウンズはコンデンサで取れます。
でも、想定より短い接点オンのタイミングはソフトを
手直ししないとダメです。

タイマー割り込みでの処理、アルプス製のエンコーダ
だと、コンデンサ無しでも安定に動いてます。
どうしたものか・・・

ボーンズのカタログにある推奨回路、
  MC14490で「5ms」のディレー
と、記されてますが、そこまで遅らせると
パルスが無くなっちゃいます。
B2

メカ絡みの電子部品、「使ってみないと分からんわ」の
例でしょか。

※0.5ms=2kHzのタイマー割り込みを0.25ms=4kHzに
早くして試してみますわ。

※現状(0.5ms割り込み処理)での抜けの様子。

・正常時1
Ee002_m

・正常時2
Ee000_m

・A相パルスがちょっと短くなって、抜けが発生
Ee001_20221227103701
前半3つはOK。 右の3つがアウト。
4クロック分、安定しなかったのでチャタリングと
判断してしまった。

MC14490の内部構造
144_a
4ビット続けて同じ入力(H/L)が出現したときに安定と判断。
入力にはプルアップ抵抗が入ってます。
16ピンに6素子入っているんですが、入力と出力のピンが
イケズな配置なんです。
TTLの240や241、244に倣ったんでしょうけれど・・・

| | コメント (0)

2022年12月14日 (水)

Arduino UNOを使ったUSB電流計 4桁表示も

デバッグ時の電流チェック用ツール、
2022年11月29日:Arduino UNO(のチップ)を使ったUSB電流計
2022年12月2日:Arduino UNOを使ったUSB電流計 箱に入れて完成
ということで、最小桁を1mAにした3桁表示のは
できあがりました。
A11_20221214145801
・回路図
Ab1_20221214145901
しかし・・・欲が出てくるものです。
「0.1mAまで読みたい」っと。

そうするとATmega328P内蔵の10bit ADCではちょいと
チカラ不足になってしまいます。

部品箱にある手持ちのADCを探すと12bit 1chの
MCP3201が出てきました。
電流検出抵抗は0.075Ω。そして基準電圧を2.5Vに
して300mAフルスケールで電流を計るようにして
みました。
INA180A3で100倍。
0.075Ωに333mAで25mV。
これを100倍で2.5Vの基準電圧値。
0.1mA分解能で表示できます。

電圧は、ATmega328Pの内蔵基準電圧を使って
0~6Vを入力。 3桁表示です。

A12_20221214150001

7seg LEDは緑色に。
4桁連結の手持ち品が無かったので、手配線で
セグメントをつなげています。
A13_20221214150101

A14_20221214150101

これに使った7seg LEDはカソードコモン。
  3桁表示のは3つ連結されていて、
  アノードコモンでした。

Ab2_20221214150101

※スケッチのアップはちょっと待って。

※二つのスケッチと回路図を圧縮(2022-12-21)
   ダウンロード - usb_cur.zip

・タイマ0割り込み(delayなどのシステム用)は止めてます。
   イケズするつもりはないのですが、
   余計な割り込みは不要ということで。
・校正操作はtera termなどの1文字出力できるターミナルで。
・Entを続けて2回入力(1秒内)すると校正モードに。
・直線補間のための電流値と電圧値を8項目設定。

| | コメント (0)

2022年12月12日 (月)

セラロックの精度は±0.5%

Arduino UNOのブートローダーを焼いたATmega328Pで
使う16MHzの発振子、周波数の精度を気にしなければ
セラロック(コンデンサ内蔵型セラミック発振子)が
お手軽です。

素子ごとにばらつきがあるので実際のどのくらいの
周波数になるかは使ってみないとわかりません。
先日使ったこれでは、「16.0202MHz」でした。
「+0.126%」と十分にスペック内です。
  ※タイマーのコンペアマッチで方形波を
   出力して周波数を測定し、分周比から
   原発振周波数を計算。

C11_20221212093301

しかし、計時するタイマー機能を乗せた
スケッチではこの誤差が気になります。
このセラロックでの精度だと1時間で4.5秒、
1日で1分50秒ほど進みます。

水晶発振子にすれば20~30PPM内にできるので、
計時機能のあるモノを作るときはHC-49U/Sを
使うのが間違いありません。
  ※月差ン秒を問題にする時計機能付きの
   ものはRTCなど特殊な装備が必須。
   きっと停電も処理しなくちゃならない
   だろし。

このセラロック、コンデンサが内蔵されてい
るわけですが、
  「さらにパラってみたらどうなる?」
を試してみました。

両端に「15PF」を入れると・・・
周波数は「16.0133MHz」で「+0.083%」に。
ちょっとだけ下がりましたが、計時用タイマーに
使うにはまだまだです。

 

| | コメント (2)

2022年12月 2日 (金)

Arduino UNOを使ったUSB電流計 箱に入れて完成

2022年11月29日:Arduino UNO(のチップ)を使ったUSB電流計
ダイソーの箱(No.1434 トラベルケース S 2P) に入れて完成です。
コネクタ部の加工(四角穴)はドリルでの穴あけが必須。
ヤスリで形を整えました。
「ダイソー ミニケース 5個組」のようにカッターナイフだけでは
加工できません。

悩みどころはスモークのアクリル板を張り付けるかどうか。
・透明なフタ
B12_20221202135601
・スモークアクリルをフタの裏から
B11_20221202135601

スモーク板を入れると真っ正面から見た時はエエ感じな
んですが、使っている7seg LED、そんなに明るくありま
せんのでちょっと暗い感じなんです。

暗いと思ったらフタを開けたらOK!ということで
スモーク板は剥がさず(両面テープ貼り)に様子を見ます。

シリアル出力するデータはこんな具合。
最初にタイトルとEEPROMに記録している設定
パラメータ(校正データ)を出力。
その後、1秒サイクルで電流と電圧値を出力します。
先頭の数字は6桁の連番。
   (6桁が一巡するのは11日半)
経過秒数を示すとともにデータの抜けがないかの
チェック用です。

# USB Cur,Volt checker
# Cur :999mA max
# Volt:5.00V typ
# USB_CUR2.ino 2022-12-01
# 1 mA-Lo : 10
# 2 mA-Lo A/D : 13
# 3 mA-Hi : 900
# 4 mA-hi A/D : 882
# 5 V-Lo : 450
# 6 V-Lo A/D : 264
# 7 V-Hi : 550
# 8 V-Hi A/D : 779
0 1mA 5.00V
1 0mA 5.00V
2 0mA 5.00V
3 81mA 4.99V
4 381mA 4.96V
5 706mA 4.93V
6 963mA 4.91V
7 1044mA 4.90V
  :

そうそう。
あれこれ作っているツールが出すシリアル出力データ、
主データ以外の部分の行頭に「#」を付けているのは、
グラフ化ツール「GNU PLOT」のためなんです。
GNU PLOTは「#の付いた行はコメントだ」として
扱ってくれて、グラフ描画データと分離できるんです。


もうひとつ。
今回の電流計、空きピンの「PB2(16pin)」に
割り込み周波数の1/2の方形波を出力しています。
500Hz=2ms周期がLEDのダイナミック点灯。
この半分の周波数の方形波が出ています。
  ハード的にコンペアマッチでトグルしてます
  んで、ジッタはありません。
この周波数を読めばクロックの周波数精度がわかります。
こちらでは「250.3231Hz」とずいぶん高め。
  +0.13%。 1日あたり112秒進む。
セラミック発振子を水晶に変えるほうが良いかなぁ。

| | コメント (0)

2022年11月29日 (火)

Arduino UNO(のチップ)を使ったUSB電流計

単電源で反転アンプ マイナスの入力電圧は増幅できます
は、電流をアナログ出力するだけのものでしたが、
Arduino UNOのチップATmega328Pと3桁7seg LEDで
USBラインの電流値を表示してみました。
U51  
  ※ちょっと訂正。 TNX ラジオペンチさん
  ※電源側のコネクタ、USBではなくXHにしてるのは
   こちらの都合です。

スケッチをアップするためのArduino UNOとのつなぎ
はこんな具合。 +5Vラインはつないでいません。
Aa36
こんな目的です。
・回路の動作テスト、通電OKとなれば(電源周りは正常だと
 わかったら)CVCC電源じゃなく、5V出力のACアダプタ
 (USBコネクタで出てる)を使うことが多くなった。
・CVCC電源にしても手持ちのUSB電流計にしても、電流
 表示の最小桁が10mA。
・試運転中の回路の動作電流、せめて1mAの桁で見ておき
 たい。
ということで、1mA表示の電流計が欲しいとなった次第です。
電流を見るのにテスターをつないだままにするのもちょっと
なぁだし、常用的に電流を監視できるようにと作りました。

内蔵のVref=1.1Vを使っている関係で、電流の計測、
ATmega328Pの10bit A/Dではちょっとチカラ不足。
1bitが1mAステップじゃなく値によっては2mA飛び
になる所も。

電圧のほうは5V±1Vを計るようにしましたんで、
10bitで0.01V表示は余裕です。

まず、これが5年ほど前に買ったUSB電流計。
B11_20221129172301  

携帯電話などの充電時、充電した電流量をチェックで
きます。
でも、電流は10mAが最小。
文字も小さいし。

せっかくなんで中味も。
B12_20221129172301
B13_20221129172401
PIC16F1933が使われています。
電源はレギュレータで落として3.3Vで動いています。
B14_20221129172401  

電流検出のアナログ部はこんな具合。
電流検出抵抗はGND側に入っています。
B15_20221129172501

50mΩを2パラで25mΩ
LM358で増幅。
R38が01Bで1kΩ。
R39が30Cで20kΩ。
20倍か21倍かのアンプ。
1Aで25mV。 それを20倍だと0.5V。
スペックでは最大3.5Aとなっているので
4Aで2V。 2Vあたりの基準電源でしょうか。

製作した回路。
A15_20221129174501

基板をこのケースに入れるつもりで大きさを決めました。
「ダイソー ミニケース 5個組」が見つからない

この記事で紹介した
No.1434 トラベルケース S 2P
完全に透明なのでLEDもエエ感じ。
  (フィルタが欲しいか)

A12_20221129172501

スケッチのアップはもうちょい整理してからに。

※実験ベンチのCVCC電源(下段)と低周波発振器二つ
B41_20221130102101
上のが「8038」で。
中段のが「MAX038」で。

トラ技Jr.2018年秋号に「8038」復活の記事
20MHzまでの正弦波をスイープ出力するMAX038を使った周波数スイープ・ジェネレータの製作
実験用電源の中身
電源を改造 AD8724D

電流値表示の最小桁が「0.01A =10mA」。
装置をデバッグする時、1mAを読みたいなぁ~と
なったわけです。

※追記
7seg LEDの表示タイミングとA/D変換の関係。
U11_20221201091701

7seg LED表示は500Hz(2ms)割り込みで。
  タイマー1のOC1A割り込みが周期
そのタイミングを使ってA/D変換(電流,電圧の2ch)。
2ms × 2ch × 128回平均で512msごとにデータを
更新。
上図波形の「電流,電圧値計算」の時間で、
「浮動小数点化したmap関数」で2点calを実行。
512ms周期でこれを実行。
  AVRマイコンの浮動小数点計算、なかなか
  早いゾ!

まずタイマー1のOC1B割り込みでLEDの駆動をオフ。
  COMをLに。セグメントをHに

その10us後のOC1A割り込みでA/D変換の
開始を指令。
A/D変換中はLEDがオフしているので、チップ
内の電流増加の影響は少ないはず。

A/D変換完了割り込み(100usちょい後)でLEDの
駆動を再開。
そして10bit A/D結果を平均処理。
2ch × 128回の平均加算完了をメインルーチン側に
知らせて「浮動小数点化したmap」で2点cal。

こんな流れです。

※追記
これが2点cal用の校正データ
1~4が電流用、5~8が電圧用
1,3,5,7がY軸の値(out)。
それぞれ10mA 900mA、4.50V 5.50Vが校正点。
2,4,6,8がその時のX軸(in)、つまりA/D値。

# 1 mA-Lo : 10 …10mA
# 2 mA-Lo A/D : 13
# 3 mA-Hi : 900 …900mA
# 4 mA-hi A/D : 882

# 5 V-Lo : 450 …4.50V
# 6 V-Lo A/D : 264
# 7 V-Hi : 550 …5.50V
# 8 V-Hi A/D : 779

ターミナルとつないで変更できるようにしています。
  EEPROMに保存。

浮動小数点化したmap関数にはmAとVの実値と
A/D値をそのまま食わせます。
いったん電流値や電圧値に変換してからゴソゴソは
ありませんので「1023 vs 1024」は関係ありません。
AREF電圧(定格1.1V)の偏差や抵抗の誤差、A/D変換に
つきまとう誤差は、実値による校正操作で考えなくて
良くなります。
  これが本来の「map関数」だぁ!
Arduino なんとかして誤用を正したい:A/Dの1/1023とmap関数
Arduino 10bit A/D値をmap関数でスケーリングする例


※こまかい補足
AD4の電流入力、1MΩで4Vにプルアップ(!)してるでしょ。
その先はINA180の出力につながる1kΩ。
ちょっとだけプラスに持ち上げることで、0V付近のADC
データを使わないで良いようにしています。
INA180の出力も完全に0Vにならないし。

※追記が続く
単電源で反転アンプ マイナスの入力電圧は増幅できます
この最終回路「INA180を使ったハイサイド電流検出回路」で
表示回路の電流を計ってみました。
U12_20221201102001

一番上の波形(ノイズでジャギジャギ)がこのアンプの出力
です。
  つなぐのにGNDラインが15cmほど延びてい
  るので、ノイズの影響大。
  プローブのGNDは表示回路側。

負荷電流を「18mA」にしました。
7seg表示は「ブランク 1 8.」となり、
COM1の最右桁を点灯したときの電流がいちばん
大きくなります。

そしてCOM3のブランクの所が、負荷電流+回路電流
となります。
全セグメントを点けている「8.」表示で、ブランクより
20mAほどアップ。
セグメントあたり2.5mAの電流ということで、おもわく
通りの駆動ができています。

※「88mA」だと。
表示は「ブランク 8 8.」となります。
U13

「8.」と「8」で電流がちょいと変化しているのが
見えるかと。

中央を拡大。
U14

A/D変換中は全桁をブランクにしている様子が
見えています。

INA180A3(100倍アンプ)の帯域幅は「150kHz」
それによる遅れも見ておかなくてはなりません。

使っているオシロには「高分解モード」という
平均処理的モードがあって(平均回数を指定できる
モードとは別に)、ノイズを低減できます。
  ただし細いパルスは抜けちゃう
それを使うと、こんな具合にジャギジャギを
消すことができます。
U15
  見やすくなりますが、割り込みタイミングの細い
  パルスは消えかけています。


※とりあえずスケッチを (ZIP圧縮)
  ・ダウンロード - usb_cur2.zip

900行ほどのプログラムです。
校正はターミナルとつないでということに
なります。
  ※ちょっとしたバグを発見しましたんで注意。
   校正モードでの「.」入力の処理。

※追記が続く
Arduino-UNO基板と、アノードコモン7seg LED、
抵抗、ボリューム、スイッチがあれば、電流検出ICが
無くてもこんな接続で「試運転」できます。
U21
calしなくてもボリュームを回せば表示が変化するはず。



| | コメント (4)

2022年11月17日 (木)

1023 vs 1024 、255 vs 256 なんでみなさん「2^n-1」が好きなの?

Arduino、analogWriteは捨てちゃえ。ちゃんとしたPWMを使おう
この直前の名なしさんから頂戴したコメント(2022年11月17日  09時28分)。
1/255や1/1023がおかしいと分かってもらうのに、こんな絵を描いてみました。
いかがでしょう。
Ss11_20221117180001
1cmを8bitにしたとき、上位桁がどういうふうに見えるかを
表現してみました。

※定規はほんまもんをスキャン

1cm、2cm・・・とcm単位での区切りのところが、
0x0100、0x0200・・・と8bit単位での桁上がりに
なります。

そこで「分解能」を示すのなら、1cmピッチの定規だと「1/10」。
「1/9」じゃありません。
それを8bitにすると・・・
「1/255」だとアカンのが見えてくるかと。

※コメントした所をコピペしておきます。
~~~~~~~~~~~~~~~~~~~~
1mmごとに目盛が刻まれた定規。
この定規の分解能は1mmで、(基点の0mmにも目盛を
入れるとして)11本目が10mm = 1cm。

目盛0~9の10本、1桁の数字で表現できるのは0~9mm。
0/10cm~9/10cmが計測範囲。
分解能は1/10cm = 1mm。
  1/9cmではありません。
10mm=11本目になると桁が増えます。

ADCだとこの10mmが基準電圧。
「基準電圧 - 1LSB」の入力電圧が最大値です。
~~~~~~~~~~~~~~~~~~~~


※追記 4cmを1023にしたら (2022-11-19)
Ss12
1mm目盛の定規、4cmでの分解能は「1/40」。
「1/39」ではありません。


※さらに追記 1cmフルスケールで
Ss2_20221126092001
定規の読みでも「-1LSB」が値が得られる最大値です。
これで、ADCによる測定が基準電圧を越えられない
ことがわかるでしょう。

| | コメント (4)

より以前の記事一覧