AD9833波形発生器をArduinoで使う

アナログデバイセズのプログラマブル波形発生チップAD9833を搭載したモジュールがAliexpressで数百円で売られている。

このチップは信号波形のデジタルデータをチップ内部のメモリに持っておいてD/Aコンバーターでアナログ波形として出力するDDS(Direct Digital Synthesis)という仕組みで動いており、アナログPLL方式のファンクションジェネレーターとは動作原理が全く違うためコンパクトながらも高精度な信号生成が可能だ。

AD9833のArduino用ドライバがGitHubに公開されている。今回は、このドライバを使ってArduinoコントロールで波形発生器を動かしたので、記事にまとめてみる。

スポンサーリンク

AD9833モジュールの配線とArduinoドライバ

ArduinoドライバはGitHub公開の以下の物をチョイス。

Arduinoとの配線やスケッチの#defineマクロは以下のようにする。
(ArduinoはUNO相当のいつものやつを使用)

AD9833モジュールArduino#defineマクロ名
REF未接続
VCC+3.3〜5V
GNDGND
DATMOSI(D11)
CLKSCK(D13)
FNCD10(任意)FNC_PIN
OUT信号出力

AD9833の動作電圧は2.3〜5.5Vと幅広いので、Arduino用の電源をそのまま供給すれば良いだろう。

サンプルスケッチを動かす

AD9833-Library-Arduino付属のサンプルスケッチAD9833_test_suiteをビルドして動かしてみる。シリアルコンソールを9600bpsで繋ぐと、以下のようなメニューが表示される。

****** AD9833 Test Menu ******

'1' IncrementFrequencyTest
'2' CycleWaveformsTest
'3' SwitchFrequencyRegisterTest
'4' PhaseTest
'5' RequestedvsProgrammedValues
'6' Output ON
Enter a number 1 to 6 >

キーボードから数字の1と6を入力すると以下のような表示に変化する。

****** AD9833 Test Menu ******

'1' IncrementFrequencyTest      RUNNING
'2' CycleWaveformsTest
'3' SwitchFrequencyRegisterTest
'4' PhaseTest
'5' RequestedvsProgrammedValues
'6' Output ON
Enter a number 1 to 6 >

この状態でモジュールのOUTピンの信号をADALM2000のアナログ入力と接続し、Scopyのオシロスコープで波形観測をすると、綺麗なサイン波が出力されているのが確認出来る。また、FFT表示も出して確認すると、1kHzから始まって5kHzまで周波数が徐々に上がって1kHzに戻るというのを繰り返しているのがわかる。

このサンプルスケッチではこの他にもサイン波以外の波形出力や位相変調器を使った信号生成など、AD9833が持っている様々な機能をテストすることが出来る。

モジュール基板にDCカット用コンデンサを取り付ける

Scopyに表示されている信号波形をよく見ると、信号がマイナス方向に振れていない事に気づく。これはAD9833の内蔵D/Aコンバータの仕様なので、このDCオフセットを取り除くには出力にコンデンサを取り付ける必要がある。

実はそこを見越してモジュール基板にはコンデンサC2用のパターンが既に用意されており、ここにコンデンサをハンダ付けすればよい。但し、隣の0Ωはコンデンサの回路をバイパスするための物なので取り外す必要がある。

0Ωを取り外し、チップコンデンサが無かったので普通のセラミックコンデンサをハンダ付けした写真は以下。SMAコネクタとOUT端子は繋がっているので、どちらからもDCカットされた信号を取り出すことが出来る。

とりあえず数百kHzの信号生成に使いたいと思っているので0.01uFを付けてみたが、出力先のインピーダンスや信号の周波数によっては変更が必要かもしれない。

固定周波数のサイン波を出力するスケッチ

単純に固定周波数でサイン波を生成させるだけのサンプルスケッチApplySignalも用意されており、このApplySignalスケッチを少し改造して固定周波数のサイン波生成用に作成したスケッチは以下の通り。

#include <AD9833.h>

#define SIN_FREQ 1000.0 // サイン波の周波数を指定

#define FNC_PIN 10

AD9833 gen(FNC_PIN);

void setup() {
    char  buffer[20];

    Serial.begin(9600);

    gen.Begin();              
    gen.ApplySignal(SINE_WAVE, REG0, SIN_FREQ);

    float actFreq = gen.GetActualProgrammedFrequency(REG0);
    Serial.print(F("Output Frequency(Hz):"));
    dtostrf(actFreq,14,5,buffer); 
    Serial.println(buffer);       

    gen.EnableOutput(true);
}

void loop() {
}

サイン波の周波数とAD9833のサンプリング周波数の組み合わせによっては指定通りの周波数を生成する事が出来ないため、AD9833が周波数の補正を行うことがある。この補正された周波数を問い合わせるAPIがGetActualProgrammedFrequencyメソッドであり、このGetActualProgrammedFrequencyの呼び出しで取得した実際に出力されるサイン波の周波数をシリアルコンソールに出力させている。実際、1000Hzを指定している上記スケッチを実行すると、シリアルコンソールには999.96106Hzが表示される。

Output Frequency(Hz):     999.96106

まとめ

GitHubに公開されているArduino用ドライバを使って、AD9833搭載のモジュールを実際に動かしてみた。SPI経由のレジスタの設定など面倒な事は全てドライバがやってくれるので、わずか数行のコードを書くだけで好きな周波数の信号を生成出来る。なかなか便利に使えそうだ。

コメント