製作モジュール一覧

2018年9月18日火曜日

Nucleo DCO 作戦検討 その3

ふたたび作戦を検討しました。


ブロック図(案)


テストプログラム(mbed-cli)
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/Nucleo_DCO_Test16

ロータリーエンコーダー


波形切り替えと周波数レンジ切り替えは、操作性がよくなるのでプッシュスイッチからロータリーエンコーダーに変更しました。(現状はOSC 1の2個だけ)

OLED表示とADC読み取り


OLEDはSSD1306(I2C)の128x64のものが届いたので交換しました。

OLED表示とADC読み取りはメイン・ループ内で行っています。

OLEDの表示は非常に時間がかかり、ADCの読み取りのレスポンスが悪くなるので、OLEDの表示をオフにするスイッチを設けました。

OLEDの表示中は4.6fps程度でPOTを回すと出音がブチブチですが、OFFにするとなめらかに変化します。

ADCの読み取りは移動平均で補間しました。補間するタイミングは波形生成割り込み中に行いました。結果、周波数からDDSのチューニングワードを毎回計算することになり、割り込みごとの処理時間が大幅に増えました。


ch2:CheckPin1(D4)

※サンプリングレートが100kHzだと処理が間に合わないので、50kHzに下げて計測。

補間処理を入れる前は割り込み時の処理時間は2マイクロ秒程度でしたが(参考「Nucleo DCO 内蔵ADCで入力系のテスト」)5マイクロ秒にまで増えてしまいまいした。結構な量の浮動小数点数演算をしていますが、F767ZIのFPUの能力のおかげでなんとかなっています。

ここまでFPUが強力だと、DDSではなく毎回波形を計算しても間に合うんじゃないかとも。

サンプリングレート62.5kHz(サンプリング周期:16マイクロ秒)までは動作します。

前回やった、浮動小数点数演算の速度を比較の結果などから、もう少しプログラムを改良できるかもしれません。

メモ:


u8g2-mbedのI2Cのクロックが50us程度になっている(I2CのStandard Modeは100kHz)。→手を加えてHW I2CやSPIで接続できるようにする?

OLED表示を別スレッドにして、プライオリティを下げればADC読み取りが優先されてOLED表示をオフにしなくても済む?

Callbackクラスを使うようにする?

2018年9月16日日曜日

Nucleo F767ZIでmbed 2とmbed OS 5の浮動小数点数演算の速度を比較

Nucleo F767ZIでオンラインコンパイラのmbed 2と、mbed-cliのmbed OS 5の浮動小数点数演算の処理時間を測定しました。

テストプログラム
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/FloatingPoint_Test01

測定結果

青とオレンジがfloat型の演算結果で、グレーと黄色がdouble型の演算結果です。

add, sub, mul, divはそれぞれ加算、減算、乗算、除算で圧倒的にfloat型が高速です。

ところが、なぜだがか三角関数や指数関数のsin, cos, exp, logは、float型とdouble型の差があまりありません。

DDSのチューニングワードを計算する
// calc tuning word
    t.reset();
    t.start();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = pow(2.0, 32) * (double)i / 100000.0;
    }
    t.stop();
    elapse = t.read_us();
    pc.printf("tword\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);
という演算では、むしろmbed OS 5のdouble型(グラフではtwordのグレイ)が最速となっています。「pow(2.0, 32)」という項は定数なので、この場合最適化されているのかもしれません。

Nucleo F767ZIをmbedで使った場合に限りますが、浮動小数点数演算の四則演算はfloat型でやったほうが速く、三角関数や指数関数(特にDDSがらみの演算)はdouble型でやってもそれほど遅くないと言えると思います。

測定データ

op OS 5 float Mbed 2 float OS 5 double Mbed 2 double
add 0.03708 0.02549 2.23522 1.64085
sub 0.07417 0.04866 2.29228 1.684
mul 0.11125 0.07416 2.36179 1.7396
div 0.21784 0.16682 2.54717 1.90871
sin 0.55664 0.37082 0.88683 0.93309
cos 0.59404 0.35549 0.95088 1.11853
exp 0.76539 0.53734 1.16889 1.04258
log 0.82766 0.48837 1.2759 1.36975
sqrt 1.31143 0.22935 3.23866 0.37065
pow32 2.28002 1.59155 0.6069 3.92082
tword 2.1812 1.60074 0.21782 3.48061

<追記:2018.09.16>

mbed-cliのOS 5とオンラインコンパイラのmbed 2で分けてグラフ化しました。

Mbed OS 5

Mbed 2

</追記>

2018年9月14日金曜日

Nucleo DCO 作戦検討 その2



パラメーター

2  6  956.50    0.000   30039   0.200:  4  3  119.26    -0.005  28422   0.200:  0  4  236.41    -0.023  47531   0.200:  0.257   1
2  6  953.49    0.000   30087   0.200:  4  3  118.65    -0.009  28342   0.200:  0  4  234.68    -0.031  47403   0.200:  0.257   1
2  6  955.64    0.000   30007   0.200:  4  3  119.09    -0.006  28310   0.200:  0  4  235.73    -0.027  47403   0.267:  0.257   1
2  6  954.14    0.000   30151   0.200:  4  3  118.79    -0.008  28486   0.200:  0  4  235.71    -0.024  47483   0.200:  0.257   1
2  6  956.07    0.000   30039   0.200:  4  3  119.17    -0.006  28438   0.200:  0  4  238.76    -0.002  47323   0.200:  0.257   1
2  6  955.64    0.000   30071   0.200:  4  3  118.97    -0.008  28406   0.200:  0  4  235.61    -0.028  47339   0.200:  0.258   1

ハードウェアでやったこと


外部ADCではなくて、NucleoF767ZIの内蔵ADCを使うためにPOTパネルを作って操作しやすくしました。

ソフトウェアでやったこと


ファームウェア(mbed-cli)
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/Nucleo_DCO_Test12

周波数レンジ


プッシュスイッチで、オシレーターごとに1オクターブ音程をずらせるようにしました。

デチューン


OSC2とOSC3は、MasterとなるOSC1に対して±1オクターブ可変するようにしました。±1オクターブ可変するために、疑似指数カーブで対応しています。


マスター・レベル


波形がクリップした場合も、デジタルならではの過激な歪が出るので、歪ませる/歪ませないを選択できるようにマスター・レベルを調節できるようにしました。


ピン割り込みのチャタリング対策をTickerからTimeoutに変更

mbedではTimeoutクラスは内部でTickerクラスのオブジェクトを持っているようなので、Timeoutにした方がいいのか悪いのかわかりません。

OLEDの表示項目


I2C接続の128x32のSSD1306 OLEDで実験していますが、表示域が少なくて一覧性が確保できません。

AliExpressで発注した128x64のOLEDは関空水没のせいか届きません。同じ日に発注したものは届いたのですが、タイミングが悪かったのか。

ここで一句

「中華製、忘れた頃に、届いてる」

ToDo:


POTの読み取り値がふらつくので、補間してみる。

波形切り替え、周波数レンジ切り替えは、プッシュスイッチでも役目は果たせますが、ロータリーエンコーダならもっと操作性が良くなるのではないかと妄想。