オリジナル16ビットCPUコアMoscoviumにロジックアナライザユニットLOGA8CHを接続して、24MHzサンプリング8チャンネルのロジックアナライザを作ったことがありました。
「#16-4 24MHz 8chロジックアナライザの制作」
PC側のインターフェイスには、Arduino UNO等でも使って来たLogiscopeというスクリプトを使っています。
Moscoviumでも、このLogiscopeを使ったのですが、Moscovium側のプログラムはアセンブラでの開発となるため、Logiscopeの全機能をサポートしているわけではなくて、それどころか、ロジックアナライザ用のI/Fにしか、対応していませんでした。
今回は、Moscovium版Logiscopeの機能を拡張すること、とりわけ、AD変換器ADC124ユニットを活用したデジタルオシロスコープの機能を追加してみたいと思います。
今回拡張するコマンドの仕様を以下に示します。
【vcdo】コマンドは、Moscovium版Logiscope専用の機能なので、詳しく説明します。その他のコマンドは、Arduino UNO等で使用していたLogiscopeと同等機能の追加です。
拡張した【vcdo】コマンドを実行すると、Moscoviumマイコン側でAD変換器を使ってアナログ信号を取り込んだ後、そのデータをPCに送ってきます。受け取ったPC側のスクリプト(logiscope.olv)は、受信データからVCDファイルを生成して、スクリプトと同じディレクトリにlogiscope_a.vcdファイルを生成します。
生成したVCDファイルは、Verilogシミュレータ(iverilog等)が出力するVCDファイルと互換なので、VCDファイルを表示可能なGTKWave等のツールを使って閲覧することができます。下図は、GTKWaveを使って表示したデジタルオシロスコープの取り込みデータサンプルです。
2チャンネルのアナログ信号を取り込んだ例となっています。測定したアナログ値は、mV単位の電圧値に換算された16ビットデジタル値となっています。よって、測定した電圧値が2.14Vだった場合、2,140と言う値を読み取ることができます。カーソルを合わせると、カーソル位置のアナログ値をmV単位で直読みできるので便利です。
GTKWaveで信号名を「右クリック ⇒ Data Format ⇒ Analog ⇒ Step」、続いて、「右クリック ⇒ Data Format ⇒ Decimal」とすると、上図の様なアナログ波形が表示されます。
信号名で、「右クリック ⇒ Insert Analog Height Extension」を選択すると、アナログ信号の高さを追加して、見やすくすることができます。上図の例だと、信号4本分の高さを追加して、表示しています。
参考に、上図のVCDファイルをリンクしておきます。
VCDファイルサンプル:logiscope_a.vcd
なお、波形表示ツールGTKWaveは、Windows版Verilogシミュレータiverilogをインストールすると一緒にインストールされているので、探してみてください。
以下にMoscovium版デジタルオシロスコープに対応したLogiscopeスクリプトと、Moscovium側で実行するプログラムをリンクします。
PC側Logiscopeスクリプト:logiscope.olv
Moscovium側プログラム:logiscope.asm
スクリプト(.olv)の実行には拙作Olive+をWindowsにインストールしてください。Moscovium側のプログラムは、アセンブルしてMoscoviumマイコンの命令ROMに書き込んでください。
今回、新規に追加するI/Oユニット(ハードウェア)はありません。
ただ、拡張したLogiscope用として、ロジックアナライザユニットLOGA8CHとAD変換器ユニットADC124を同時に搭載したマイコンが必要でした。また、Logiscopeの機能を拡張したことで、ROM容量も4Kバイトでは足りなくなってきたため、8Kバイトに拡張することにしました。
ついでに、AD変換器から読み出したデータをRAMにバッファリングする処理を高速に実行するため、スーパスケイラ版Moscovium-SSを選択しておきます。
型名MSOC115LS0808が、Logiscopeを実行するのに最適なマイコンとなります。
※他のMoscoviumマイコンでも、Logiscopeの一部機能を使うことは可能ですが、通常版Moscoviumを使う場合、【vcdo】コマンドの<smpl_us>パラメータで、(チャンネル数+1)[μs]では取りこぼしエラーが発生する可能性があります。その場合は、<smpl_us>≧(チャンネル数+2)[μs]等に設定して回避してください。
以下リンクより、オリジナル16ビットCPUコアのスーパスケイラ版Moscovium-SSを搭載したマイコンMSOC115LS0808のデザインをダウンロードできます。
FPGAボード(Sipeed Lichee Tang Primer)への書き込み手順はこちらを参照してください。
拡張した【vcdo】コマンドを使う応用例として、コンデンサの静電容量を測定してみたいと思います。
静電容量は本来、LCRメータで計測するみたいです。容量C(インピーダンス)は周波数の関数であって複素数で表現される為、通常は正弦波などの交流信号で計測するのだとか。
LCRメータも、高速な正弦波を出力する電源も手元に無いし、容量の概算値(普通に使う周波数での値)がわかれば良いとします。→PWM出力でCR回路を充放電する信号波形から容量値を簡易測定してみます。
以下、Mathematicaによる検算結果です。
検算するまでも無いほどの計算でしたけどね……。有る物は活用しておきたい。
Solve[ ]関数の第三パラメータに「Reals」を渡しておかないと、複素数の解が出力されてしまいました。「Reals」は、「実数の範囲で解け」という指示になります。
出力のConditionalExpression[A,B]関数については、「条件Bが成立している時に限り、式Aが有効」という意味です。後ほど言及しますが、「0V<<Vmin<<Vmax<<Vdd」の条件下で未知の静電容量Cを測定します。この条件下では、条件Bの論理ORで区切られた最終項(vmax<vdd && vmin<vmax)が成立するので、式Aは有効な解です。
以上を持って、検算結果OKです。
拡張したLogiscopeを使うと、PWM波形は【ana】コマンドで出力可能です。
尚、Logiscopeが出力するデフォルトのPWM周期は以下の通りです。
LogiscopeのPWM出力周期Tpwmは:
Tpwm=(timprd+1)/fcpu×timpsc[s]
デフォルトでは:
timprd=254 (16ビットタイマ周期レジスタ)
timpsc=192 (16ビットタイマ分周レジスタ)
fcpu=24MHz (動作周波数)
Tpwm≒2ms≒1/(490Hz)
もし、PWM周期を変更する必要に迫られた場合には、汎用16ビットタイマTIM162ユニットのI/Oレジスタ表を参考に、【wr2】コマンドなどを使って手動で設定を変更する(timpscレジスタを書き換える)ことができます。
静電容量Cを求める式に戻って、Vmin/Vmax値は、そもそも、AD変換器で測定したデジタル値から求めた値です。
AD変換結果をそれぞれAmin/Amaxとすると:
Vmin=Vdd×Amin/4,096
Vmax=Vdd×Amax/4,096
ここで、Amin,Amaxは、0〜4,095[LSB]の範囲を取る。
∵FPGAボードのAD変換器が12ビット解像度のため。
この関係式をCの式に代入して整理すると:
C=Tpwm/(2R×ln ((4,096−Amin)/(4,096−Amax)))
電源電圧Vddに無関係な式となりました。つまり、Vddが3.3Vから多少上下に振れたとしても、求めた静電容量Cに影響しません。
以上より、測定した静電容量Cの誤差は、PWM周期の誤差、抵抗Rの誤差(公差を含む)、AD変換器の変換誤差で決まることが解ります。
唯一既知の回路定数である抵抗Rですが、どんな値でも良いという訳ではありません。本節で説明した方法で静電容量Cを求める場合、以下の条件を満たす必要があります。
0V<<Vmin<<Vmax<<Vdd
上の関係を満たせるかどうかは、抵抗Rの値にかかっています。
未知の静電容量Cを測定しようとする場合、最適な抵抗Rが判らないので、まずは、任意の抵抗Rを選んで、一度、充放電電圧波形を観測してみる必要があります。
一般に、静電容量Cが大きいと小さい抵抗Rが必要で、静電容量Cが小さいと大きい抵抗Rが必要となります。測定しようとする静電容量が大きすぎたり、小さすぎたりする場合は、最適な抵抗Rが小さすぎたり(ショート、短絡)、大きすぎたり(オープン、開放)して、測定不可能となる場合があります。
本方式で静電容量を測定しようとする場合の限界です。
「静電容量を測定したい状況って、どんな時なの?」と、考えてみました。
市販のコンデンサは容量値が表示されているし、実測しなくても良いよね?
だとすると、静電容量を測定したいのは、コンデンサを自作した時?
2個の電極があって、その間が絶縁されていれば、静電容量の大小はあってもコンデンサとなり得ます。自作するのは容易いです。
※プリント基板やLSI等に回路を作り込む時は要注意です。細い配線とは言え、狭い間隔で並行して長く配線を引き回してしまうと、並走する2本の配線が電極となってコンデンサを形成してしまいます(既成容量)。既成容量の充放電にエネルギが使われるため、信号の伝搬遅延が発生したり、2本の配線間にクロストークが発生したりして、回路特性を低下させてしまう要因となります。
平行平板コンデンサの静電容量は、理論上、以下式で求められます。
向かい合う電極の面積: S[m2]
向かい合う電極間の距離: d[m]
電極間絶縁材料の比誘電率: ε
真空の誘電率(電気定数)ε0=8.854×10-12[F/m]
静電容量: C=ε0×ε×S÷d[F]
どのくらいの静電容量になるのか、具体的に計算してみましょう。
一辺75cmのアルミ板を2枚購入してきたと仮定します。S=0.75×0.75[m2]です。
間に挟むコピー用紙の厚さd=0.1mm程でしょうか?
紙の比誘電率ε=2〜2.5程度みたいです。
静電容量C≒99.6nFとなりました。
約100nFですので、104と刻印されたセラミックコンデンサ(下図、直径5mm程のどら焼き形)と同程度の静電容量値です。
一辺75cmなんていう、大きなアルミ板を使ってようやく、上図の様な小さなセラミックコンデンサと同程度の静電容量にしかなりません。大容量のコンデンサを自作するのは大変そうですね?
静電容量を大きくするには:
理論的にある程度計算はできますが、例えば面積Sは「向かい合った電極の面積」です。もし、アルミの板を重ねた時に少しずれてしまったら、ずれてはみ出した部分は「向かい合っ」ていないので、面積Sから除外しなければなりません。
絶縁材料の厚さdも、材料やアルミ板に歪みがあったり凹凸がある場合、ピッタリ密着させたつもりでも、所々浮いてしまっているかもしれません。その場合、電極間の距離は厚みdより広くなって、静電容量を小さくします。
絶縁材料に穴が開いている場合、穴には空気が充填されているので、空気の比誘電率ε≒1となって静電容量を低下させてしまいます。
コンデンサを自作する場合、実際にどのくらいの静電容量になったのか?測定する必要に迫られるでしょう。
LCRメータ等の装置が無い場合に、簡易測定できますよっ、と言う程度のお話です。
筆者には、コンデンサを自作したいという要求はありませんので、以下実験では市販コンデンサの静電容量を測定して見て、公称値との相違が無いかどうか?確認してみたいと思います。
こちらからデザインをダウンロードして、MSOC115LS0808マイコンをFPGAボードに書き込んでください。
命令ROMには、logiscope.asmをアセンブルして書き込んでください。
こちらのCR回路とFPGAボードの指定端子(ピン配置表はこちら)を接続してください。
FPGAボードにFTDI等のUSB⇔UART変換モジュールを接続して、電源を投入してください。
以下に実験中の様子を示します。
PC側でLogiscopeを起動(logiscope.olv)して、実験を進めます。
※スクリプト(.olv)の実行には拙作Olive+をWindowsにインストールしてください。
実験サンプル:【 】内はLogiscopeからの送信データ
【ana,0,128】
OK: analogWrite(0, 128)
tim0_pwma端子にデューティ50%(=128)のPWMを出力しました。
【vcdo,3,16,4,4000】
AD変換器のチャンネル0と1を4μs間隔でサンプリング、取り込み開始(トリガ)はチャンネル0の波形が16LSB以上上昇したタイミング、取り込み時間は最大4,000μs(=4ms)として、【vcdo】コマンドを実行します。
測定した波形はlogiscope_a.vcdファイルに出力されたので、波形表示ソフトウェアGTKWaveを使って閲覧します(下図)。
実験サンプル:【 】内はCygwinシェルウインドウからの実行コマンド
【gtkwave logiscope_a.vcd】
チャンネルcha[15:0]が、充放電に使用したPWM出力(Tpwm≒2ms、デューティ50%)、チャンネルchb[15:0]が容量Cの電圧波形です。
chaの立ち上がり位置でchbの電圧値を拾ってVmin、chaの立ち下がり位置でchbの電圧値を拾ってVmaxとします。すると、以下の様に未知の静電容量Cを求めることができます。
上図で測定したVmax=1.959V
上図で測定したVmin=1.277V
使用したPWM周期Tpwm=(timprd+1)/fcpu×timpsc≒2.040ms
timprd=254 (16ビットタイマ周期レジスタ)
timpsc=192 (16ビットタイマ分周レジスタ)
fcpu=24MHz (動作周波数)
使用した抵抗R=220Ω
電源電圧Vdd=3.3V
より、静電容量Cは以下の通り求められる。
C=Tpwm/(2R×ln ((Vdd−Vmin)/(Vdd−Vmax)))≒11.2μF
実際に使った容量は、10μFの電解コンデンサ(下図)だったので、公称値との乖離は約12%程でした。まずまず。
同様に、セラミックコンデンサ104=(10×104)[pF]=100nFをR=20kΩで観測したところ、以下図を観測しました。
静電容量Cを求めてみるとC=55.8nFと、公称値100nFに対して大きな誤差(約−44%)が有りました。
試しに、104のコンデンサをもう一つ並列に接続して測定したところ、測定値はおよそ×2倍の約116nFとなって、挙動としては期待通りでした。
nFオーダと言う小さい容量値が上手く測定できなかったのか、セラミックコンデンサの公差が思った以上に大きいのか、抵抗などの公差による誤差が支配的となって、公称値よりも小さい値に測定できてしまったのか、詳細は不明ですm(1__)m。
Moscovium版Logiscopeにデジタルオシロスコープ機能を拡張して、今回は2チャンネルのアナログ信号取り込みを試してみました。最大4チャンネルまで取り込むことができますし、1チャンネルであれば最速500kHz(2μs間隔)で高速サンプリングできますので、アナログ回路のデバッグに使用できると思います(満足(1^−^))。