製作モジュール一覧

2018年9月11日火曜日

Nucleo DCO 作戦検討

ファームウェアのめどが立ったので作戦を検討しました。


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

ブロック図(案)

ピン接続表(案)

POT入力


3オシレーターですが、それぞれのオシレーターで周波数を設定するのではなく、OSC1で基本の周波数を1つ設定(ブロック図のMaster Freq POT)し他のオシレーターはデチューン(ブロック図のDTN POT)として設定しようと思います。

3オシレーターの波形をプログラムでMIXしてオーバーフロー/アンダーフローしないように境界を設けていて、オーバーフローした場合、かなりきつい歪が発生するのでマスターレベル(図のMaster Level POT)で内部的なレベルを調整できるようにします。

当初はPOTで位相を調整するように考えていましたが、音出ししてみるとあまり効果がないので廃止しました。デチューンの仕方によってうなりが発生します。

3OSCともノコギリ波でおおよそ1オクターブずつずらした合成波形

これを7オシレーターぐらいに増やしてちょっとずつデチューンすればSuper SAWになります。

プッシュスイッチ入力


プッシュスイッチの読み取りはmbedのInterruptIn(割り込み)で処理しました。

NucleoでInterruptInを使う場合はピン名のアルファベットの部分がかぶっても大丈夫ですが、数字の部分がかぶると使えません。例えば、PA_0とPA_1の組み合わせはOKで、PA_0とPB_0の組み合わせはNGです。

そのためプッシュスイッチにつなぐZIOヘッダの「PE_10」を飛ばしています。

処理が煩雑なのでInterruptInのオブジェクトは配列にしたかったのですが、引数付きのCallbackの仕方がよくわからず、かっこ悪いですが1つずつ定義しました。

