🐙

Pico ボードは実験室! pico-jxgLABO を導入してロジックアナライザ機能を試してみる

に公開

Raspberry Pi Pico は Raspberry Pi Ltd. が提供する小型で安価 (約 800 円) なマイコンボードです。初代の Pico は 125MHz の 32bit ARM コア (しかもデュアル)、264KByte の SRAM, 2MByte のフラッシュメモリ。Pico 2 にいたっては CPU 150MHz (デュアル), 520KByte の SRAM, 4MByte のフラッシュメモリ、ハードウエア浮動小数点演算をサポートするなど、非常に高性能なマイコンボードです。

pico-and-pico2.jpg

でもそんな豊富な機能も、使い方を知らなければ宝の持ち腐れ。そこで、Pico ボードで実際に様々な機能を試すことができる実験プラットフォーム pico-jxgLABO を開発しました。主な特徴は以下の通りです。

  • 容易な環境構築: Pico ボードを USB ケーブルで接続するだけで、すぐに実験を開始できます
  • ロジックアナライザ: 最大 50MHz (Pico 2 の場合) でサンプリングができるロジックアナライザ機能を搭載。配線をすることなく、内部信号をキャプチャできます。もちろん、GPIO ピンに接続することで外部信号のキャプチャも可能です
  • シリアル通信: UART, SPI, I2C の各種シリアル通信プロトコルで、データの送受信が可能です
  • GPIO 制御: GPIO ピンの制御が可能。入力、出力、PWM 制御などができます。
  • ホスト PC と共有できるファイルシステム: Pico ボードのフラッシュメモリをファイルシステムにマウントし、ホスト PC と共有することができます
  • PC ライクなファイル操作: ファイルのコピー、削除、ディレクトリの作成など、PC のようなファイル操作が可能です

pico-jxgLABO は単なる実験プラットフォームにとどまりません。任意のプログラムにわずか 4 行のコードを追加するだけで pico-jxgLABO の豊富な機能を組み込むことができます。例えば、ロジックアナライザ機能を使って、Pico ボード上で動作するプログラムのデバッグや、シリアル通信のモニタリングなど、いろいろな用途に利用できます。僕にとってはこちらが主な使用目的になります。

各機能の詳細は以下の記事を参照ください。

▶️ GPIO 制御 - L チカだけじゃ物足りない! gpio コマンドで Pico の GPIO 制御の深淵にもぐる
▶️ PWM 制御 - 操作方法を知って使いこなす! pwm コマンドで Pico の PWM の限界を探る
▶️ ロジックアナライザ (PulseView 連携) - pico-jxgLABO × PulseView: プローブ接続いらずで気軽に使えるロジックアナライザを体験しよう!

pico-jxgLABO の導入方法

必要な機材

pico-jxgLABO を使うのに必要な機材は以下の通りです。

  • ホスト PC (Windows, Linux など)
  • Pico ボード (Pico, Pico 2, Pico W, Pico 2 W など)
  • USB ケーブル

ホスト PC にはシリアル通信のためのターミナルソフトをインストールしてください。以下の説明では、ホストとして Windows PC を使用し、ターミナルソフトには Tera Term を使います。

Pico ボードへの書き込み

  1. 以下のいずれかの UF2 ファイルをダウンロードします
  2. Pico ボードの BOOTSEL ボタンを押しながら USB ケーブルを接続すると、Pico ボードが USB マスストレージとして認識されます。多くの場合 D: ドライブとして認識されます
  3. ダウンロードした UF2 ファイルを上記のドライブにコピーします。コピーが完了すると、Pico ボードは自動的に再起動され、pico-jxgLABO が利用できるようになります

pico-jxgLABO の使い方

環境設定と動作確認

シリアル通信をするため Tera Term を起動します。メニューバーから [設定 (S)]-[シリアルポート (E)...] を選択し、接続する Pico ボードのシリアルポートを選択します。

teraterm-setting.png

