LoginSignup
0
0

More than 1 year has passed since last update.

MicroPythonを使ってみる(その5):DAコンバーター(続き)

Posted at

ソフトウェア処理の改善

前回(MicroPythonを使ってみる(その4)&エレキ素人が何か考える(その7):DAコンバーター)にて、ソフトウェア処理の限界をほのめかたしたところ、有識者からアドバイスされたコードがあり、その結果をここに記す。なお、ハードウェアとしては、継続してWio Terminalを用いている。

ソースコード

オリジナル(コードA)

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)))

アドバイスされたコード(コードB)

上記オリジナルコードの「while 1:」以下を下記コードで置き換える。

currentTicks = time.ticks_us()
while 1:
  for i in range(num):
    dac.write(ary[i])
    lastTicks = currentTicks
    currentTicks = time.ticks_us()
    us = 1000000//(num*freq) - time.ticks_diff(currentTicks, lastTicks)
    if us > 0:
      time.sleep_us(us)

システム稼働時間(マイクロ秒)による調整である。

アドバイスされたコードの変形(コードC)

後述するが、切り捨て処理に差があったので、こちらも記載。

    us = int(1000000/(num*freq)) - time.ticks_diff(currentTicks, lastTicks)

結果

設定値:freq=100Hz,num=100(分割数)

改善の効果が見られたと思う(簡易オシロスコープによる波形および典型的な周波数)。

コードB

コードC

ここでのまとめ+α

コード
計測値(Hz) 62.9 113.4 108.9

コードBとコードCとで違いがあり(切り捨て処理)、下記コードで調査。

import time
freq = 100
num = 100

start = time.ticks_us()
us = int(1000000/(num*freq))
end = time.ticks_us()
print("int " + str(end-start) + " ticks")

start = time.ticks_us()
us = 1000000//(num*freq)
end = time.ticks_us()
print("//  " + str(end-start) + " ticks")

>>> %Run -c $EDITOR_CONTENT
int 46 ticks
//  20 ticks
>>> %Run -c $EDITOR_CONTENT
int 46 ticks
//  21 ticks
>>> %Run -c $EDITOR_CONTENT
int 45 ticks
//  20 ticks

「int()」と「//」との切り捨て処理の処理時間に差があるようだ。

各種ケース

コードAとコードC(アドバイス改良版)の比較(num=100(分割数))

freq(設定値(Hz)) 100 50 25 10 5
コードA実測値(Hz) 62.9 31.9 22.5 9.5 4.9
コードC計測値(Hz) 108.9 68.2 38.9 18.1 9.0

コードAとコードC(アドバイス改良版)の比較(freq=100Hz)

num(分割数) 100 50 25
コードA実測値(Hz) 62.9 77.7 87.8
コードC計測値(Hz) 108.9 141.6 166.3

コードC:num=100(分割数)

freq(設定値(Hz)) 25 50 75 100 150 200
計測値(Hz) 38.9 68.2 97.4 107.2 146.1 136.4

設定値200Hzの実測値不明(何度やってもこの周辺の値だった)。

コードC:num=200(分割数)

freq(設定値(Hz)) 25 50 100
計測値(Hz) 36.2 52.3 68.4

コードC:num=400(分割数)

freq(設定値(Hz)) 25 50
計測値(Hz) 28.2 33.78

コメント

素人+αには、よくわからないのが本音。ゴメンナサイ。なぜか、100us程度のSleepがあるケースでは改善があるように見える。

おまけ

ついでにDA処理の時間も計測。

import time
from machine import DAC, Pin

dac = DAC(Pin(11))
start = time.ticks_us()
dac.write(2048)
end = time.ticks_us()
print(str(end-start) + " ticks")

>>> %Run -c $EDITOR_CONTENT
10062 ticks
>>> %Run -c $EDITOR_CONTENT
21 ticks
>>> %Run -c $EDITOR_CONTENT
21 ticks
>>> %Run -c $EDITOR_CONTENT
21 ticks
>>> 

1回目だけはものすごくかかる。その後は一定。

とりあえず、今回はEOF。

0
0
0

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
0
0