MicroPythonを使ってみる（その５）：DAコンバーター（続き）

# ソフトウェア処理の改善
[前回（MicroPythonを使ってみる（その４）＆エレキ素人が何か考える（その７）：DAコンバーター）](https://qiita.com/infinite1oop/items/180248ddd0a9cbf094ba?utm_campaign=email&utm_content=link&utm_medium=email&utm_source=public_comment#comment-14c2f479b6604add7526)にて、ソフトウェア処理の限界をほのめかたしたところ、有識者からアドバイスされたコードがあり、その結果をここに記す。なお、ハードウェアとしては、継続してWio Terminalを用いている。

## ソースコード
### オリジナル（コードＡ）
```python
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)))
```

### アドバイスされたコード（コードＢ）
上記オリジナルコードの「while 1:」以下を下記コードで置き換える。

```python
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)
```
システム稼働時間（マイクロ秒）による調整である。

### アドバイスされたコードの変形（コードＣ）
後述するが、切り捨て処理に差があったので、こちらも記載。
```python
    us = int(1000000/(num*freq)) - time.ticks_diff(currentTicks, lastTicks)
```

## 結果
### 設定値：freq=100Hz,num=100(分割数)
改善の効果が見られたと思う（簡易オシロスコープによる波形および典型的な周波数）。
#### コードＢ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/055213c1-a026-a2bb-6adf-bf0c713eefd2.png", width=65%>

#### コードＣ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e5690a2b-087a-8a2a-530c-1d41d1553ae9.png", width=65%>

#### ここでのまとめ＋α
|コード|Ａ|Ｂ|Ｃ|
|--|--|--|--|
|計測値(Hz)|62.9|113.4|108.9|

コードＢとコードＣとで違いがあり（切り捨て処理）、下記コードで調査。
```python
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()」と「//」との切り捨て処理の処理時間に差があるようだ。

### 各種ケース
#### コードＡとコードＣ（アドバイス改良版）の比較（num=100(分割数)）
|freq(設定値(Hz))|100|50|25|10|5|
|--|--|--|--|--|--|
|コードＡ実測値(Hz)|62.9|31.9|22.5|9.5|4.9|
|コードＣ計測値(Hz)|108.9|68.2|38.9|18.1|9.0|

#### コードＡとコードＣ（アドバイス改良版）の比較（freq=100Hz）
|num(分割数)|100|50|25|
|--|--|--|--|
|コードＡ実測値(Hz)|62.9|77.7|87.8|
|コードＣ計測値(Hz)|108.9|141.6|166.3|

#### コードＣ：num=100(分割数)
|freq(設定値(Hz))|25|50|75|100|150|200|
|--|--|--|--|--|--|--|
|計測値(Hz)|38.9|68.2|97.4|107.2|146.1|136.4|

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

#### コードＣ：num=200(分割数)
|freq(設定値(Hz))|25|50|100|
|--|--|--|--|
|計測値(Hz)|36.2|52.3|68.4|

#### コードＣ：num=400(分割数)
|freq(設定値(Hz))|25|50|
|--|--|--|
|計測値(Hz)|28.2|33.78|

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

### おまけ
ついでにDA処理の時間も計測。
```python
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。