pico-jxgLABO は 2 つのシリアルポートを提供します。一つはターミナル用、もう一つはロジックアナライザやプロッタなどのアプリケーション用です。提供する最初のシリアルポート (上の例だと COM21) がターミナル用になります。これを選択して [新規オープン (N)] または [現在の接続を再設定 (N)] をクリックします。

ターミナル上で [Enter] キーを押すと、以下のようなプロンプトが表示されます。

L:/>

このプロンプトを使って pico-jxgLABO の操作をします。プロンプトの入力内容は、カーソルキーやデリートキーなどで編集ができます。TAB キーでコマンド名やファイル名の補完ができます。また、上下矢印キーでコマンド履歴を参照できます。

まずは、help コマンドを入力して、使用可能なコマンドの一覧を表示してみましょう。

L:/>help
.               executes the given script file
about-me        prints information about this own program
about-platform  prints information about the platform
adc             controls ADC (Analog-to-Digital Converter)
adc0            controls ADC (Analog-to-Digital Converter)
adc1            controls ADC (Analog-to-Digital Converter)
                        :
                        :

オプション --help (または -h) をつけてコマンドを実行すると、詳細な使い方が表示されます。

L:/>cp --help
Usage: cp [OPTION]... SOURCE... DEST
Options:
 -h --help      prints this help
 -r --recursive copies directories recursively
 -v --verbose   prints what is being done
 -f --force     overwrites existing files without prompting

なじみのあるファイル操作コマンド (ls, cp, mv, rm, mkdir, cat など) が利用可能です。また、リダイレクトに対応しているので、コマンドの出力をファイルに保存することができます。

L: ドライブは Pico ボードのフラッシュメモリを FAT ファイルシステムとしてマウントしたもので、ホスト PC からは USB マスストレージとして認識されます。ホスト PC 側で割り当てられるドライブレターは環境によって異なりますが、例えば D: ドライブとして認識されることが多いです。Pico ボード上で作成したファイルは、ホスト PC から参照できますし、ホスト PC から Pico ボード上にファイルをコピーすることもできます。

ロジックアナライザ機能を試す

pico-jxgLABO のロジックアナライザ機能を試してみましょう。今回はデモンストレーションとして I2C インターフェースの信号をキャプチャします。

la コマンドを使ってロジックアナライザを起動します。オプション -p でキャプチャするピンを指定します。ここでは Pico ボードの GPIO2 (I2C SDA) と GPIO3 (I2C SCL) を測定します。

L:/>la -p 2,3 enable
enabled pio:2 12.5MHz (samplers:1) pins:2,3 events:1/88674 (heap-ratio:0.7)

これでロジックアナライザが有効になりました。バックグランドで信号のキャプチャが行われています。信号の変化があるときだけキャプチャ処理が行われるので、急いで操作をする必要はありません。

次に、i2c1 コマンドを使って I2C プロトコルの信号を出力します。オプション -p で使用する SDA, SCL ピンを指定します。scan サブコマンドは、アドレス 0 から 127 に対して Read リクエストを送信し、応答があったアドレスを表示します。

L:/>i2c1 -p 2,3 scan
Bus Scan on I2C1
   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

これで I2C の信号が生成されました。キャプチャがされているか、la コマンドを実行してロジックアナライザの状態を確認します。

L:/>la
enabled pio:2 12.5MHz (samplers:1) pins:2,3 events:3461/88674 (heap-ratio:0.7)

イベントの数が増えて、信号のキャプチャがされていることがわかります。la print コマンドを使って、キャプチャした信号を表示します。

L:/>la print
 Time [usec] P2  P3  
             │   │  
             :   :  
        0.00 └─┐ │  
        1.20   │ └─┐
      575.04 ┌─┘   │
      579.52 │   ┌─┘
      585.84 │   └─┐
      590.24 │   ┌─┘
      596.64 │   └─┐
      601.04 │   ┌─┘
      607.36 │   └─┐
      611.76 │   ┌─┘
      618.16 │   └─┐
      622.56 │   ┌─┘
      628.88 │   └─┐
      633.28 │   ┌─┘
      639.68 │   └─┐
      644.08 │   ┌─┘
      650.40 │   └─┐
      654.88 │   ┌─┘
      655.52 └─┐ │  
      661.20   │ └─┐
      665.60   │ ┌─┘
      671.92   │ └─┐
      676.32   │ ┌─┘
      676.64 ┌─┘ │  
      682.72 │   └─┐
      687.84 └─┐   │
         :
         :

