今回試用してみるデバイスはDDS(ダイレクト・デジタル・シンセサイザ)です。正弦波、三角波、矩形波などの波形をお好みでシンセサイズしたのち、DAコンバータを介してアナログ出力できるもの。ディープな用途には必携?らしいデバイスであります。動作させるためにはホストのマイコン必要。今回はM5Stackを使ってテスト。
※「部品屋根性」投稿順Indexはこちら
ダイレクトデジタルシンセサイザ(DDS)
以下のアナデバ様の製品ページ(日本語)では素直に「プログラマブル波形生成器」とタイトルされております。
AD9837 プログラマブル波形生成器、2.3V~5.5V、低消費電力8.5mW
カッコいいデバイスらしくパッケージはLFCSPのみ。私ははんだ付けすることができませぬ。しかし、いつものように秋月電子通商殿からDIP化モジュール(米国式に言うとブレークアウト・ボード)がでてます。ピンヘッダをはんだ付けすればOKっと。
ホストにはMicroPython搭載のM5Stack
「シンセサイザ」であるだけに、波形や周波数、位相といった項目をデジタルな数値で指定しないとなりませぬ。そのインタフェースはSPIです。よってSPIマスタになれるデバイスが必要です。そこで今回は別シリーズでMicroPython (UIFlow2版)を書き込んで使っているM5Stack Gray をホストにして動作確認してみることにいたしました。回路はこんな感じ。
ESP32マイコンを搭載するM5StackはハードウエアのSPIも搭載しているのですが、内部で他の用途に「いろいろ」使っているのでハードウエアSPIのチャネルには接続せず、GPIO端子をソフトウエアSPIで使用することにいたします。
なお、AD9837はデジタルにシンセサイズする回路であるだけにクロックが必要です。今回は、後に述べるアプリケーションノートの関係で25MHzのクロックが欲しかったです。M5Stack(ESP32)上のMicroPythonで25MHzクロックを生成させる方法については別シリーズの以下記事でやってます。
MicroPython的午睡(134)M5Stack UIFlow2、CLOCK出力
テストに使用したMicroPythonスクリプト
今回は 400Hzの正弦波を生成してみています。これはアナデバ様の以下のアプリケーション・ノートで設定値などが書かれていたので、その値をそのままコピペして設定したものです(あざ~す。)
なお、上記のAD9833/AD9834と今回のAD9837の設定方法は同じということみたいです。知らんけど。
上記アプリケーション・ノートの設定値を流し込むスクリプトをMicroPythonで書いたものが以下に。
# AD9837sinwave400Hz.py import machine import M5 import time mclkOutPin = 5 PWMfreq = 25000000 PWMduty = 512 #50% CSpin= 2 SCK=machine.Pin(16) MO=machine.Pin(17) def main(): M5.begin() print("M5STACK, testAD9837.") cs = machine.Pin(CSpin, mode=machine.Pin.OUT, value=1) mclkOut = machine.PWM(machine.Pin(mclkOutPin), freq=PWMfreq, duty=PWMduty) ad9837 = machine.SoftSPI(baudrate=100000, polarity=1, phase=0, bits=8, firstbit=machine.SPI.MSB, sck=SCK, mosi=MO, miso=machine.Pin(25)) cs(0) ad9837.write((0x2100).to_bytes(2, 'big')) # RESET(Disable OUTPUT) ad9837.write((0x50C7).to_bytes(2, 'big')) # Set Freq Low ad9837.write((0x4000).to_bytes(2, 'big')) # Set Freq High ad9837.write((0xC000).to_bytes(2, 'big')) # Set Phase ad9837.write((0x2000).to_bytes(2, 'big')) # Enable OUTPUT cs(1) loopCounter = 0 while True: loopCounter += 1 print("LOOPCOUNTER: ", loopCounter) time.sleep(10) if __name__ == "__main__": main()
なお、AD9837のレジスタ幅は16ビットなのですが、ESP32版のSoftSPIの場合、ビット幅は8ビットのみ許されるようです。そこで8ビット設定で、必ず2バイト連続で送信してます。MSBファーストなのでバイト順はbig endianね。
また、AD9837の制御はライトオンリなのでMOSIだけあれば良いのです。しかし、miso=Noneと設定したらエラーになったので、急遽、ここでは使っていないPin(25)にmisoを押し付けてます。
実機動作確認
周波数約400Hz、ピークツーピークの振幅約610mV、ほぼほぼ予定通りでないかい。