今回のテーマは「二本立て」です。
Logiscopeは、本HPで開発してシステムデバッグなどに活用してきた、超簡易的ロジアナ+オシロスコープ機能を備えたツールです。
基本的には、Arduino UNO(ATmega328P)の延長なので、プログラム拡張の作業量自体は軽微です。実際、何か所か「#ifdef __AVR_ATmega328PB__」を追加して場合分けするだけで済みました。
Logiscopeの機能としては、様々なコマンドでデジタル端子番号D<dpin>やアナログ端子番号A<apin>を指定することになります。以下のピン配置表で、ATmega328PとATmega328PBの端子番号を確認しておいてください。
ピン配置表:
Arduino IDE+MiniCoreボードの環境では、本家UNOでは割り当てされていない、RESET,XTAL1,XTAL2等の端子や、28DIP→32TQFPで追加になった4端子にも、デジタル端子番号D#が割り振られているので、それらもLogiscopeから制御/観測が可能と、なります。
UNO(ATmega328P)→ATmega328PBで追加された端子は以下の通りです。
Arduino UNOでは、リセット端子、水晶発振端子として占有使用されているため、デジタル端子番号D#の割り当てが有りませんでした。
これらの端子は、ヒューズを書き込んで、リセット端子を無効にしたり、外部発振を使わずに内蔵RC発振器で動作させたりすると汎用I/Oポートとして使用可能となるため、MiniCoreボードのATmega328PBではデジタル端子番号D20〜D22が割り当てられている様です。
※なお、ヒューズの書き込みなどに使うシリアルプログラミングモードにはRESET端子が必須となりますし、外部発振で使いたい場合にはXTAL1,2端子が占有使用されるため、本節の3端子をデジタル端子として使うのは推奨しません。
パッケージが変わった事(28DIP→32TQFP)で追加になった端子は以下の通りです。
PORT-E(PE0〜PE3)、I2C#1通信端子(SCL1,SDA1)、追加のアナログ端子(A6,A7)の4本が、デジタル端子番号D23〜D26に割り当てられました。
単なる汎用I/Oポートとしても、「あと数本足りない」時には助かりますが、上の4端子は、2ユニット目のI2C#1やアナログ端子など、中々使い勝手の良さそうな追加端子です。美味。
ATmega328PBに搭載されているタイマのユニット数も増加しています。これに伴い、PWM出力も+4本増加しました。
えっと、ATmega328PBデータシート上は、PWM出力が+4本増加している様に記載されています。上に示した様に、OC3A,OC4A,OC3B,OC4Bの4本が増加しているのは確かですが、OC3BとOC4Bの2本は同じI/OポートD2に割り当てられているため、PWM出力可能な端子数としては、+3本の増加に留まっています。
しかも、D0,D1端子は、UART#0と重なっているので、Arduino IDEでUART#0からの書き込み機能を使う場合には、実質使用不可です。
実用的に使用可能なPWM端子は、D2に追加となった1本だけ、と、残念な仕様でした。出力場所(端子)の良し悪しで、こうも残念な事になるとは……、勿体ない👻。
ここからはATmega328PBに限らず、これまでに対応してきたマイコンボードである、Arduino UNO、328duino、Arduino DUE、STM32ボードを含めて、Logiscopeの機能を拡張して行きます。
拡張としては、冒頭に記載した複数デジタル端子の取り込みだけでなく、既存の【osc】コマンドにデジタル端子によるトリガ機能も追加して行こうと思います。
既存の【trg】コマンドでは、デジタル端子1本の取り込みができます。
PWM等の波形を取り込んで確認することができるだけでなく、UARTやDHT11など、1本のデジタル端子で閉じる通信信号線にも応用可能です。
その一方で、I2CやSPI等の通信規格では、クロックとデータなど、複数の信号線が組み合わさって通信を成立させることが多いです。この様な通信状況を確認したい場合、1端子だけ取り込みできる【trg】コマンドでは不足なのです。
1端子の取り込みには、普通にdigitalRead()関数などが使用可能でした。しかし、この調子で複数端子を取り込もうとすると、以下の様に実行する事になります。
pin0=digitalRead (pin_Dx0);
pin1=digitalRead (pin_Dx1);
pin2=digitalRead (pin_Dx2);
pin3=digitalRead (pin_Dx3);
上例に於いて、厳密に言うとpin0およびpin1は同時刻の状態ではありません。UNO @16MHzの様に非力なマイコンボードでは、pin0とpin1間の時間差は数μsに上ります。pin1とpin2、pin2とpin3、……すべて同じ事ですから、各端子の変化タイミングと取り込みタイミング次第では、本来とは異なる変化順番で取り込んでしまうこともあり得ます。
つまり、複数端子の取り込みを実行する場合には、個別にdigitalRead()関数を実行してはダメで、「同時に」取り込む必要があるのです。
Arduino UNOのメインマイコンATmega328Pを例にとると、例えば、以下の端子は、1つの汎用I/Oポートである、PORT-B(PB5〜PB1)に割り当たっています。
同じI/Oポートに配置されているため、ATmega328Pの内部I/OレジスタPINB(I/Oアドレス=0x03)を読み出すと、同時に5本のI/Oポート状態を取り込むことができます。
この様に、新設する【cap】コマンドで同時に取り込むデジタル端子はマイコン毎に、
しなくてはなりません。
既存の【osc】コマンドは、Logiscopeに備わった機能の1つで、指定したアナログ入力端子状態を取り込むコマンドです。
本コマンドでは、取り込み開始のトリガを、直前のアナログ読み取り値からの偏差で指定することができます。例えば、+10を指定すると、アナログ値の偏差が+10LSB(立ち上がりエッジ)以上になった時点で取り込みを開始します。−10なら、立ち下がりエッジで取り込みを開始します。
ところが、アナログ信号はノイズなどによっても変動するため、トリガの偏差を小さく設定し過ぎると、ノイズに反応してしまいます。逆に大きく設定し過ぎると、変動が緩やかだった場合等に条件と合致せず、トリガが掛からない場合があり得ます。
そこで、観測したいアナログ信号とは別に、トリガとなるデジタル端子を指定しておき、デジタル信号の立ち上がり/立ち下がりエッジで、アナログ信号の取り込みを開始する様にするのが、今回の拡張です。コマンド名を【tosc】コマンドとします。
拡張したArduino側の制御プログラムとWindows側のスクリプトを、改めてリンクしておきます。
Arduino側制御プログラム:logiscope.ino
Windows側U/Iスクリプト:logiscope.olv
※スクリプト(.olv)の実行には拙作Olive+をWindowsにインストールしてください。
Arduino IDEを使って、logiscope.inoをArduinoへコンパイル&書き込みしておきます。
Windowsでlogiscope.olvを実行すると、Olive+が起動して、Arduinoがつながっている通信ポートを問い合わせてきますので、メニューから選択してOKボタンを押します。
コマンド入力を求めるウインドウが開きますので、あとは、実装したコマンドを入力して送信すれば、応答があるはずです(下図)。
以下に、新設したコマンドの仕様を説明しておきます。
新設Logiscopeコマンド仕様:
Logiscopeの変更履歴を見ていたところ、久しぶりの更新でした。まあ、ほぼほぼ完成・安定していたプログラムなので、そうなりますよね。デバッグでの使用頻度も高いし、本ページでは非常に重要なツールです。
【tosc】コマンドの検証には、何らかのアナログ信号が必要なので、外部にCR充放電回路を接続して実験しようと思います(下図は参考)。
上図は使い回しなのですが、今回は時定数CR=1μF×1kΩ=1msで回路を構成して使います。
本ページでは折角なので、対応したばかりのATmega328PBボードを使って、Logiscopeの新機能を試してみようと思います。新機能は、UNO、DUE、STM32ボードでも動作するので、他のマイコンボードを使ってもOKです。その場合、【ana】コマンドや【cap】コマンド等の対象端子が異なるので、適宜読み替えて実験して見てください。
以下に実験中の様子を示します。
して、この先に進んでみてください。
ATmega328PBボードでジャンパ線を使い、以下の様に接続してください。
実験を進めます。
実験サンプル:【 】内はLogiscopeからの送信データ
【ana,2,32】
OK: analogWrite(2, 32)
【ana,3,96】
OK: analogWrite(3, 96)
【ana,5,160】
OK: analogWrite(5, 160)
【ana,6,224】
OK: analogWrite(6, 224)
4本分のPWMを異なるデューティで出力しました。
【cap,1b,03,03,10000】
新設した【cap】コマンドを使い、4端子(D13,D12,D10,D9)を取り込み(第一引数=1b)、トリガ端子は下位2ビット(D10,D9、第二引数=03)で、{D10,D9}=0x03(第三引数=03)となった時に取り込みを開始、10,000μs(第四引数=10,000)まで取り込んだら終了と指示しました。以下の様な波形が表示されたはずです。
一番上の波形から下方向へ順に、【cap】コマンドで取り込むI/Oポートの下位ビット→上位ビットの波形データが表示されます。UNO(ATmega328PBも同じ)であれば、上から順に、D9,D10,D11,D12,D13です。現在、こちらの接続ですので、上から順に、D6,D5,(−),D3,D2のPWM波形に対応します。
左端の0μsタイミングに着目すると、トリガに設定した下位2ビットが{D10,D9}=0x03になったタイミングで取り込みを開始していることが解ります。
ATmega328PBは、内蔵RC発振器モードに設定してあるため、fcpu=8MHzです。このため、タイマ#0(D6,D5 → D9,D10)は周期2,048μs、タイマ#2(D3 → D12)およびタイマ#3(D2 → D13)は周期4,096μsと、なっている様です。各々、【ana】コマンドで設定したデューティでPWM波形が出力されている事を確認できました。
また、異なるタイマ間では、タイマカウンタが同期していないため、PWMの位相がずれていることも判ります。一方、D6,D5 → D9,D10は同じタイマ#0なので同じ位相で、常に立ち上がりエッジの時間が等しいことが見て取れます。端子状態を同時取り込みしたお陰です。
ここで、D11端子のはんだ不良が発覚しました。上の実験で意味ありげにD11を避けて接続したのは、その為です。D11ポートにLOW/HIGHレベルを接続して、【ind】コマンドで読み出すと正常なので、はんだ不良で高抵抗になっていて、高速なPWM波形に追従できない様です。
D11にはSPIのMOSI端子が割り当たっており、シリアルプログラミングモードでの通信は、できているので、出力機能には問題なく、入力機能にダメージがあるのかも知れません。
はんだ付け確認の実験をした時には、OK判定だったのだけど、その後悪化したのか、見抜けなかったのか……?完全に接続されていない状況では無いみたいなので、微妙な状態なのでしょう。いずれにしても、筆者のはんだ付け技術不足が招いた不具合ですm(1x_x;)m。
不具合があるのはピッチ変換したATmega328PBの方で、Logiscopeの機能に問題ありませんので、念のため。
※やはり、ピッチ変換は鬼門でした。
こちらのCR回路を実装したブレッドボードと、ATmega328PBボードでジャンパ線を使い、以下の様に接続してください。
実験を進めましょう。
実験サンプル:【 】内はLogiscopeからの送信データ
【ana,9,128】
OK: analogWrite(9, 128)
デジタル端子D9に、デューティ50%(=128/255)のPWMを出力しました。D9をD13端子と、CR回路に接続してあるので、PWM出力でCR回路を充放電しています。
【tosc,0,+13,5,100】
デジタル端子D13の立ち上がりエッジをトリガ(第二引数=+13)として、アナログ端子A0(第一引数=0)をサンプリングレート19.2kHz(第三引数=5 @clk=8MHz)で、100サンプル分(第四引数=100)のデータを取り込みました。下図の様な波形が表示されましたか?
トリガに指定したD13端子がそのまま、CR回路の充放電電圧となるので、上図の時間0μs位置が常に、D13の立ち上がりエッジ、かつ、充電開始タイミングと、なっています。【tosc】コマンドの第二引数を「−13」として、D13端子の立ち下がりエッジを指定すると、放電開始タイミングで観測することもできます。
トリガエッジ(左端、0μs)から、約60μs程遅れて、アナログ波形が立ち上がり始めているように見えていますが、fcpu=8MHzのATmega328PBで、1回分のAD変換時間(約52μs @8MHz)が観測されたと考えられます。この程度の時間差は生じる、と言う事を前提に観測してください。
今回の実験では手っ取り早く、自分で出力した信号を自分で観測して見ました。実際にシステムデバッグに使用する場合には、システムを構成するマイコンボードとは別に、Logiscopeを実行するマイコンボードを用意して、様々な信号線を観測しながらデバッグや検証を進める事になります。
例えば、以下記事の実験などがそうです。
「#17-6 I2Cマスタ通信」
FPGAボード+MCP4725(DA変換器モジュール)で正弦波を出力する実験で、出力した正弦波(アナログ波形)を観測するのに、STM32ボード+Logiscopeを使った例です。
その点、5Vトレラント端子(汎用I/Oポート、アナログ入力は3.3V)を備えているSTM32ボードは、UNO等5V定格マイコンボードのデバッグにも使えるし、fcpu=72MHzと高速な為、信号波形の取り込み解像度も高く、重宝しています。
今回のお買い物は、以下の通りです。
「#29-1 ロボットカーを組み立てよう」のお買い物と一緒に、秋月電子通商で購入してあった物です。
元々手持ちに有った10μF電解コンデンサに対して、1桁ほど小さい電解コンデンサを買っておきました。アナログフィルタを作る時など、容量値の選択肢が増えると回路設計し易くなるので、先回りして購入したものです。現時点で、具体的な用途は頭にありません。
今回は使用しませんでしたが、同じく手持ちに有った0.1μFから1桁小さいセラミックコンデンサ0.01μFも購入しておいたので、併せてご紹介しておきます。
今回の実験では、時定数を1ms程に調整できれば良かったので、容量値1μFは必須では無かったのですが、折角購入したので、使って見ました。
本HPを立ち上げた当初、だいぶ初めの頃に開発したLogiscopeですが、本HPに於けるシステムデバッグには、欠かせないツールと、なっています。今回の拡張で、更に使い勝手が向上したので、宜しければ、ご活用ください。