表示分解能 (1 行あたりに表示する時間間隔) は、デフォルトで 1000usec (1msec) です。上の例だとエッジの間隔が 5usec 程度ですから、それよりも短くしないと正しい表示ができません。そこで、オプション --reso を使って、表示分解能を 4usec に設定して波形表示をします。

L:/>la print --reso:4
 Time [usec] P2  P3  
             │   │  
             :   :  
        0.00 └─┐ │  
        1.20   │ └─┐
               :   :
      575.04 ┌─┘   │
             │     │
      579.52 │   ┌─┘
             │   │  
      585.84 │   └─┐
             │     │
      590.24 │   ┌─┘
             │   │  
      596.64 │   └─┐
             │     │
      601.04 │   ┌─┘
             │   │  
      607.36 │   └─┐
             │     │
      611.76 │   ┌─┘
             │   │  
      618.16 │   └─┐
             │     │
      622.56 │   ┌─┘
             │   │  
      628.88 │   └─┐
             │     │
      633.28 │   ┌─┘
             │   │  
      639.68 │   └─┐
             │     │
      644.08 │   ┌─┘
             │   │  
      650.40 │   └─┐
             │     │
      654.88 │   ┌─┘
      655.52 └─┐ │  
               │ │  
      661.20   │ └─┐
               │   │
      665.60   │ ┌─┘
               │ │  
      671.92   │ └─┐
               │   │
      676.32   │ ┌─┘
      676.64 ┌─┘ │  
             │   │  
      682.72 │   └─┐
             │     │
      687.84 └─┐   │
               │   │
         :
         :

画面キャプチャをして、横向きに回転させたイメージを以下に示します。

la-i2c.png

まだプロトコルアナライザが実装されていないので、ビットパターンを手動で解析する必要があります。でも、I2C の解説記事などを片手に信号を眺めてみれば ... スタートコンディション・アドレス・Read/Write・ACK・ストップコンディションのビットパターンが見えてきませんか? ブラックボックスだった信号プロトコルが、波形を観測することですべてが明白になって、なんだか嬉しくなります。

la print は、デフォルトでは最初の 80 イベントを表示します。--part:all オプションを使うと、すべてのイベントを表示できます。

L:/>la print --part:all
 Time [usec] P2  P3  
             │   │  
             :   :  
        0.00 └─┐ │  
        1.20   │ └─┐
             :
             :

Ctrl-C キーを押すと、表示を中断できます。

リダイレクトを使うと、表示内容をファイルに保存できます。例えば、i2c.log というファイルに保存するには以下のようにします。

L:/>la print --part:all > i2c.log

L: ドライブは ホスト PC には USB マスストレージデバイスとして認識されるので、ホスト PC 側で i2c.log ファイルを開くことができます。PC のテキストエディタで開くと、内容が見やすくなります。

キャプチャをやり直すには la enable コマンドを再度実行します。オプションを省略すると、前回の設定が引き継がれます。

L:/>la enable
enabled pio:2 12.5MHz (samplers:1) pins:2,3 events:1/88674 (heap-ratio:0.7)

la disable コマンドを実行すると、ロジックアナライザが無効になります。