こうしたいが、
InterruptIn Button[] = {
InterruptIn(PB_11, PullUp),
InterruptIn(PB_10, PullUp),
<後略>
こうした
InterruptIn Button0(PB_11, PullUp);
InterruptIn Button1(PB_10, PullUp);
<後略>
以前、FunctionPointer.hで定義されている、int型の引数を1つとるコールバック関数型の「event_callback_t」を使いましたが、Mbed OS5では非推奨となっています。

参考「mbedのコールバック FunctionPointerを使うテスト

Mbed OS 5の「platform/FunctionPointer.h」には

MBED_DEPRECATED_SINCE("mbed-os-5.1",
                          "FunctionPointer has been replaced by Callback<void()>")

という記述がありCallbackクラスをつかうことが推奨されています。いずれ使ってみようと思います。

参考「https://os.mbed.com/docs/v5.8/reference/callback.html

チャタリング対策


チャタリングが発生したのでタイマー割り込みのTickerクラスで対策しました。ピン割り込みがかかったとき、タイマー割り込みを有効にしています。

※1回のみの割り込みなのでTimeoutクラスにすれば良かった?

処理時間の計測

テストプログラム(mbed-cli)

Nucleo F446RE
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/InterruptIn_Test02

Nucleo F767ZI
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/InterruptIn_Test03

Board function ピン割り込み(us) チャタリング対策(us)
F446RE attach() 10.9 3.1
F767ZI attach() 5.5 2.1
F767ZI attach_us() 4.9 2.1

※attach()の引数はflot型、attach_us()の引数は整数型

ピン割り込みの処理時間はF767ZIのattach_us()で4.9usと、波形生成の割り込み周期の10usと比べて十分短いとは言えませんが、Tickerの方が優先順位が高いようです。

Nucleoの割り込みベクタ表は「RM0410 Reference manual」の「10  Nested vectored interrupt controller (NVIC)」に載っています。


赤枠で囲みましたが、TickerがSysTick、InterruptInがEXTxを使っているかどうかはわかりません。mbed OS 5もまだ良く分かっていないのに、1896ページもあるReference Manualを読み解くのはとてもじゃないけど無理な話です。

割り込みの優先順位は、NVIC_SetPriority()で設定できるようです。

参考「割込み 256

出力波形


Aruduino LFOと同じような方法で出力波形を増やしました。メモリが潤沢なので12bit / 64k要素のWave Tableを使用しました。

random()関数の処理時間を計測すると0.113 usで、ノイズも無事出力できました。

random()関数の処理時間を計測するプログラム(mbed-cli)
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/random_Test01

ToDo


周波数設定(Range切り替え含む)

電源電圧監視

OLED表示項目の整理

PA_7(ADC)の読み取り値がおかしい?

2018年9月6日木曜日

Nucleo DCO 内蔵ADCで入力系のテスト

POTx16 PizzaBoxのMCP3008(SPI ADC)でPOTの値を読み取れないかと試してみましたが、通信速度が遅いせいかメインループがうまく回らなくなりました。

うまく動かないテストプログラム(mbed-cli)
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/Nucleo_DCO_Test06

MCP3008によるPOT値の読み取り


単体のテストプログラムを書いてMCP3008から読み取る時間を計測しました。

オンラインからライブラリ(mcp3008)を追加

> mbed add https://os.mbed.com/users/ryood/code/mcp3008/

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



ch1:D4 ch2:D5

ch1は16ch分、ch2は1ch分でH/Lしています。1ch分で48.3usかかっていて100kHzのサンプリング周期の10usより長くなっています。

はっきりとは言えませんが、Nucleo_DCO_Test06がうまく動作しないのは、MCP3008とのSPI通信中に何かが競合して処理が戻ってこない可能性が高いためだと思います。

内蔵ADCによるPOT値の読み取り


NucleoF767ZIは12bit ADCが24chあり、ZIOヘッダにも18ch分引き出されています。そのうち2chはDACと共用されています。

内蔵ADCのテストプログラム(mbed-cli)
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/InternalADC_Test01


ch1:D4

内蔵ADCの読み取りは7.88usです。これもかなり遅いですが100kHzのサンプリング周期の10usよりは短いです。内蔵ADCの読み取り中に割り込み(Ticker)が優先されればOKです。

内蔵ADCでNucleo DCOのPOT入力を読み取り


前回の3オシレーターMIXするテストプログラムに結合しました。


u8g2-mbed + DDS(3OSC) + 内蔵ADCの結合テストプログラム(mbed-cli)
https://github.com/ryood/Nucleo_DCO/tree/master/mbed/Nucleo_DCO_Test07 (69e60db6bbf20065a08d25b653dfb63fc732724e)

処理時間の計測


メインループのタイミング

周波数は7.752Hzになっています。OLEDに表示させているFPSも7.8fps程度になっています。

波形出力の割り込み処理のタイミング



サンプリングレート100kHz程度で(ジッターあり)、処理時間は2usです。まだ余裕がありそうですが、サンプリングレートを倍の200kHzにするとメインループに処理が戻らず、割り込みも処理落ちしてしまいました。


波形出力


POTで周波数がだいたい200Hz、100Hz、50Hzになるようにして波形出力しました。

UART_TRACEを有効にして読み取ったパラメーターを表示


OSC1:drate      OSC1:phase      OSC1:PulseWidth OSC1:amplitude  OSC2:drate      OSC2:phase      OSC2:PulseWidth OSC2:amplitude  OSC3:drate      OSC3:phase      OSC3:PulseWidth OSC3:amplitude
201.648364      0.012698        0.012943        0.159463:       98.107455       0.012698        0.011233        0.155800:       50.439564       0.012454        0.010745        0.157265:
201.453004      0.012943        0.012943        0.160684:       97.912095       0.009524        0.010745        0.157265:       50.439564       0.013919        0.012698        0.159707:
201.501844      0.012210        0.008547        0.160928:       97.912095       0.012210        0.010745        0.156532:       50.390724       0.012698        0.012210        0.156288:
201.697204      0.012943        0.012454        0.161416:       97.912095       0.010745        0.010989        0.156777:       50.341884       0.012210        0.012454        0.156777:
201.892564      0.011722        0.012454        0.159707:       97.814415       0.008059        0.010989        0.155556:       50.293044       0.011477        0.011966        0.156288:

読み取り値はfloat型で、結構ふらついています。

出力波形はUART_TRACE、CHECK_PINを無効にして計測しました。

3オシレーター合成(OSC1 + OSC2 + OSC3)

他のチャンネルのLevel POTを最小にして1chだけのオシレーターの波形出力を計測しました。

OSC1のみ

OSC2のみ

OSC3のみ

特にOSC3の波形が歪んでいますが、POTの読み取り値がふらついているためだと思います。ADC読み取りを抑止して、プログラム上でパラメーターを決めて(OSC1、OSC2のamplitude=0.0、OSC3のamplitude=0.3にした)出力すると以下のように比較的きれいです。


メモ:


波形を増やす。波形切り替え。

Range切り替え。

ADCの読み取りは内蔵でもかなり時間がかかる。

Freq POTを回すと周波数の変化がトビトビ。Phase POT、Level POTを回すとブチブチ。→補完する?

2018年9月1日土曜日

Nucleo DCO 3オシレーターをMIXするテスト

3波形を合成(加算)して出力するテストをしました。

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

パラメータ OSC1 OSC2 OSC3
波形 サイン波 サイン波 サイン波
周波数 1kHz 2kHz 1kHz
振幅 0.5 0.5 0.0
位相 0.0 0.0 / 0.5 0.0

OSC2は、位相が0の場合と0.5(π rad)の場合の2通りです。

OSC3は、加算していますが振幅0なので、OSC1とOSC2の2波形の合成波形が出力されます。

OSC1 + OSC2(位相:0.0)

ch1:Dac1(PA_4)

OSC1 + OSC2(位相:0.5)

ch1:Dac1(PA_4)

同様の波形合成をシミュレーションしました。

シミュレーション回路図

過渡解析

緑の線が位相0°、青の線が位相180°(π rad)です。

波形出力の割り込み処理時間

ch2:CheckPin1(D4)

割り込み処理に要した時間(PW)は1.7マイクロ秒です。ジッターがあるため、線が多重になっています。


OLEDに表示させている書き換えのフレームレートは9.4fps程度です。

レスポンスがどうなるかわかりませんが、メインループ内で入力処理を行う余裕はありそうです。