ロジックアナライザーでタイミング合わせ

Spread the love

ロジックアナライザーで、タイミング合わせをしてみました。アナログ信号の場合、オシロスコープを使って波形を観察します。しかし、デジタル信号の場合、オシロスコープではやりづらい部分があります。デジタル信号の場合、波形そのものの重要性は高くありません。それよりも、他の信号との関連が重要となるため、より多くの信号を同時に扱う必要があります。また、信号をデコードして、信号の内容を表示する機能もあると重宝します。つまり、オシロスコープとは、少し違った見方で、信号を観察する道具が、ロジックアナライザーです。

激安ロジックアナライザーを買いました

Arduinoをいじり始めてから、ロジックアナライザーが欲しくなりました。しかし、まともなロジックアナライザーは高価で、私には手が出せません。そこで、困ったときのアリエクです。

早速目に飛び込んできたのは、500円以下のロジックアナライザーです。

アリエクで見つけた格安ロジックアナライザ
アリエクで見つけた格安ロジックアナライザ

この商品は、ロジックアナライザーというよりも、デジタル入力インターフェイスといった方がよいでしょう。これをPCに繋いて使用するようです。この手の中華製品ですから、説明書も保証書もなく送られてくるはずです。したがって、肝心のソフトウエアについては、自前で調達するしかありません。

もちろん、万一動かなかったとしても自己責任です。しかし、中華製品に共通する、「as isだけど無茶安だよ」という精神は結構好きです。

到着した商品を見てみる

中国から届いたロジックアナライザーは、見慣れた銀色の袋に入っていました。

中国から届いたロジックアナライザー
中国から届いたロジックアナライザー

中身は非常にシンプルで、本体とUSBケーブル、プローブ代わりのケーブル10本です。

ロジックアナライザーと付属品
ロジックアナライザーと付属品

いつものとおり、説明書も品質保証書もありません。そして、肝心のソフトウェアも同梱されていません。使用方法はネット検索をして、見つけなければいけません。ネット検索のキーワードになるのが、製品のモデル名です。

ロジックアナライザーの製品名:これでいいのか?
ロジックアナライザーの製品名:これでいいのか?

本体には「Analyzer 24MHz8CH」としか書かれていません。かなりざっくりしています。しかし、検索してみると、結構出てきます。片っ端から見ていったところ、どうやらPulseViewというアプリが使えるようです。

ロジックアナライザーのアプリを入手する

PulseViewの開発を行っている、sigrokのページに飛んでみました。すると、サポートしているデバイスの一覧に、購入したロジックアナライザーらしきものがありました。

sigrokサポートデバイス一覧の中にありました
sigrokサポートデバイス一覧の中にありました

早速、ソフトウェアをダウンロードしました。

64ビット版のPulseViewをダウンロード
64ビット版のPulseViewをダウンロード

ダウンロードして、インストールしたのですが、MSVCP100.DLLが見つからない旨のエラーが出ます。これは、Visual C++の再配布可能パッケージが、インストールされていないために生じるエラーです。これは、マイクロソフトのサイトからダウンロードできます

ロジックアナライザーを早速使ってみた:解決すべき問題

試しに、Arduinoにある三つのタイマーの同期をとってみようと思います。Arduinoでは、タイマーを使って、PWM信号を発生させることが出来ます。しかし、三つのタイマーの同期をとることが、これまで上手くいきませんでした。同期がとれていない状態を、ロジックアナライザーで取得してみました。

ロジックアナライザーの出力:同期がとれていない状態
ロジックアナライザーの出力:同期がとれていない状態

タイマーAとBのスタート位置は合っていますが、タイマー0,1,2のスタート位置が一致していません。つまり、三つあるタイマーカウンターTCNT0、TCNT1L、TCNT2の値がバラバラだということになります。

そこで、以下のコードをスケッチに追加してみました。

  // タイマ同期
  TCNT0 = uint8_t(0);  
  TCNT1L = uint8_t(0);  
  TCNT2 = uint8_t(0);   

三つのカウンターをゼロリセットしてみました。その結果がこれです。

三つのタイマーをゼロリセットして同期をとった結果
三つのタイマーをゼロリセットして同期をとった結果

いい感じになりました。

ロジックアナライザーを早速使ってみた:ズレ時間の計測

三つのタイマーを、ゼロリセットすることで、大まかに同期は取れました。しかし、よく見ると少しずれています。拡大して、どのくらいずれているのかを計ってみましょう。

ロジックアナライザーでキャプチャした信号にタグをつけて、ズレを計測する
ロジックアナライザーでキャプチャした信号にタグをつけて、ズレを計測する

拡大した信号のスタート部分にマーカーをつけて、ズレ時間を測定してみました。なお、マーカーを使う方法以外に、カーソルをあてて計測する方法があります。しかし、カーソルの場合二点間の計測しかできません。今回は三点の計測をしたかったので、マーカーを使いました。

マーカーAの右側のマーカーに+125nsと表示されています。そして、三番目のマーカーには、250nsと表示されています。

つまり、Timer1のリセットは、125nsオフセットした設定をしなければなりません。また、Timer2については250nsオフセットさせなければなりません。

Arduinoのクロック周波数は16MHzですので、1クロックサイクルは62.5nsです。すると、Timer1は125ns/62.5nsですので、ぴったり2クロック遅延していることになります。そして、Timer2は250nsですので、4クロックの遅延です。これをスケッチに反映してみました。

  // タイマ同期
  TCNT0 = uint8_t(0);  
  TCNT1L = uint8_t(2);  
  TCNT2 = uint8_t(4);   

