Arduino APIとの比較を通じてArm純正RTOS、Mbed OS6の入出力API群を練習してます。前回はPWM出力、今回はDAコンバータを使った「真の」アナログ出力です。対応ボードの都合上、Arduino側はUNO R4のみ。Mbed OS6側はNUCLEO‐F446REのみです。出力電圧を観察するだけ。
※「モダンOSのお砂場」投稿順Indexはこちら
※Arm社のWeb開発環境(無料)、Arm Keil Studio Cloud 上でArm社のRTOS、Arm Mbed OS6 を使って実験してます。ターゲット機はST Microelectronis製STM32F446RE搭載、NUCLEO-F446REボードです。
DAコンバータ
最近の各社マイコンにはDAコンバータの搭載機種が増えているような気もします。しかし、必ずしも全ての機種で搭載ということにはなってないです。まあ大人の事情ね。今回実験に使っているボードで搭載しているのは以下です。
-
- Arduino UNO R4、12bit DAC搭載。使えるのは1チャンネルのみ
- NUCLEO-F446RE、12bit DAC搭載。2チャンネル。
ただしUNO R4はIO電圧5Vなので、DA出力は0Vからほぼほぼ5V付近まで。一方NUCLEO F446REは3.3VのIO電圧なので、DA出力も0Vからほぼほぼ3.3V付近までです。
Arduino環境でのアナログ(DAC)出力
前回みたとおり、Arduino環境では analogWrite()関数をPWM出力に使ってました。これはArduino UNO R4でも変わらないのですが、
analogWrite()するピンをDACの出力ピンに向ける
ように設定すると、あれま、同じAPI関数がDAC出力を司ってくれます。ちょっとこんがらがるな~。まあ、PWM出力は特定のデジタルIO端子に対してしか効果を持たず、DAC出力は1端子(A0端子)のみなのでなんとか覚えられますが。さらに言うとPWM出力のときはpinModeでOUTPUT設定しておくお約束でしたが、DAC出力の場合はpinModeの設定は不要。
なおデフォルトでは、DAC出力のレゾリューションもPWMにあわせて8ビットになっているみたいです。analogWriteResolution()関数を使えばレゾリューションを12ビットにできることはできますが、PWMもDACも同じ関数というのが釈然としないなあ。
なお、Arduino UNO R4では、PWMと互換の関数でDACを制御する以外に以下のお名前のクラスのインスタンスを定義することで波形出力ができるようになります。要「#include “analogWave.h”」です。
analogWave
コンストラクタには端子名を与える必要があるのですが、UNO R4の場合1端子しかないので、以下の1択っす。
analogWave wave(DAC);
振幅、周波数、オフセット、全て思いのままじゃと。その上で、ノコギリ波、サイン波、矩形波を生成することもできると。なかなか嬉しい機能です。
実際にデフォルト設定のまま、440Hzの正弦波を出力してみたところが以下に。
ちょっとガタついているけれども。
一方、地味なanalogWrite()関数でアナログ出力してみたものが以下に。こちらはレゾリューションを12ビットにアップした上で、値1024と値2048をanalogWrite()してます。
Mbed OS6上でのAnalog(DAC)出力
お作法どおりです。特定のピンに対してインスタンスを生成することによってAnalog出力が使えるようになります。使用するクラスは以下です。
実機上で動作確認したクラスインスタンスの生成は以下です。
AnalogOut ao2(ARDUINO_UNO_A2);
これで、以降 A2 ピンを対象にAnalog出力を行う ao2 という名のインスタンスが使用できます。
やはりMbed OS6では、アカラサマに各社のレジスタ値などを見せることは避けられているようで、出力電圧の設定はお行儀が良いです。
-
- write()、float型の0.0f ~ 1.0f を出力電圧の0%~100%とする
- write_u16()、符号なし16ビット整数で設定。0xFFFFで出力電圧の最高値。
上記のメソッドを ao2.write(0.1f)みたいに使っても良いのですが、代入演算子もオーバライドされているので、以下のような単刀直入な書き方も可能。
ao2 = 0.1f;
今回は、NUCLEO‐F446REを使用なので、忘れずにターゲットをF446REに変更しておきます。
ターゲットがF401REのままだと、Keil Studio CloudはF401REはDACの搭載がないことを知っているのでエラーになる筈。
そこで、以下のような10%、20%、30%の階段波形をmain()ループ内で出力するように設定し、
いい感じでないかい。