モダンOSのお砂場(86) NucleoでArduinoからMbed OS6、アナログ入力

Joseph Halfmoon

Arduino APIとの比較をしながら、Mbed OS6の入出力API群を練習してます。前回は基本のキの字のデジタル入出力でした。今回はアナログ入力です。ADコンバータを使ってアナログ電圧を読み取るもの。コマケー話はいろいろあるケド、まずは読み取るところから。アナログ出力の方は2系統やらないとならないのでまた今度ね。

※「モダンOSのお砂場」投稿順Indexはこちら

※Arm社のWeb開発環境(無料)、Arm Keil Studio Cloud 上でArm社のRTOS、Arm Mbed OS6 を使って実験してます。ターゲット機はST Microelectronis製STM32F401RE搭載、NUCLEO-F401REボードです。

Arduino環境でのアナログ入力

以下の3つのAPIがアナログ入力のために使われますが、ぶちゃけデフォルト設定のままであれば、analogRead()一つで即座にアナログ入力可能です。

    • analogRead()
    • analogReadResolution()
    • analogReference()

analogRead()関数に渡すのはADコンバータに接続可能なピン名のみです。Arduino UnoであればA0からA5までの6本がアナログ入力向けのピンであるのでA0からA5のどれか、ということになります。

Arduino UNO R3の場合、10ビットのADコンバータを搭載しているのでレゾリューションは固定。しかしUNO R4の場合は14ビットのADC搭載だけれども、UNO R3との互換性を考えて初期状態10ビットだそうな。変更したい場合は以下のようにanalogReadResolution()を呼び出せとあります。

analogReadResolution(14);

また、ADコンバータには必ず参照電圧というものがあり、これを基準にAD変換するわけであります。この電圧、UNO R4では2系統使用可能です。この切替に使うのがanalogReference()です。

    • AR_DEFAULT、デフォルト5V(電源電圧に同じ)
    • AR_INTERNAL、内蔵リファレンス電源 1.5V
Mbed OS6上でのアナログ入力

Mbed OS6上では、入出力するピンを対象に「インスタンス」を生成することから始めるという統一的なお作法です。アナログ入力で使うクラスは以下です。

上記からURLをたどっていただいてAPIのリファレンスを見ると分かりますが、ピン名だけでも初期化可能なコンストラクタですが、参照電圧を追加で与えることも可能だと。

ADコンバータのスペックは各社のマイコンでいろいろある筈なので、Mbed OS6上のAPIは「汎用的」なインタフェースになってます。

    • read()メソッドは、正規化されたfloat値を返す [0.0, 1.0]
    • read_u16()メソッドは、符号無整数値16ビットを返す。今回実験につかったSTM32F401REの場合、ADコンバータは12ビットなので、12ビットの値に下4ビット0のゲタを履かせて16ビット化している
    • read_voltage()メソッドは、float型のV単位の値を返す。

今回は、なるべく生の値に近くということで read_u16()メソッドを使ってみました。

実機動作確認

毎度お馴染みの被テストデバイスが以下に。今回はArduino式名称「A5」端子の先に50KΩの多回転ポテンショメータを取り付けてアナログ入力信号としています。AIN_DUT

実験に使ったソース main.cpp が以下に(LCD制御部分などは変更ないので以前のまま。)

#include "mbed.h"
#include "AQM0802.h"
#include "MYSTAT.h"

#define BLINKING_RATE   500ms
#define AIN_RATE        1000ms

I2C i2c(I2C_SDA, I2C_SCL);

AQM0802 lcd(i2c);  

DigitalOut ledRED(ARDUINO_UNO_D2);
Thread threadLED;

AnalogIn ain5(ARDUINO_UNO_A5);
Thread threadAIN5;

void blink_thread()
{
    while (true) {
        ledRED = !ledRED;
        ThisThread::sleep_for(BLINKING_RATE);
    }
}

void ain_thread()
{
    char dstr[8];
    while (true) {
        sprintf(dstr, "%u", ain5.read_u16());
        lcd.displaySTR(LCD_LLINE, dstr);
        ThisThread::sleep_for(AIN_RATE);
    }
}

int main()
{
    lcd.init();
    lcd.displaySTR(LCD_HLINE, "Voltage");
    
    threadLED.start(blink_thread);
    threadAIN5.start(ain_thread);

    while (true) {
        ThisThread::sleep_for(10s);
    }
}

折角RTOSを使っているのに、前回まではThread使ってなかったので、今回は、

    1. LEDを点滅させるLチカスレッド
    2. アナログ入力値を読んでLCD画面に値を表示するスレッド

を独立させてみましたぞ。ポテンショメータのねじを回すと表示の値が変化しますな。これでアナログ入力の練習はできたっと。随分手抜きな。

次回はアナログ出力だな。

モダンOSのお砂場(85) NucleoでArduinoからMbed OS6、デジタルIO へ戻る

モダンOSのお砂場(87) NucleoでArduinoからMbed OS6、PWM出力 へ進む