」で考えた通りAVRからのPWM出力をレベル調整(減衰)物理的なスイッチで、GNDレベルを矩形波の中点に持ってくるという方針で実験した。VCCを分圧するだけの回路だ。AVRからのPWM出力も一旦受けてそのまま出力するふうにしたが、これは別にこの基板を通さなくてもいいのか?あとでまた考えてみよう。変な図になってるがTLE2426のIN/OUTの向きが、OUT/COMMON/INなので逆向きという意味。Fritzingで作図しておいてブレッドボードで組むときすっかり忘れていてTLE2426を逆向きに刺してテスタで計ったら出力電圧が微妙におかしくなった。電流が流れまくったのかな?触ったら熱くなっていた。電源は矩形波だけのファンクションジェネレーターの5VからとったCをいろいろつけたが1000pFから47uFぐらいまで差し替えてみたが少しずつ変わる特に変わったところ1kΩの負荷で測定してCなしC3にだけ10uFのケミコンパスコンを入れると波形は直角的になる。ノイズは増えるみたいだ。TLE2426の入力側のC1は入れても入れなくてもあんまり差はなかった。ウィーンブリッジ正弦波発振回路の実験リズムマシンのコーディング(と仕様ぎめ)が途中なのでアナログ回路の実験。参考にしてウィーンブリッジ正弦波発振回路を組んでみた。LTSpaiceのシミュレーションLTSpiceでシミュレーションしてみようと思ったが、うまく発振してくれなかった。発振回路の場合はSpiceでは初期値をなんかゴニョゴニョしないとダメらしいんだが、よくわからないのでブレッドボードで実験することにした。振幅3.280V、周波数103.9Hzで発振してくれた(^q^/理論値では1kHzあたりになるはずだがまあいいや。拡大デジタル回路と違って拡大してもなめらかですなあ。周波数をちゃんと50Hzとかあたりにして振幅変調させればTR-808っぽいkickになるかな?リズムマシンならオシレーターもVCOである必要はないのです。<追記:2015.10.29>LTSpiceのOPAMPをUniversalOpamp2ではなくて特定の品種のものを指定したら発振した。発振用の初期設定は.tranにStartupをつければいいようだ。→電圧・電流源を開始から20usかけて電圧を上げる指定また、ブレッドボードでの実験でCを0.01uFではなく、0.1uFを使っていた。100Hz前後の発振周波数でOKみたい。小ネタ実験2015年10月25日日曜日ブログのレイアウト模索します去年書いた記事とか探しづらくなってきたので、ブログのレイアウトをいじります。結合(メモ)動作はするようだが、8kHzまでサンプリング周波数を落とさないとI2Cに制御が回らない。Creatorのプロジェクトhttps://github.com/ryood/RhythmMachine/tree/master_test/Master_Test/PSoC/Sequencer_Master/Sequencer_Master_AQM1602_MCP4922_DDS.cydsnリズムマシン関連のGitリポジトリを整理したhttps://github.com/ryood/RhythmMachine/tree/master_testそろそろ仕様を固めないとだめか。Miniは3.3Vで動作するので3.3V系の回路の実験をするのに便利そうなので仕入れてみた。普通のArduinoボードと違って書き込み用にUSB-Serial変換アダプタが必要だ。USBシリアル変換モジュールキットがあったので使ってみた。USBバスからVCCに5V供給にした。LEDは別につけなくてもいいけど、UART通信の状態が見れるのでつけた方が安心かな?sinkなのでFT232RL側はLEDのカソードをつないでRを介してVCCにつなぐ。Miniに割り当てられたポート>に変更した。ExampleのBlinkは動作した(^q^/書き込み時のUART通信を見ると信号レベルも3.3Vになっている。J1の設定で変更されるのかな?(←未確認)メモ:秋月のFT232RLのキット(たぶん1年以上前に買った)にはんだ不良があって最初動かなくてハマってしまった。ピンヘッダと基板のはんだ付けが導通していなかった。はんだ付けはやっぱ電子工作の基本だ。Ver.2仕事でアジャイル開発というのはなかなか難しいが、ひとりアジャイルは楽しい。Ver.2I2Cバスにデバイスを複数載せるのはなにかとしんどそうだ。理屈の上ではできそうでもしんどそうだと思ったらやめたほうがいい。LCD」は同一基板に載せるつもりだ。I2Cは2個使えるので、LCD制御用とシーケンサー基板制御用の2系統のI2Cを使える。DAC出力のSPIはUDBのコンポーネントを使えばリソースは足りそう。4でリズムマシンの音出しテストサンプリング周波数48kHzはムリだった。32kHzでも処理が追いつかなくて、16kHzでギリギリセーフだ。コードを最適化していけばもうちょっと頑張れると思うが、I2Cで入出力処理したり、トラックを増やしたりしたいので16kHzでやっていくことにする。SPI通信に時間が食われているのかも?と思ってPSoC4の内蔵DACでもやってみたが、大して変わらなかった。Creatorのプロジェクトhttps://github.com/ryood/RhythmMachine/tree/master/PSoC/PSoC_Fixedpoint_DDS_RhythmMachine/PSoC_Fixedpoint_DDS_ThythmMachine_MCP4922.cydsnDACにSPI送信する前後でPin_LDACをH/Lしているので、DACにデータを送信した場合としない場合を比較してみた。48kHz)DACへ送信すると処理がサンプリング間隔に間にあっていない。Creatorのプロジェクトhttps://github.com/ryood/RhythmMachine/tree/master/PSoC/PSoC_Fixedpoint_DDS_RhythmMachine/PSoC_Fixedpoint_DDS_RhythmMachine_IDAC.cydsnDACに値を設定する前後で「Pin_IDAC8_Check」をH/Lした。ch2:Pin_IDAC8_Checkありゃ?なんか波形がおかしいかな?気が向いたらもう一回チェックしてみよう。ch2:Pin_Sampling_OVギリギリ間に合ってる感じだ。12kHz8kHz8kHzまで下げるとかなり余裕がある。音出しMCP4922はPin14の出力をそのまま、PSoCのIDACは1kΩのRでI-V変換してオーディオインタフェースに入力して、PC上のGoldWave(波形編集ソフト)で録音した。DACの出力にはLPFを入れていない。8kHzではさすがに変な音になるが、逆にエフェクトかけたみたいで面白いかもしれない。MCP4922の16MHzのキックの裏拍が歪っぽいが、スネアとかぶっていてオーバーした値に強制的にリミットをかけているのでどうとも言えない。(波形は頭打ちの矩形波的になっている)メモ:ProperaheadのRebirth338(TB-303、TR-808、TR-909のソフト音源)で遊んでいたのがPentiumの200MHzとかそのあたりのCPUだったような気がするので、いくらARMとはいえFPUやMMX(だっけか?)の載っていない48MHzのCPUで音を作って合成するのはそれなりに真剣にやらないといけないようだ。5LPならもう少し余裕がありそうだがなんか悔しいのでPSoC4でできる範囲で粘ろうと思う。サンプリング周波数を実行時に設定できるようにする?シーケンサー基板とPSoC4でほんとに単にシーケンサーとして使い、アナログ発振回路やノイズ生成回路の振幅を制御することも妄想中。MasterコンポーネントはSCBコンポーネントより高速に動作させることができた。ブレッドボード図SCBモードと比べてMOSI(オレンジの線)だけがピンの位置が異なっている。Masterコンポーネントのclockに入力したクロック周波数の1/2がSPIのクロックになる。して、ノコギリ波を出力した。564.2HzMCP4922はMax:20MHzなので仕様外だが、動作した。349.4Hzタイミング制御なしで連続して出力しているので周波数が高い方が処理速度が速い。3.7usch2はSPIのSCLKだが、間欠的なので「(2)F:」は正確な周波数が表示されていないと思う。SPIのデータ送信の前後でLDAC(ラッチ)をH/Lしているのでこの間隔がSPI通信の実行時間になる。Masterコンポーネントの24MHzはMCP4922の方の仕様外なので、12MHzを使うとしても、SCBコンポーネントの8MHzより速い。17.58usなので、このスキマ時間で波形生成の演算+αをやらないといけないようだ。だいたい6.7usなのでなんとかいけるかな?メモ:足りなかたらサンプリング周波数を32,000Hzに落とす。仕様を無視してSPIのSCLKを24MHzでやる。MasterコンポーネントはMOSI、MISOをまとめて3Wireでやるモードもあるので配線の具合では試してみる。MasterのExampleプロジェクトはやれなかった。WaveSpectraで周波数特性を測定したいのだが、ループバックした時の特性が怪しい。使い方は「WaveGeneとWaveSpectraで周波数特性の測定」の通りにしたんだが、間違ってるのだろうか?WaveGeneの設定WaveSpectraの設定&解析結果めちゃくちゃハイ落ちしている。「オーディオインターフェイスに入れるLimiterの構想」でやった時よりも劣化してる気がする。SDS7102)で手作業で周波数ごとの出力レベルを見てみた。WaveSpectraの測定でもあまりかわらない。US-144MKIIはいつ買ったか忘れたが、出力段に電解コンデンサが入っていると仮定するとこれが劣化しているような気がする。保証期間も過ぎてることだしガワを開けて観察してみようかな?周波数特性を見る手段ちゃんとしたサイン波を出せるファンクションジェネレーターを作れば、オシロと組み合わせてひとつひとつ調べればある程度周波数特性を見れる気がします。Discoveryも欲しいけどここはじっとがまん今日はがんばってハンダ付けしていなかった部品のハンダ付けをした。右下のD020のDIP変換基板に載せているのがPCM5102というDACで384kHz/32bitのスペックらしい。PSOC増刊付録のPSoC5LPの基板も実験に使えるようにピンソケットをハンダ付けしてみた。Kitに移植して処理時間を計測してみた。Creatorのトップデザイン時間の計測には16bitタイマー(TCPWMコンポーネント)を使って処理の開始時と終了時にCounter値を取得して調べた。取得値はUARTを使ってPCで表示。SPI通信自体は行っていない。Creatorのプロジェクトhttps://github.com/ryood/RhythmMachine/tree/master/PSoC/PSoC_Fixedpoint_DDS_RhythmMachine48000回ループさせて、サンプリング周波数48kHzでちょうど1秒の間にどれだけ実行時間を消費するか見てみた。42.6%表は上から順に追加変更していったものだ。比率(初期プログラムに対する短縮率)を見ると、「シーケンスを見て処理を省略」するとかなり速くなっている。シーケンスが0(音符で言う休符)のとき、処理を省略するというもので、かなり早くなるが、音数が増えると処理落ちする可能性がある。「hihatの波形生成をDDSに」も結構効いている。Hihatの波形をrand()関数で作っているのをテーブル参照にした。rand関数ですらコストが高いらしい。inline指定やコンパイルオプションの変更は多少効く感じだ。SPI通信との兼ね合い波形生成とSPI通信と順番に処理するとかなりカツカツっぽい。DDSで波形生成」で調べたSPI通信のタイミングざっくり見てサンプリング区間の50%以下で波形生成の処理を終わらせないとだめっぽい?入出力系のI2C通信の時間もあるので。Block)以外にもUDB(内蔵のCPLDみたいなもの)を使ったコンポーネントもあるようなので、これもテストしてみたいと思います。C++でリズムマシンのコードを書いた。12bitのデータを数値出力してGoldwaveで再生したものをYoutubeにアップした。2013のプロジェクトhttps://github.com/ryood/DDS_RhythmMachine_Test/tree/fixedpoint/DDS_RhythmMachine_Testソースコードhttps://github.com/ryood/DDS_RhythmMachine_Test/blob/fixedpoint/DDS_RhythmMachine_Test/DDS_RhythmMachine_Test.cpp浮動小数点演算が出てこないようにしたが、波形の出力周波数の設定値だけはdouble型のまま。32bit固定小数点型にすると2^32と掛け算するときにオーバーフローするので保留。→リズムマシンなので音程の精度は必要ないので問題があれば整数型にするつもりだ。toneAmountで位相変調して周波数の微調整をすればいいかな?スネアの音にスナッピーを入れたり、クラップやその他も作りたいけど、一旦PSoCに落とし込んで様子を見たいと思います。Studioで作ったリズム・マシンのコード(浮動小数点演算)をそのまま固定小数点演算にしようと思ったが、固定小数点演算を使うと問題が発生した。固定小数点型というのは、32bitなら32bitのうち上位数桁を整数部、残りの下位を小数部として扱う方式だ。32bitでQ8.24だと上位8bitを整数部として扱い、下位24bitを小数部として扱う。+127までしか扱えない。浮動小数点のつもりで、でかい整数を固定小数点型にキャストするととんでもないことになるし、実際そうなった。整数演算で線形補完するアルゴリズムもどっかにあった気がするが、調べたりするのがめんどくさいのでDecay波形もテーブル参照でやることにした。テーブル参照ならテーブルを作ってやれば線形補完だけではなく、疑似的にいろんな波形を使えるかも?という目論見もある。ROMは意外とサイズが制限されているので、128個のテーブルにした。演算は32bitの固定小数点でやるので固定小数点の中の値(32bit整数)をそのままテーブルにした。波形テーブルhttps://github.com/ryood/DDS_RhythmMachine_Test/blob/fixedpoint/DDS_Decay_Test/ModTableFp32.hプログラム・コード浮動小数点演算で結果を見ながら整数演算にに変換していった。+1.0の範囲で波形を作れたので、これと元波形を乗算すれば振幅変調できるかな?バグはかなりありそうだが。Studioで固定小数点演算のテストをしてみた。」の記事を参考にした。Amazonではまた転売価格になってますが、マルツにはまだ在庫ありそうです。PSoCでは関数呼び出しのコストが高そうなので、マクロ関数で定義してみた。Q8.24の固定小数点と浮動小数点で、-1.0~1.0の範囲で乱数出力して誤差を出力した。除算ありE列、F列はExcelの関数で誤差の最大値と最小値を抽出した。ごつい誤差がでているが、これは除算の時に除数が小さい時に発生する。除算なしプログラムを修正して除算を省いてみると誤差はなくなった。出力桁数が少ないのでもっと細かい誤差はあると思うが、DDSで使うならこれぐらいの精度で十分だと思う。外付けDACでサイン波生成」でもMCP4922でサイン波を出力してみたが、もう少し詳しくテストしてみた。がんばって2ch出力させてみた。1Hzと0.5Hzのサイン波を生成して、LEDを点滅させている。Clockは48MHzに設定。TopDesignTCPWM_P4のConfigureダイアログTC_Sampling_TimerのPeriodを249に設定した。0..249でカウントアップしてオーバーフローしたらISR_Sampling_Timerの割り込みがかかる。48kHz今まで(ぴゅんぴゅん3号など)250に設定していたので、間違っていたかも。割り込みと同時にOVからPin_Sampling_ClockにH/Lの信号が出力される。→オシロをあてればサンプリング周波数が測定できる。MCP4922のchannelAから1kHz、channelBから2kHzのサイン波を出力するプログラムだ。ch2:DACのchannelBの出力(1)F:47.94kHz(2)F:998.0HzchannelBは2kHzのはずなのでおかしい。ch2:LDAC(DACのラッチ)よく見てみるとサンプリング区間の2回に1回しかラッチ信号が出力されていない。(ラッチ信号は2ch分あるので連続で2回出力される)SPIのクロックを上げるSPIMのConfigureダイアログSPIクロックを4MHzから8MHzにあげてみた。bitsを16に変更(デフォルトは8)。これで16bitまとめて出力できる。main.cもこれに合わせて変更した。ch2:LDACサンプリング区間ごとにラッチ信号が2回ずつ出力されている。ch2:DACのchannelB出力周波数も無事2kHzに(^q^/)メモ:MCP4922の2ch同時出力はできたが、SPIの信号出力で相当時間が食われている。SPIの出力が終わるまで非同期で別の処理ができればいいが、波形生成の演算はSPI出力の前に終わらせる必要があるし、2ch出力は努力目標ということにしようかな。リズムマシンはDecayやLevel、トラックの合成など結構計算量がありそうだし、無理そうならサンプリング周波数を32kHzに落とすとか。