計算どおり、Timer1を2クロックオフセットしました。また、Timer2については4クロックオフセットしました。その結果はこんな感じです。

ロジックアナライザーの出力は計算どおりにはならなかった

ロジックアナライザーを早速使ってみた:最後はエイヤで治す

2クロックずつオフセットした結果、ズレは減少しました。しかし、完全にズレを無くすことはできていません。そこで、オフセット量をもう少し大きくしてみました。

スケッチは、こんな風に修正しました。

 // タイマ同期
  TCNT0 = uint8_t(0);
  TCNT1L = uint8_t(3);
  TCNT2 = uint8_t(6);
オフセットを1クロック増やした結果
オフセットを1クロック増やした結果

ビンゴです。信号のスタートが、ぴったり一致しました。

これで、デューティー比が異なる6つの同期した信号を、同時に出すことが出来ました。信号全体はこんな感じです。

デューティー比の異なる6つのPWM信号
デューティー比の異なる6つのPWM信号

今回使用したスケッチはこんな感じです。

void setup() {
  // put your setup code here, to run once:

  // timer0のセッティング
  TCCR0A = 0;                                     // タイマー0コントロールレジスタAをクリア
  TCCR0B = 0;                                     // タイマー0コントロールレジスタBをクリア
  TCCR0A |= (1 << WGM01) | (1 << WGM00);          // タイマー0をmode3 fast PWMモードに設定
  TCCR0B |= (0 << WGM02);                         //
  TCCR0A |= (1 << COM0A1) | (0 << COM0A0);        // D6 SET on BOTTOM,reset on MATCH
  TCCR0A |= (1 << COM0B1) | (0 << COM0B0);        // D5 SET on BOTTOM,reset on MATCH
  TCCR0B |= (0 << CS02) | (0 << CS01) | (1 << CS00);       // プリスケーラー 1/1
  TIMSK0 |= (0 << OCIE0B) | (0 << OCIE0A) | (0 << TOIE0);  // 割り込みは使用しない
  OCR0A = 37;                                              // duty factor 1/7
  OCR0B = 73;                                              // duty factor 2/7

  // timer1のセッティング
  TCCR1A = 0;                                // タイマー1コントロールレジスタAをクリア
  TCCR1B = 0;                                // タイマー1コントロールレジスタBをクリア
  TCCR1A |= (0 << WGM11) | (1 << WGM10);     // タイマー1をmode5 8bit fast PWMモードに設定
  TCCR1B |= (0 << WGM13) | (1 << WGM12);     //
  TCCR1A |= (1 << COM1A1) | (0 << COM1A0);   // D9  SET on BOTTOM,reset on MATCH
  TCCR1A |= (1 << COM1B1) | (0 << COM1B0);   // D10 SET on BOTTOM,reset on MATCH
  TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);       // プリスケーラー 1/1
  TIMSK1 |= (0 << OCIE1B) | (0 << OCIE1A) | (0 << TOIE1);  // 割り込みは使用しない
  OCR1A = 110;                                             // duty factor 3/7
  OCR1B = 146;                                             // duty factor 4/7

  // timer2のセッティング
  TCCR2A = 0;                                 // タイマー2コントロールレジスタAをクリア
  TCCR2B = 0;                                 // タイマー2コントロールレジスタBをクリア
  TCCR2A |= (1 << WGM21) | (1 << WGM20);      // タイマー2をmode3 fast PWMモードに設定
  TCCR2B |= (0 << WGM22);                     //
  TCCR2A |= (1 << COM2A1) | (0 << COM2A0);    // D11 SET on BOTTOM,reset on MATCH
  TCCR2A |= (1 << COM2B1) | (0 << COM2B0);    // D3  SET on BOTTOM,reset on MATCH
  TCCR2B |= (0 << CS22) | (0 << CS21) | (1 << CS20);      // プリスケーラー 1/1
  TIMSK2 = (0 << OCIE2B) | (0 << OCIE2A) | (0 << TOIE2);  // 割り込みは使用しない
  OCR2A = 183;                                            // duty factor 5/7
  OCR2B = 219;                                            // duty factor 6/7

  // DDR(Data Direction Resystor)の設定
  DDRD |= 0b01101000;  // D3,D5,D6を出力モードに設定
  DDRB |= 0b00001110;  // D9,D10,D11を出力モードに設定

  // タイマ同期
  TCNT0 = uint8_t(0);   // Timer0をリセット
  TCNT1L = uint8_t(3);  // Timer1は8ビットモードなのでTNCT1Lのみ3クロックオフセット
  TCNT2 = uint8_t(6);   // 3クロック2回分、計6クロックオフセット
}

void loop() {
}

デコード機能を試す

今回購入したロジックアナライザーは、ワンコインで買える安物です。しかし、有志の手によるソフトウェアが優れています。例えば、信号のデコード機能も用意されています。

試しにUARTの信号のデコードをしてみました。

ロジックアナライザーでのUART信号デコード
ロジックアナライザーでのUART信号デコード

試しにUART信号をASCIIにデコードしてみました。UART以外にも、I2CやSPIなど、数えきれないくらい沢山のデコーダーが搭載されています。

今回購入した、ロジックアナライザーですが、サンプリング周波数は、最大24MHzまでです。また、チャンネル数も8チャンネルしかありません。しかし、アマチュアならばこの程度の性能であっても、そこそこ使えるのではないでしょうか。今回やった、6チャンネル62.5kHz PWM信号の同期をとるのには十分な性能でした。また、強力なデコード機能は、重宝しそうです。

これでワンコインなら、いい買い物だと思います。