【技術】Raspberry Pi Pico がやってきた!

  2024年11月15日
   ■Tags: | | | | | | | | | | | | | |

0.ピコの正体

わーい、得意なLinux上でのソフトウエア開発と思っていた矢先

  Raspberry PiリナックスRaspberry Pi Picoくみこみマイコン

という事実。OSもなく、組込みマイコンでした。

     ラズベリーパイピコと電子ペーパー

※ 下側の青い基板は電子ペーパー(後述します。)の制御基板で、上の緑色がピコです。

気を取り直して、開発環境構築選定していく過程で、実質Linuxシステムによるクロス開発に落ち着きました。
組込み用マイコンでセンサーやスイッチLEDやその他様々なものをI/O接続する事ができます。
詳細は、下記リンクで確認して下さい。

Raspberry Pi Picoの説明
Raspberry Pi Picoのデータシート

1. 開発環境の構築

開発ターゲットが決まりましたので、これのソフトウエアを開発する環境を整備します。
インターネット検索で調査をすると実に様々な開発環境が有りました。
基本、技術者として他人の絵空事は参考情報で何事も自分で試して決めてきましたので同様な手順を踏みました。
(開発期間が短期の為丁寧な確認はできませんしたが)満足のできる選定ができました。

表1. 開発環境比較
番号名前評価コメント備考
ラズパイ(Raspberry Pi OS)クロス開発ピコ開発元なので安定しています。但しラズパイでLinuxを動作させた経験から開発環境自体が遅そうです、。参考資料本家のはじめの一歩
Arduino IDEネット調査の感触では利用者が多い様で情報に困らなそうです。
ソフトウエアの書き方に少し癖がありそうです。
また、開発環境と導入ライブラリのバージョンで悩ましい難題がでてきそう。
参考URL:Arduino IDEダウンロード先
追加ライブラリ:更新御確認下さい。
Thonny(Micro Python)Python環境なので、動かしながらデバッグできます。処理速度に不安がありますが、
バイナリ化も出来る様です。
社内試作ならよさそうです。が、そもそもPython言語、美しくないので個人的に嫌いです。
今回インタプリタ実装は想定外です。
参考URL:Thonnyの配布元
本家SDK:Picoシリーズ向けPython SDKドキュメント
Eclipse×Windows上のEclipseにArmコンパイラやSDKをインストールしてラズベリーパイ ピコの
クロス開発環境にします。
この環境を本命にインストールを進めたのですが、
英語で記述されたインストール方法に従って構築しました。が、
コンパイルはできているのに、Link時に謎エラーメッセージが出て…
時間をかければ解決できそうです…ですが
超速前提、短期開発期間ではトライはNGはて困りました。
他の方法を発見したので中断しました。
参考URL:Eclipse CDT
本家SDK:Picoシリーズ向けC/C++ SDKドキュメント
Visual Studio CodeVisual Studio Code 個人的感覚と異なる異次元のツール。
未だに使用せずディスクの肥やし状態です。
本家では、Eclipseよりこちらを推奨しているようですが、参照ドキュメントが古いのかインストール途中で説明と異なる状態に見え途中で断念しました。
頻繁アップデートはうれしいです。が、過去と異なる動作を平気で繰返すいつものやり方についていけません。
空白です。(実は失念しました。)
下記により良いソリューションを見つけたので中断しました。
Raspberry Pi DesktopEclipse環境構築で少し困りラズベリーパイのホームページを探してみると
何とRaspberry Pi OSをWindowやMacで動かしてしまう環境を見つけました!
この環境を構築するためには、バーチャル環境が必須です。
幸い私のPC環境にはUbuntu24.04LTSを毎日起動しているVirtualBOX環境が
ありました。
上記Ubuntuと同様に「Raspberry Pi Desktop for PC and Mac」で
環境構築できました。
動作速度も問題なく、ラズパイのホームページに記載のドキュメント通りに
無事に開発環境も構築できました。
本家環境URL:Raspberry Pi Desktop
参考資料:本家のはじめの一歩

開発環境(オペレーティングシステム関連)情報です。

ラズベリパイ ピコにビルドしたバイナリファイルをドラグ&ドロップする為に
Windows10 上のフォルダをRaspberry Pi Desktopにマウントして使用しています。
実際のソフト開発や編集はWindows上のEclipseを使用しています。


2.組込み開発での衝撃

2.1 組込みソフトのインストール方法

 組込みだと、ICE上で動作・デバッグして、その後ROM焼きしてテスト実施という手順を踏むことが多いです。
