Arduino UNO R4 Minimaの特徴の一つがDAC(D/Aコンバータ)を搭載していること。どんな感じなのか試してみる。
ピン配置
まず、Arduino UNO R4 Minimaのピン配置。公式のデータシートから引用。
Arduino UNO R3と基本的にはコンパチブル。
DACの出力はA0に割り当てられている(多重化)。
余談ながら、Arduino UNO R4 Minimaの外形寸法はmmだけになっている(R3はmmとmilの併記)。
サンプルプログラム
公式のチュートリアルにDACの解説もある。
ノコギリ波を発生させて圧電サウンダを鳴らすというもの。
- ノコギリ波のデータは予めテーブルに用意
- 波形データを読み出してanalogWrite()で出力
- 周期はボリュームで可変
これをそのままやってみる。ただし、音での確認ではなく、オシロスコープで見てみる(実際に鳴らした様子は後でビデオで)。
もっと高速な波形が出るのかと思っていたけど、なんと、最高でも約150Hz、最も遅い設定だと8Hz(遅くするのはいくらでも遅くできるだろうが)。
しかし、150Hz位までしか出せないの?このプログラムでは一周期分のデータを120ポイントで持っているので、例えば半分の60ポイントにすれば周波数は二倍の300Hzくらいにはなるのかもしれない。でも、それにしてもなぁ…。
上限を探る
上のサンプルプログラムはこうなっている。
void loop() {
sample = map(analogRead(A5), 0, 4095, 0, 1000);
analogWrite(DAC, waveformsTable[i]); // write the selected waveform on DAC0
i++;
if (i == maxSamplesNum) // Reset the counter to repeat the wave
i = 0;
delayMicroseconds(sample); // Hold the sample value for the sample time
}
この中で、時間の制約となるのはanalogRead()で可変抵抗を読み取り。また、loop()を使って回しているので、loop()を呼び出す事自体がオーバヘッドとなる。
ということで、そうした制約をなくしてブン回して周波数はいくつになるかやってみる。上のノコギリ波のプログラムを改造して使ってもいいのだけど、ATtiny85でやったものと同じ正弦波でやって見る(一周期は32ポイントに分割)。
#define N_WAVE 32 /* 正弦波テーブルの数(一周期分) */
unsigned int wave[N_WAVE]; // 正弦波テーブル
void setup() {
float unit_deg;
int i;
/* 正弦波テーブル作成 */
unit_deg = (2.0 * 3.141592) / (float)(N_WAVE);
for (i = 0; i < N_WAVE; i++) {
wave[i] = (unsigned int)((((sin(unit_deg * (float)i) + 1.0) / 2.0) * 4095.0) + 0.5);
}
analogWriteResolution(12);
}
void loop() {
int i;
i = 0;
while (1) {
analogWrite(DAC, wave[i]);
i++;
if (i >= N_WAVE) {
i = 0;
}
}
}
DACの解像度は12ビットを指定した(analogWriteResolution(12))。
実際に出力波形がこれ。
周波数は約3.2kHz。ここまでしかいかないのかぁ。
出力にはLPFは入れずに直接オシロにつないで見たので波形がガタガタしている。
まとめなど
analogWrite()をただブン回すだけのシンプルなものでも3kHzくらいまでしか出せない。これだと音源として使うには厳しそう。RA4M1のデータシートを見ると、DACのConversion timeは最大で30μsとなっているので、もうちょっと上まで出てくれても良さそうな気もするのだけど。analogWrite()が重いんだろうか?
最後に音を。前半がノコギリ波。最高でも150Hzくらいまでなので、圧電サウンダを鳴らすには厳しい(周波数が低すぎる)。最後の数秒は正弦波(約3.2kHz)。
コメント