Arduino UNO R4 WiFi デジタルアナログ変換器(DAC)

UNO R4 WiFiボードのDACを使い、波形を生成し、圧電素子に出力する方法を学びます。


AUTHOR: Jacob Hylén


Arduino UNO R4 WiFiは、デジタル信号をアナログ信号に変換するDAC(Digital-to-analog Converter: デジタルアナログ変換器)を搭載しています。この機能は、多くの楽しいオーディオプロジェクトを作るのに使うことができるだけでなく、例えば、安価なファンクションジェネレーターとして、プロのラボ機器として動作させることもできます。

目的

この記事では、以下を学びます。

  • UNO R4 WiFiに搭載されているDAC機能
  • PWMとDACの違い
  • 波形(サイン波)の生成方法
  • 圧電スピーカーへの波形の出力方法

必要なハードウェアとソフトウェア

回路図

このチュートリアルで必要な回路図は以下の通りです。

UNO R4に接続された圧電ブザー

UNO R4に接続された圧電ブザー

アナログ出力とPWM

アナログ出力が必要となる多くのユースケースでは、本物のアナログ出力の代わりにPWM(パルス幅変調)を使っても、原則的に同じ結果が得られます。デジタル出力ピンは、完全にオン(HIGH)か完全にオフ(LOW)のどちらかにしかなりませんが、精密なタイミングでオンとオフを繰り返せば、平均電圧を制御でき、アナログ出力を模擬できます。この方法はPWMと呼ばれます。

例えば、LEDを薄暗くするときは、PWM出力できるデジタルピンをアナログピンとして自由に利用できます。そして、LEDはDAC出力を使っているときと同じように薄暗くなります。

しかし、これは常に成り立つとは限りません。望みの結果を得るには本物のアナログ出力が必要となる場合が多くあります。オーディオ出力がこの一例です。PWM出力では、本物のアナログ出力と同じ品質の音を得られません。また、多少の工夫が必要となります。

コード

このチュートリアル向けのコードは2つの部分に分かれています。一つはメインスケッチで、もう一つは事前に生成されたのこぎり波を含むヘッダファイルです。

このスケッチでは、事前に生成したサイン波があります。スケッチの最初や途中で、動的にサイン波を生成することもできますが、いいパフォーマンスが得られないので効率的ではありません。なので、事前に生成するのが最適な方法です。

波形は、サンプルとして配列に格納します。スケッチの各ループでは、DACの出力値を配列の次の値に更新します。

新しいスケッチを開き、以下のコードをペーストしてください。

i
ソースコードは、Githubにもあります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
  SineWave

  Generates a pre-generated sawtooth-waveform.

  See the full documentation here:
  https://docs.arduino.cc/tutorials/uno-r4-wifi/dac
*/

#include "analogWave.h" // Include the library for analog waveform generation

analogWave wave(DAC);   // Create an instance of the analogWave class, using the DAC pin

int freq = 10;  // in hertz, change accordingly

void setup() {
  Serial.begin(115200);  // Initialize serial communication at a baud rate of 115200
  wave.sine(freq);       // Generate a sine wave with the initial frequency
}

void loop() {
  // Read an analog value from pin A5 and map it to a frequency range
  freq = map(analogRead(A5), 0, 1024, 0, 10000);

  // Print the updated frequency to the serial monitor
  Serial.println("Frequency is now " + String(freq) + " hz");

  wave.freq(freq);  // Set the frequency of the waveform generator to the updated value
  delay(1000);      // Delay for one second before repeating
}

テストする

コードをボードにアップロードしたら、DACにサイン波の生成し、圧電ブザーやスピーカーに音を生成します。オシロスコープがあれば、プローブをDAC出力に接続して波形がどのようになるのかを見てみるのも面白いと思います。

次に、可変抵抗器をひねって、どのように音が変化するか見てみましょう。

アナログ波の形

上述のスケッチは、サイン波を生成します。電圧を時間に対してプロットすると、その線がサイン関数のように見えるので、サイン波と呼ばれます。

