UNO R4 の DAC について調べてみた。 [Arduino]
Arduino UNO R4 には、DAC (Digital Analog Converter) がついています。
アナログのA0ピンです。
デジタルでいうと14ピン。
UNO R4だと、定数で DAC および A0 が 14 となっていました。
どうやって出力するかというと、analogWrite を使うだけ。
analogWrite( ピン番号 , 値 );
でいい。
値は、
analogWriteResolution( 分解能(ビット数)) ;
で指定した範囲。
これを指定しない場合はデフォルトの8になるので、0-255の範囲。12を指定すると0-4095の範囲。
// UNO R4 DAC analogWrite
void setup() {
analogWriteResolution( 12 ); // If not specified, the default is 8.
}
void loop() {
static uint16_t val;
val = ++val & 0x0fff; // 0, 1, 2, ..., 4095 , 0, 1, 2, ...
analogWrite( DAC, val );
delayMicroseconds( 500 );
}
ピン番号がDAC対応ピン(DAC/A0/D14)だとDACで出力し、非対応ピンの場合にはPWMで出力するようになっています。13番ピン(LED_BUILTIN)にすると、PWMで内臓LEDが光ります。
DACピンでの analogWrite() は呼び出されると、大まかに以下の手順。
1. ピンがDAC使用可能ピンか確認
2. DACのチャンネル取得?
3. dac.cppのanalogWriteに値を渡す
4. 値を分解能に合わせてスケーリング
5. 値を書き込む
という手順です。
%localAppData%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.4\cores\arduino
(1.0.4のところはバージョンによって異なります。)
ここの dac.cpp や analog.cpp を参照。
1, 2の作業を毎回ではなく、先にしておいて、3~5だけを行うのが以下のスケッチ。
少し早くなります。(delayMicroseconds()をなくすとよくわかります。)
// UNO R4 DAC analogWrite (faster)
#include <dac.h>
static CDac dac( A0 );
void setup() {
analogWriteResolution( 12 ); // If not specified, the default is 8.
}
void loop() {
static uint16_t val;
val = ++val & 0x0fff; // 12bit : 0, 1, 2, ..., 4095 , 0, 1, 2, ...
dac.analogWrite( val ); // faster
delayMicroseconds( 500 );
}
これでいいのかどうかはわからないけど、とりあえず動いている。
analogWrite()のかわりに、init()とset()だけでいけると思ったけど、だめだった。
さらに、レジスタをいじってみる。(5の作業のみ。)
// UNO R4 DAC analogWrite (fastest)
void setup() {
analogWriteResolution( 12 ); // If not specified, the default is 8.
analogWrite( DAC, 0 ); // For initialization.
}
void loop() {
static uint16_t val;
val = ++val & 0x0fff; // 12bit : 0, 1, 2, ... , 4095, 0, 1, 2, ...
R_DAC->DADR[0] = val;
delayMicroseconds( 500 );
}
DACの初期設定もレジスタをいじるのは大変なので、analogWrite( DAC, 0 ); を1回呼び出すことで代用。
処理速度は断然速いです。
(delayMicroseconds()を外して書き込み、UNO R4を振ると残像の細かさがダントツです。)
(LEDの明るさで動作確認をしたけど、LEDは一定の電圧以下では光らないので、LEDの明るさ調整にはPWMのほうが向いていそう。)