ラズパイだとマイクロSDにOSイメージを作製して動作確認とかソフトのインストールが結構手間でした。
ピコは簡単なしかけをして、ICEやロム書き等の手間をピコをUSBメモリに見える様にする事で
ピコぺコピペでソフトインストールできます。

 電源を落としても実行バイナリはROMに残っていますのでほぼUSBメモリ感覚です。
この方式が特許になっていなかったら、(簡単にコピペできたらいけないシステムも
あるかも知れませんが)組込み系は真似して欲しいです。

以下に簡単な手順を示します。

1.開発環境でビルドして”ターゲット.uf2″ファイルを作成する。
2.Raspberry Pi Picoを開発環境PCに接続前に“BOOTSEL”という白いボタンを押して接続する。
3.開発環境PCにUSBメモリを接続した場合の様にドライブが追加されます。
4.このドライブに”ターゲット.uf2″をドラグ&ドロップします。
5.組込みソフトの書込みが終わると自動で立ち上がります。


はい、組込みソフトインストール完了です。
但し、デバッグはデバッガーを接続できていないので途中で止めたりメモリの値を確認したりできません。
代替手段として、USB接続によるプリント出力デバッグをするようです。

以下に示すデータシートでご確認下さい。

Raspberry Pi Picoのデータシート

2.2 On/Offスイッチ回路が超簡単

GPIOを使用して入力でピコ内でプルアップやプルダウンを指定する事で
外部にプルアップ/プルダウン抵抗を付けなくても動作します。
※ピン毎の許容範囲には注意(公開しているドキュメント参照して下さい。)

   マウスポインタを画像に合わせてPicoの中を覗いてみましょう!

ボタンクラスの初期化メッソード

以下に、ボタンスイッチクラスメッソードを示します。
チャタリング対策や長押し判定等の為、初期化では他にも処理がありますが公開するのはエッセンスのみです。
補足を列挙します。

1.pullupとpulldownは、クラス変数でbool型です。
2.gpioは、クラス変数でuint型使用するGPIOのポート番号が入っています。
3.gpio_init()関数はSDKで用意されている関数です。
4.gpio_set_dir()関数もSDKで用意されている関数です。
5.gpio_pull_up()関数、gpio_pull_down()関数も同様です。

ライブラリを組込んで3関数呼ぶだけで、sw入力初期化終了
後は、入力状態を用意されたSDK関数で状態を確認するだけです。


/*!
 * @brief ボタンSWの初期化
 * @fn             bool     initiate();
 * @return         GPIOポートの初期化状態(true : 成功、 false : 失敗)
 * @author         M,H
 * @date           2024/09/20
 * @version        1.00
 * @detail         予め設定済みのGPIOポートをスイッチ入力用に初期化する。
 *                 プルアップまたはプルダウンの指定があれば設定する。
 *                 pullup == true かつ pulldown == true の場合は
 *                 同様に初期化処理はせず falseを返す。
 * @par            History
 *   2024/09/20    新規作成
 */
bool
__no_inline_not_in_flash_func(button::initiate)()
{
    if(pullup &&  pulldown) return false; /*! プルダウン/アップ両方ON、初期化せず終了。*/
    gpio_init(gpio);			  /*! ポートを初期化する。		         */
    gpio_set_dir(gpio, GPIO_IN);	  /*! ポートを入力に設定する。	         */
    if (pullup) {			  /*! プルアップ指定があれば、	         */
        gpio_pull_up    (gpio);		  /*! ポートをプルアップに設定する。          */
    } else if (pulldown) {		  /*! プルダウン指定があれば、	         */
        gpio_pull_down  (gpio);		  /*! ポートをプルダウンに設定する。	         */
    } else {				  /*! 両方の指定がない場合は、	         */
        ;				  /*! なにも設定しない。		         */
    }
    return true;
}

注1: メッソードに見慣れない__no_inline_not_in_flash_func()がありますが、関数をFLASH ROMに置かない設定です。   開発物が随時ROM に状態記録する為、そういう設定にしています。

2.3 Lチカなんて本体だけで実現できる

 膨大な公開されているサンプルプログラムがあるので、開発環境を構築して
そのサンプルをビルドするだけで、Lチカみんな大好き実現できます。
そんなこと書くと元も子もないので、ボタンスイッチと同様にC++クラスにまとめました。
初期化メッソードのみですが参考まで。

LED出力初期化メッソード

以下に、LED出力クラスメッソードを示します。

1.stateは、クラス変数でbool型です。trueでOn、falseでOffです。
2.gpioは、クラス変数でuint型使用するGPIOのポート番号が入っています。
3.gpio_init()関数はSDKで用意されている関数です。
4.gpio_set_dir()関数もSDKで用意されている関数です。
5.gpio_put()関数は、出力値を設定します。