サイン波と比べ、全く異なる音を生成するアナログ波もいくつかあります。このスケッチで利用しているライブラリは、のこぎり波と矩形波を生成することもできます。これらの波形の名前も、電圧を時間に対してプロットした形から名付けられています。

波形を変更して、音がどのように変わるか聞いてみましょう。

スケッチの18行目の"wave.sine(freq);"を、以下のように変更してください。

1
wave.square(freq);

1
wave.saw(freq);

設定が機能していることがわかると思います。別の例も試すことができ、UNO R4のDACをどのように使えば、音やメロディを生成できるか理解できると思います。

i
注意: この設定では、圧電ブザーを使っています。音がとても小さいことに気づくと思います。音を大きくするには4Ωか8Ωのスピーカーと、アンプが必要です。簡単に使えるブレイクアウトアンプモジュールをネットで多く見つけることができます。

Frere Jacques

以下のコードはFrere Jacquesのメロディを演奏します。

i
ソースコードは、Githubにもあります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
  DAC Melody player

  Generates a series of tones from MIDI note values
  using the Uno R4 DAC and the AnalogWave Library.
   The melody is "Frere Jacques"

circuit:
     * audio amp (LM386 used for testing) input+ attached to A0
     * audio amp input- attached to ground
     * 4-8-ohm speaker attached to amp output+
     * Potentiometer connected to pin A5

  created 13 Feb 2017
  modified 3 Jul 2023
  by Tom Igoe

  See the full documentation here:
  https://docs.arduino.cc/tutorials/uno-r4-wifi/dac
*/
#include "analogWave.h"
analogWave wave(DAC);

#define NOTE_A4 69         // MIDI note value for middle A
#define FREQ_A4 440        // frequency for middle A

// the tonic, or first note of the key signature for the song:
int tonic = 65;
// the melody sequence. Note values are relative to the tonic:
int melody[] = {1, 3, 5, 1,
                1, 3, 5, 1,
                5, 6, 8, 5, 6, 8,
                8, 10, 8, 6, 5, 1,
                8, 10, 8, 6, 5, 1,
                1, -4, 1,
                1, -4, 1
               };
// the rhythm sequence. Values are 1/note, e.g. 4 = 1/4 note:
int rhythm[] = {4, 4, 4, 4,
                4, 4, 4, 4,
                4, 4, 2,
                4, 4, 2,
                8, 8, 8, 8, 4, 4,
                8, 8, 8, 8, 4, 4,
                4, 4, 2,
                4, 4, 2
               };
// which note of the melody to play:
int noteCounter = 0;

int bpm = 120;  // beats per minute
// duration of a beat in ms
float beatDuration = 60.0 / bpm * 1000;

void setup() {
// start the sine wave generator:
  wave.sine(10);
}

void loop() {
  // current note is an element of the array:
  int currentNote = melody[noteCounter] + tonic;
  // play a note from the melody:
  // convert MIDI note number to frequency:
  float frequency =  FREQ_A4 * pow(2, ((currentNote - NOTE_A4) / 12.0));

  // all the notes in this are sixteenth notes,
  // which is 1/4 of a beat, so:
  float noteDuration = beatDuration * (4.0 / rhythm[noteCounter]);
  // turn the note on:
  wave.freq(frequency);
 // tone(speakerPin, frequency, noteDuration * 0.85);
  // keep it on for the appropriate duration:
  delay(noteDuration * 0.85);
  wave.stop();
  delay(noteDuration * 0.15);
  // turn the note off:
 // noTone(speakerPin);
  // increment the note number for next time through the loop:
  noteCounter++;
  // keep the note in the range from 0 - 32 using modulo:
  noteCounter = noteCounter % 32;

}

MIDI Piano Notes

このスケッチは、可変抵抗器の入力を段階に分解し、ピアノの鍵盤に対応した88のMIDIノートに変換します。

i
ソースコードは、Githubにもあります。

まとめ

このチュートリアルでは、Arduino UNO R4ボードのDACを試しました。最初にサイン波を生成し、その後、様々な例を通じて、アナログ出力の可能性を見てきました。

オリジナルのページ

https://docs.arduino.cc/tutorials/uno-r4-wifi/dac

最終更新日

November 12, 2023

inserted by FC2 system