
前回生成した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作るのメンドクセーなあ。


