【arduino】何事も食わず嫌いはいかん、とりあえずやってみることが大事だ
どうも、じぇいかわさきです。
今回も自分が取り組んでいるArduinoのプログラミングネタで、ADC(Analog Digital Converter)の取り扱いになります。
Raspberry Piの場合には、このADC機能が搭載されていないので外部にADC回路を組み込まなければいけませんが、ArduinoやRaspberry Pi picoの場合には、最初から本体に内蔵されているので、そちらを使用します。
ただし、内蔵版は10bitなので解像度を必要とする場合には、やはり外付けで12bitや16bitのADCの回路を組むことになります。
今回は、内蔵のADCを使いますので、外部回路は不要となります。
こちらも、初めて使うADC機能とプログラミングに挑戦となります。初めてなんで、何となくワクワクしますね。
さあ、それでは実験の始まりです。
まずは実験の前提条件
実験をするといっても、闇雲に実験してもしょうがないです。やはり、最終的にやりたいことを意識して実験環境は作る必要がありますね。
自分がやりたいことの前提条件は以下の通り。
1.入力は0〜750mVとなっている(別回路)
2.750mV入力された時のADCの値を調べたい
3.実験としては5Vを分圧して750mVを作る
ざっとこんな感じです。
上記の条件から、ArduinoのA0ポートにMAX750mVの電圧が入力される環境を擬似的に作る必要があります。
そのためには
1.印加電圧を5V
2.A0ポートに入力されるのは可変抵抗のセンター
3.抵抗と可変抵抗の2つの抵抗で構成する
となります。この時、抵抗をR1とし可変抵抗をR2とします。R2は手持ちで10KΩがありましたので、これを使用することにします。
それではR1をいくつにすればよいのか、オームの法則から解いていきます。
A0ポートに入力する電圧が750mVとし、この時可変抵抗器R2の値は最高の10KΩとなりますから
R1+R2の間に5Vが印加され、R2の両端には0.75Vが発生するのが条件ですから、R1の両端には5V-0.75V=4.25Vが発生します。
(R1/(R1+R2)) * 5V = 4.25Vが成り立ちますから
(R1/(R1+10KΩ)) = 4.25V/5V
R1 = 0.85(R1+10KΩ)
R1 = 0.85R1 + 8.5KΩ
R1 - 0.85R1 = 8.5KΩ
0.15R1 = 8.5KΩ
R1 = 8.5KΩ/0.15
R1 = 56.666KΩ
R1は約57KΩとなります。手元に57KΩがなかったので、100KΩを2つ並列にして50KΩとし、50KΩと10KΩの可変抵抗で実験環境を作りました。
こんなかんじですね。
コードを考えてみる
実験環境は出来上がりました。それでは実際のコードを考えていきましょう。
まずは、A0ポートに先程の可変抵抗器の値を入れるようにします。
ここでは
#define IN_FWD A0
としてIN_FWDと言う変数にA0の値が入るようにします。
次にArduino nanoで搭載しているADCは10bitですから、2の10乗となりますから1024ですね。すなわち0〜1023の値で表現することができるということです。
ADCの値を実際の電圧に変換するには
(ADC値 * 5V)/1024
で実際の電圧を求めることができます。
出来上がったコードは以下の通り。
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#define IN_FWD A0
void setup() {
// put your setup code here, to run once:
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.begin(16, 2);
}
void loop() {
float analog_0 = analogRead(IN_FWD);
float voltage_0 = (analog_0 * 5)/1024;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("ADC=");
lcd.setCursor(0,1);
lcd.print("V=");
delay(1000);
}
このコードで、ADCに入力された値と電圧をLCDに表示します。
実際にコードをコンパイルして、Arduinoに流し込んだ結果がこのようになります。
目的としていた、ADCの使い方とLCDへの表示ができました。
表示をよく見るとちょっと問題が
出来上がったプログラムで、可変抵抗器を回していくとADCの値と電圧値が変わっていきますので、問題なく動いている事が確認できました。
しかし、よく表示をみているとアレ?って言うことに気が付きました。
自分が最初に定義した条件は、750mVを最大とするでした。確かに表示は0.80Vまで行きます。これは57KΩに対して50KΩだったことにより目標上限を超えているとおもいますが、問題はそこではありません。
750mVまでですから、0.750という表示にならなければいけません。なぜなら、750mVの1/10は75mVですから、0.075と表示しなければいけないのですが、今のままでは0.07か0.08のどちらかになってしまいます。
今まで、floatの関数はそのまま使用してきているので、小数点以下の桁数を指定する方法は知りません。
どうしたらよいか?
困った時のGoogle先生に聞いてみましょう。
どうやら表示する際に、Stringの文字関数に変換し、その際に桁数を指定すれば良いようです。
この電圧値は、特に計算に使用しているわけでもなく、表示用なので文字関数でも問題ないと判断しました。
loop内のコードを以下のように書き換えました。
void loop() {
float analog_0 = analogRead(IN_FWD);
float voltage_0 = (analog_0 * 5)/1024;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("ADC=");
lcd.print(String(analog_0,0));
lcd.setCursor(0,1);
lcd.print("V=");
lcd.print(String(voltage_0,4));
delay(1000);
}
変化点としては、ADCの小数点以下は無いので表示を削除。代わりに電圧の表示を小数点以下4桁迄に変更しました。
再コンパイルしてArduinoに書き込み実行させてみると、以下のように改善されていることが確認できました。
これで一様、今回の目的は達成したことになります。
まとめ
今回の目的であった、ADCに入力された電圧のADC値はいくらになり、それを電圧で表示するといくらになるのか、そんなコードを勉強しました。
実際に表示された値と、デスターで測定した値はほぼイコールになりました。
ほぼと言ったのは、テスターのピンを当てると、インピーダンスが変化してADCの値も、電圧表示も少し動いてしまい、テスターの数値と0.002程度の違いが発生したからです。
しかし、実際にはテスターを当てることはありませんので、ほぼ問題なく使用できると思います。
ままではどちらかと言うと、デジタル値での使用が中心であったArduinoですが、今回アナログ値を使用して使用してみても、意外と簡単に使用できることが分かりました。
プログラミングと同じで食わず嫌いはいけませんね。
さあ、また次のステップを考えていきたいと思います。
この考えているときが、また楽しいんですがね。
ここまで読んでいただき、ありがとうございます。