前回生成した25MHzクロックを使って別シリーズにてDDS、AD9837を駆動、美麗な正弦波を得ることができました。ただブレッドボード接続だったので配線が汚いです。そこでM5Stackの側面のピンソケットに差し込める「アタッチメント」ボートを作製。チェック不十分にて大慌て。壊れずに動いて良かった。
※「MicroPython的午睡」投稿順 Indexはこちら
※M5Stack Grayに書き込んだUIFlow2.0 (Alpha-27)対応のMicroPython処理系とWindowsパソコン上で動作しているThonny 4.0.1で動作確認しています。
AD9837
アナログ・デバイセズ製AD9837は、DDS(ダイレクト・デジタル・シンセサイザ)です。デジタル・シンセシスした正弦波、三角波、矩形波をDAコンバータを通してアナログ出力できるもの。波形、周波数、位相などはSPIマスタからの書き込みに応じて動作します。別件シリーズで正弦波出力の動作確認した記事が以下です。回路図なども以下に。
部品屋根性(113) AD9837、プログラマブル波形生成器、M5Stackで生成テスト
アタッチメントボード
ただね、上記別件シリーズでは通例のごとくブレッドボード上で被テスト回路をこさえたのでジャンパ線の接続が汚いです。そこでM5Stackの側面ピンソケットに差し込める「アタッチメント」形式のボートに設えました。こんな感じ。
出来たところで、つい嬉しくなって、よく確かめもせずにM5Stackに接続し危うく虎の子のAD9837DIP化ボードを壊すところでした。まさかのショート。簡単なボードだからといって手を抜くなよ、自分。。。
上記は配線修正後です。まあ壊れもせず波形出力できているのでまあいいか。
今回作成のMicroPythonスクリプト
別件シリーズでは闇雲に正弦波を出力するだけだったので、こちらでは、波形や周波数をM5Stackの画面とボタンを使ってローカルに設定して動作させたいです。まあ、GUIというほどでないけれども老眼の目にも見える設定方法が良い。今回はボードを作るところで疲れてしまったので、とりあえず以下のようなところまで。
-
- 正弦波、三角波、矩形波の選択機能のみ実装
- Aボタンを押すと、正弦波、三角波、矩形波の選択が「回る」
- Bボタンで決定するとその波形が出力される
# AD9837UI.py import machine import M5 from M5 import * import time mclkOutPin = 5 PWMfreq = 25000000 PWMduty = 512 #50% CSpin= 2 SCK=machine.Pin(16) MO=machine.Pin(17) title0 = None labelA = None labelB = None labelC = None numSEL = 1 numMAX = 3 finFlag = False def btnA_wasClicked(state): global numSEL, numMAX numSEL += 1 if numSEL > numMAX: numSEL = 1 def btnB_wasClicked(state): global finFlag finFlag = True def showTitle(): global title0, labelA, labelB, labelC Widgets.fillScreen(0x222222) title0 = Widgets.Title("AD9837 DDS", 20, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu24) labelA = Widgets.Label("Select Waveform", 20, 24, 1.0, 0x222222, 0xFFFFFF, Widgets.FONTS.DejaVu24) labelB = Widgets.Label("SINE ", 20, 48, 1.0, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu24) labelC = Widgets.Label("---", 20, 72, 1.0, 0x222222, 0xFFFFFF, Widgets.FONTS.DejaVu24) M5.update() def selWave(): global finFlag, numSEL, numMAX, labelB, labelC numMAX = 3 while not finFlag: M5.update() if numSEL == 1: labelB.setText("SINE ") elif numSEL == 2: labelB.setText("TRIANGLE ") else: labelB.setText("RECTANGLE") time.sleep_ms(100) if numSEL == 1: labelC.setText("SINE ") elif numSEL == 2: labelC.setText("TRIANGLE ") else: labelC.setText("RECTANGLE") finFlag = False return numSEL def main(): M5.begin() print("M5STACK, testAD9837.") showTitle() BtnA.setCallback(type=BtnA.CB_TYPE.WAS_CLICKED, cb=btnA_wasClicked) BtnB.setCallback(type=BtnB.CB_TYPE.WAS_CLICKED, cb=btnB_wasClicked) selectResult = selWave() print("select: {0}".format(selectResult)) if selectResult == 1: cword = 0x2000 elif selectResult == 2: cword = 0x2002 else: cword = 0x2028 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((cword).to_bytes(2, 'big')) # Enable OUTPUT cs(1) loopCounter = 0 while True: loopCounter += 1 print("LOOPCOUNTER: ", loopCounter) time.sleep(10) if __name__ == "__main__": main()
実機動作確認
以下のようにAボタンを何回か押して、上から3行目の青のラインで波形を選択し、Bボタンを押すと上から4行目に選択結果が白のラインで表示され、出力がイネーブルとなります。
矩形波だけは「デジタル」なので振幅が異なります。
波形の選択はできた。でも周波数が400Hz固定のまま。当然、周波数設定のところも作るよね、自分。UI作るのメンドクセーなあ。