mbed(NUCLEO-L152RE )でアナログ入出力を行います。
アナログ入出力ピンについて
NUCLEO-L152REのアナログ入出力ピンについて説明します。
NUCLEO-L152RE の仕様ではアナログ入力は21個、アナログ出力は2個になります。
アナログ入出力の最大電圧は3.3[V]です。ピンに5[V]を入れないように注意してください。
アナログ入力の注意点
アナログ入力は最大3.3[V]までです。
5[V]で動かしているから、5[V]トレラントだから5[V]まで使えるのでは?と思う方がいるかもしれませんが、仕様上3.3[V]まで(厳密には違いますが)なので注意してください。
アナログ出力の注意点
アナログ出力はNUCLEO-L152REの場合、通常「1個」しか使うことができません。
NUCLEO-L152RE のアナログ出力のピンは「PA_4」と「PA_5」になります。そして問題なのが、PA_5が基板上のLEDと接続しており、LED制御用のピンとして扱われているからです。なのでプログラム内部でPA_5をアナログ出力に設定できないようになっています。
内部プログラムを改造すれば「PA_5」をアナログ出力として使えるようにできるようですが、私としては特に必要がないので、このまま使用します。
アナログ入出力の値について
アナログ入出力は電圧の値をそのまま使うわけではありません。なので、3[V]出力したいときに、「3」と設定するのは間違いです。
では、どのように扱うのかと言いますと、パーセントで表します。0~1.0までの値です。
整数値で扱う方法もあるのですが、ビット演算など必要になるため、ここでは一般的?なパーセントでの扱い方のみ説明します。
さて、例えばアナログ入力に2[V]が入っていたとします。すると入力値はいくつになるでしょうか?
答えは、2[V]を全体(3.3[V])で割ってやればいいので、大体「0.61」になります。
この様にパーセントで扱うことになるので、少しだけ計算をしなくてはいけません。
また、アナログ入力の分解能は12ビットなので、あまり細かい数値(精度)を期待しても、その12ビットで表すことができる範囲になります。
アナログ入力値のゆれについて
アナログ入力は一定の電圧入力であったとしても数値が上下します。これはアナログ入力の仕様上どうすることもできないことなので、基本的には諦めてください。
例えば、アナログ出力から「0.61」を出します。この値をアナログ入力で受け取ると以下の表のようになります。
入力値 | 電圧 |
0.612454 | 2.021099 |
0.606593 | 2.001758 |
0.611966 | 2.019487 |
0.606593 | 2.001758 |
アナログ入力値では結構大きな違いのように感じますが、電圧にしてしまえば大体2[V]で問題ない感じです。
プログラム
アナログ入出力のプログラムについて簡単に説明します。今回使用するピンは以下の通りです。
- アナログ入力:PA_1
- アナログ出力:PA_4
上記のピンを使用する理由は、隣り合っているのでテストが楽だからです。
以下のプログラムはPA_1とPA_4をジャンパーピンなどで接続した状態を前提とします。
#include "mbed.h" int main() { AnalogIn aIn(PA_1); AnalogOut aOut(PA_4); float outValue = 0.0; printf("Start\r\n"); while (1) { // メイン処理 float inValue = aIn.read(); float voltage = 3.3 * inValue; printf("%f, %f, %f\r\n", outValue, inValue, voltage); // 出力変更 outValue += 0.1; if (outValue > 1.05) { outValue = 0.0; } aOut.write(outValue); wait(1); } }
5行目が「PA_1」をアナログ入力に設定する処理です。
6行目が「PA_4」をアナログ出力に設定する処理です。
12行目は「PA_1」のアナログ入力の値を取得しています。
13行目の計算はアナログ入力値を電圧に計算しています。
15行目は値をパソコンにシリアル出力しています。
22行目はアナログ出力を行っています。今回のプログラムでは1秒ごとに0.1ずつ加算して出力するようにしています。
19行目で1.05と比較していますが、これはアナログ出力の上限値「1.0」の代わりです。1.0と比較してしまうと、プログラムでは1.0になる予定ですが、加算しているため、内部的には1.0より微妙に大きな値になっているからです。
ちなみに「printf(“%0.10f\r\n”, outValue);」として値を表示してみると、1.0の予定の時の値は、「1.0000001192」となっていました。浮動小数点演算での比較での注意点です。
これはmbedに限らずどの環境でも、どの開発言語でも起きうる問題です。これを解決するためには、今のCPUとは全く違う構造のCPUを開発するしかないはずです。簡単?にいうと2進数を使っている限り無理です。
このプログラムを実行すると、以下のような値が表示されます。ちなみに先ほども言いましたが、値にはゆれがあるので、毎回同じ数値になるとは限りません。
出力値 | 入力値 | 入力値を電圧に変換 |
0.0 | 0.003419 | 0.011282 |
0.1 | 0.096703 | 0.319121 |
0.2 | 0.197070 | 0.650330 |
0.3 | 0.302564 | 0.998462 |
0.4 | 0.402442 | 1.328059 |
0.5 | 0.496459 | 1.638315 |
0.6 | 0.596825 | 1.969524 |
0.7 | 0.695727 | 2.295897 |
0.8 | 0.798046 | 2.633553 |
0.9 | 0.902076 | 2.976850 |
1.0 | 0.996337 | 3.287912 |
まとめ
アナログ入出力はどうでしたか?
注意すべき点はいくつかありましたが、手軽に扱えるのを確認してもらえたと思います。
更新履歴
版 | 更新日 | フォームバージョン | mbedライブラリ | 説明 |
新規作成 | 2017/6/9 | V2.J28.M16 | 124:2241e3a39974 |