ライブラリを組込んで3関数呼ぶだけで、LED出力初期化終了です。
後は、出力値をgpio_put()関数で状態を変更するだけです。


/*!
 * @brief LED出力の初期化
 * @fn             bool     initiate();
 * @return         GPIOポートの初期化状態(true : 成功、 false : 失敗)
 * @author         M,H
 * @date           2024/09/20
 * @version        1.00
 * @detail         予め設定済みのGPIOポートをLED出力用に初期化する。
 * @par            History
 *   2024/09/20    新規作成
 */
bool
__no_inline_not_in_flash_func(led::initiate)()
{
    gpio_init(gpio);                        /*! ポートを初期化する。		*/
    gpio_set_dir(gpio, GPIO_OUT);           /*! ポートを出力に設定する。		*/
    state = false;                          /*! 初期値はOFFに設定する。		*/
    gpio_put(gpio, state);                  /*! ポートを設定値にする。		*/
    return true;
}


注2: LEDには制限抵抗入れて下さい。もちろんGP25は、ピコ内臓LEDポートなので何も必要ないです。

2.4 日本語ドキュメントが公開されている


 ラズベリーパイホームページで公開されているドキュメンに日本語版がある。
少し情報が古かったりするので英語版参照必須ですが、ピコ使う人日本人が多いのでしょうか。


3.Flashメモリを使いこなす

 今回、開発要件で随時状態を記録し電源OffからOnとなった際に前回の状態を保持する必要がありました。
バックアップ用に電池を付け、ピコの状態をDormantにする等で対応するのには巨大バッテリを用意しない限り無理でした。
そこで、Flashメモリに必要な情報を記録し、電源On時にその情報を確認検証することで対応することにしました。
技術的に非常に重要なものですので、概要だけ公開します。

  1. 容量は16Mbitで32ブロックです。プログラムもここに先頭から書き込まれます。
  2. ブロックは、4kbytesのセクタに分かれていますので、1ブロック16セクタです。
  3. Flashメモリの消去は、セクター単位でしかできません。
  4. データの書込みは256bytes単位で書き込めます。
  5. Flashメモリを操作している間は、その他(割込みを含む)のソフトからアクセスしてはいけません。
  6. Flashメモリを操作中でも、電源Offする場合があります。(システム構成に依存します。)

SDKは用意されていますので、上記特性を理解した上で適切なソフト構成、データ構成を設計します。
今回貴重なノウハウを得ることができましたのでハードを含めたピコのソフト開発は、ぜひ弊社にご相談下さい。


4.コンパイルからソフトインストールまで

 ソフトウエアを公開できませんが、開発の状況を確認して頂く動画を作成しました。
1つ目は、開発環境でのビルドする動画です。
2つ目は、バイナリをピコにインストールして動作させる動画です。
公開できる範囲に絞っていますので、ボタン入力機能は使用していません。
ただのタイマー(カウントアップ)のみですが、Lチカみんな大好きは本体で実現できますので動作確認できます。
全て一人で撮影した(片手にiPhone)ので、細々ご容赦下さい。
また、タイマーの出力には電子ペーパーを使用しています。電源か切れても表示が消えません。

今回のものとは異なりますが、電子ペーパーは、最近家電屋さんの値段のタグに使用されてます。
今回使用したものは中国メーカーのWaveshareという会社です。
詳細は下記URLでご確認下さい。

https://www.waveshare.com/wiki/Pico-ePaper-2.66#RPi_Pico

4.1 開発環境ビルド動画

 画像が鮮明ではないのでよく分からないかも知れません。
以下の手順をしてバイナリを作成しています。

  1. ターミナルを開きます。
  2. cdコマンドで開発環境ディレクトリに移動します。
  3. まだMake環境を整備していない場合はcmakeを実行してMakefile等を生成します。
  4. makeコマンドでコンパイル&リンクをします。
実際の開発環境整備にはもう少し手順がりますが、開発環境比較の参考資料の通りに実施すれば良いです。

4.2 インストール及び実行動画

 Timer.uf2というファイルをピコにコピーして実行ファイルをインストールします。
インストールが終了するとリセットがかかり、そのまま自動実行します。

  1. Raspberry Pi PicoのBOOTSEL白いボタンを押下したままにします。
  2. ダウンロード元PCとRaspberry Pi PicoをUSBで接続します。
  3. PC上にRaspberry Pi Picoドライブがマウントされます。
  4. そのドライブにインストールしたい*.uf2ファイル(今回はTimer.uf2)をコピーします。
  5. コピーが終了しインストールが完了すると、自動実行します。
このサンプルプログラムは、ピコ本体のLED点滅と電子ペーパーへのタイマカウント表示をします。

以上です。