ロジックアナライザの基本的な操作は以上になります。i2c コマンドを使ったデバイスとの通信例を以下にいくつか紹介しますので、いろいろ試してみてください。

  • RTC モジュール DS3231 の時刻を読み取る (I2C アドレス 0x68 にデータ 0x00 を送信してから 7 バイトのデータを受信)

    L:/>i2c1 -p 2,3 0x68 write:0x00 read:7
    
  • EEPROM 24LC64 のアドレス 0x0186 にデータ 0xaa, 0xbb, 0xcc, 0xdd を書き込む (I2C アドレス 0x50 にデータ 0x01, 0x86, 0xaa, 0xbb, 0xcc, 0xdd を送信)

    L:/>i2c1 -p 2,3 0x50 write:0x01,0x86,0xaa,0xbb,0xcc,0xdd
    
  • EEPROM 24LC64 のアドレス 0x0186 から 4 バイトのデータを読み取る (I2C アドレス 0x50 にデータ 0x01, 0x86 を送信してから 4 バイトのデータを受信)

    L:/>i2c1 -p 2,3 0x50 write:0x01,0x86 read:4
    

その他の機能

pico-jxgLABO には、ロジックアナライザや I2C 通信以外にも多くの機能があります。以下にいくつかの例を示します。

  • GPIO 制御: gpio コマンドを使って、GPIO ピンの制御ができます。例えば、GPIO6 を出力モードに設定して HIGH にするには以下のようにします。

    L:/>gpio6 func:sio dir:out put:1
    
  • PWM 制御: pwm コマンドを使って、PWM 信号の出力ができます。例えば、GPIO6 で 1kHz の PWM 信号を 50% デューティサイクルで出力するには以下のようにします。

    L:/>pwm6 func:pwm freq:1000 duty:.5 enable
    
  • ADC 制御: adc コマンドを使って、アナログ信号の読み取りができます。例えば、ADC0 (GPIO26) のアナログ値を読み取るには以下のようにします。

    L:/>adc0 read
    3.300V
    
  • UART 通信: uart コマンドを使って、UART 通信ができます。例えば、GPIO0 (TX) と GPIO1 (RX) を使ってデータの送受信を行うには以下のようにします (通信相手のデバイスが接続されていないのでデータ受信はタイムアウトになっています)。

    L:/>uart0 -p 0,1 write:0x12,0x34,0x56,0x78 read:6
    No data received within timeout
    
  • SPI 通信: spi コマンドを使って、SPI 通信ができます。例えば、GPIO2 (SCK), GPIO3 (MOSI), GPIO4 (MISO) を使ってデータの送受信を行うには以下のようにします。

    L:/>spi0 -p 2,3,4 write:0x12,0x34,0x56,0x78 read:6
    00 00 00 00 00 00
    

    通信相手のデバイスが接続されていないのでデータ受信はすべて 0 になっています。

  • ファイル操作: cp, mv, rm, mkdir などのコマンドを使って、ファイルやディレクトリの操作ができます。例えば、test.txt ファイルを backup.txt にコピーするには以下のようにします。

    L:/>cp test.txt backup.txt
    
  • シェルスクリプト実行: シェルスクリプトファイルを作成して、複数のコマンドをまとめて実行できます。例えば、pwm-2-3-4-5.sh ファイルに以下の内容を書いておきます。

    pwm-2-3-4-5.sh
    pwm --quiet 2,3,4,5 func:pwm freq:1000 counter:0
    pwm2 --quiet duty:.2
    pwm3 --quiet duty:.4
    pwm4 --quiet duty:.6
    pwm5 --quiet duty:.8
    pwm 2,3,4,5 enable
    

    以下のように実行します。

    L:/>. pwm-2-3-4-5.sh
    

まとめ

この記事では、pico-jxgLABOの 導入方法とロジックアナライザ機能を中心に紹介しました。800 円の Pico ボードで詳細な信号解析ができることを体験していただけたでしょうか。

pico-jxgLABO は今回紹介したロジックアナライザ機能以外にも、GPIO 制御、PWM 出力、シリアル通信、ファイル操作など、組み込み開発に必要な機能を豊富に提供しています。また、わずか 4 行のコードで既存プロジェクトに組み込むことも可能です。

今後の記事では、これらの機能を個別に詳しく解説していく予定です。pico-jxgLABO を使って、Raspberry Pi Pico の豊富な機能を存分に活用してください。

GitHubで編集を提案

Discussion