1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MicroPythonを使ってみる(その4)&エレキ素人が何か考える(その7):DAコンバーター

Posted at

MicroPythonとエレキ素人のコラボ(若干こじつけ)

MicroPythonを用いて、Wio TerminalのDAコンバーター経由で正弦波をつくり、オシロスコープで観察してみる。

Wio Terminal

本家サイトはこちらである。後ほどオシロスコープで波形を観察するので、ピン配置を下記に記す。
ピンアサイン.png
ピン11:DAC0(DAコンバーター)、ピン6:GNDとをオシロスコープにつなげる。

MicroPython環境

Wio Terminalでは、本家サイトのArduPyというMicroPythonの環境がある。その手順に従い、ArduPy FirmwareをWio Terminalに入れる。プログラム作成やWio Terminalへの書き込みに関しては、他のIDEを使っても良い。今回は、MicroPythonで有名どころのThonnyを利用した。

正弦波を作り出すソースコード

ここにMicroPythonでDACを扱うコードがあったので、そのまま使おうとしたが、DMA転送によりDACを実現するwrite_timed()という関数が、Wio Terminalに存在しなかった。

>>> from machine import DAC
>>> help(DAC)
object <class 'DAC'> is of type type
  write -- <function>
  resolution -- <function>
  reference -- <function>

他にMicroPythonを扱えるボード(ESP32, ESP8266, Seeeduino XIAO)を所持していたが、いずれにもwrite_timed()には存在しなかった。どうも、write_timed()が存在するのはpyboardのみらしい(執筆時点)。

sleep_us()で実現

そこで、write()とsleep_us()を用いて、ソフトウェア的に無理やり実現する。下記コードとなる。

import time
import math
from machine import DAC, Pin

freq = 100
num = 100
ary = list(range(num))
for i in range(num):
  ary[i]=int(4095*(math.sin(2*math.pi*i/num)+1)/2)
dac = DAC(Pin(11))
while 1:
  for i in range(num):
    dac.write(ary[i])
    time.sleep_us(int(1000000/(num*freq)))

上記コードでは、sin値を整数値化(0-1)し、100Hz(freq)、1周期を100分割(num)して出力している。Wio Terminal DACの分解能は10bit(=4096)であり、分割されたポイントごとの値を事前に作成しておき(配列ary)、freqに従って、アナログ出力(write)する。4096をwriteすると、0Vが出力されたので、最大値を4095としている。

検証の前に

time.sleep_us()の精度が気になるところ。そこで、次のようなコードで確認。

import time
start = time.ticks_us()
time.sleep_us(1)       # 1,10,100,100と変化させる。sleep_ms()にも置き換える。
end = time.ticks_us()
print(str(end-start) + " ticks")
sleep_us() 1 10 100 1000
ticks 26 36 126 1026
sleep_ms() 1 10 100 1000
ticks 1029 10028 100030 1000029

これらから、sleepの確からしさは、1 ms以上と思われる。ここでは、テストなので、100 us以上を考慮した。

検証

今回はオシロスコープとして、pokitMeter(スイッチサイエンスさんで購入)を利用。オシロスコープとWio Terminalとの接続は下記状況。

結果

100Hz(freq)、分割数100(num)と設定した結果(sleep:100us)

image.png
ソフトウェア処理の限界か、100Hzに程遠く、62.9Hzと表示(赤枠)。このオシロスコープでは、周波数解析も可能、下記のとおりの結果。
image.png
ピークは68.226Hz。

100Hz(freq)、分割数50(num)と設定(sleep:200us)


77.7Hzと表示。分割数を減らしたので、若干、波がデジタルチックになってる。

100Hz(freq)、分割数25(num)と設定(sleep:400us)


87.8Hzと表示。波がひどくなってきたが、sleepの回数が減ったため、周波数が100Hzに近づいてきている。

50Hz(freq)、分割数100(num)と設定(sleep:200us)


31.9Hzと表示。

25Hz(freq)、分割数100(num)と設定(sleep:400us)


22.5Hzと表示。

10Hz(freq)、分割数100(num)と設定(sleep:1000us = 1ms)


9.5Hzと表示。

5Hz(freq)、分割数100(num)と設定(sleep:2ms)


4.9Hzと表示。ここまで来ると精度が高くなっている。

最後に

ソフトウェア処理の限界が一部垣間見える。DMAを利用しないとダメか。

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?