ちょっとTea Time!? PICOの開発環境を揃える(備忘録) 2022.7.10

PICOに触れたのはちょうど1年くらい前. 面白く動かすところまではやったけど、
結局中途半端のままだなあ〜. 3個目のPICOも結局のところ、封もあけずに部品箱の肥やしになっています.
 でも、最近またふと考えるところもあり使って見ようかと思っていますが、なにぶん1年前の
ことなのでほとんどが忘却の彼方です. ということで、もう一度PICOが使えるように環境整備を行います.

今度は忘れていいように、ちょっと備忘録として丁寧(?)に書いておきましょう.

そして、RasPiのOSもいつの間にか64Bit版になっているのでそれをつかってみたいと思います.
使うRasPiは遊休中の3Bです. 4Bもありますが、すにでAD/DAを組み込んだ計測器と化しているので
下手にOSを変更して動かなくなると嫌なので、そのままにしておきます.

部品箱の肥やしになっている3個目のPICO。まあ、部品みたいなものだけど・・・・


遊休しているRasPi3B+をPICO開発用に再構築です。SDカードには
VOLUMIOが入っていたののでOSから入れ替えです。


1.64BitOSとPICO開発ツールのインストール
以前のRasPiのOSをインストールしようとしたら巨大なファイルをダウンロードしてから、
SDカードに書き込むという操作が必要でしたが、今はimagerというソフトがあって、
これを起動すればOSとストレージを選べば、OSをSDカードに直接書き込んでくれるようです。
便利になりました。


imagerというソフトでOSが簡単にSDカードに書き込めます。

でも、ここからが長かった。 まずSDカードを差し込んでRasPiを起動するとセットアップの画面がでてきます。
使用する国等を選択したのち、ソフトのUPDATEが始まりますが、これがやたら長い!
思わずフリーズしたかと思うような感じですが、画面を見ていると亀のごとく進んでいます。
もう放置プレーです。

こんな画面でOSのセットアップが始まります。


UPDATEはやたらめったら時間がかかります。1時間くらいかかった?

やっと、OSのインストールが終わって使えるようになりました。

PICOの開発環境のインストール

LINUXは全然詳しくないので、他のHPを参考にして、コマンドウインドを開いてほぼ呪文をそのまま打ち込みます。

$ wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh
$ chmod +x pico_setup.sh
$ ./pico_setup.sh

なにやら、PICOのソフトをダウンロードして展開し始めました。
でも、これも長い!やたら長い! 体感で1時間以上かかっているような感じです。
インストールの途中でスクリーンセーバが動いて画面が真っ暗になりますが、不安になるので
そのたびにマウスを動かして、インストールが動いているかどうかを確認です。でも、なんども繰り返すうちに
これまた放置プレーになって、Netflixをみていました。ひょっとして寝落ちもしたかな〜?


PICOの開発環境をインストールです。これも長い! もう寝てしまいそう・・・・

ようやく、OSとPICOの開発環境がインストールできました。ふう〜
LINUX系のソフトってどうして、こんなにインストールに時間がかかるのだろう?
ソースレベルでダウンロードしていちいちコンパイルするからかなあ〜。まあ、その方が
機器差が吸収出来るのでいいかもしれませんが、それにしても長いわあ〜。


ようやくPICOの開発環境が整いました。

2.新規のプログラムを作成できるようにする

WEBをくぐると、大体はすでにあるLチカのプログラムを動かして終わりとなっているのが多いですが、
新しいプログラムを作るときにどうするかがよくわかりません.で、色々とたぐって断片的な情報を
つなぎあわせです. 決して正しくはないとは思いますが、まずはこれでできそうです.

1)ディレクトリ作成
 新しいプログラムは新しいディレクトリに作成します. ここではpico_tempという名前で
ディレクトリとして作ります. 作成するのは2箇所です.

 pico/pico-example/pico_temp    ここはソースが入る場所
 pico/pico-example/build/pico_temp    ここは実行ファイルが入る場所

2)環境整備?
ディレクトリを作ったら、下記のファイルを編集です.
 pico/pico-example/CMakeLists.txt

CMakeLists.txtのテキストの一番最後にpico_tempをadd_subdirectoryとして加えます.


新しく作ったディレクトリのうち、ソースファイルのあるpico/pico-examples./pico_tempの
ディレクトリに2つのファイルをおきます.
  CMakeLists.txt
  temp.c   
    

どちらのファイルも他のプログラムから適当にコピペです.そして、CMakeLists.txtを編集です.
実行ファイルを格納するディレクトリ名とソース名を書き込みます.これはひな型を書き換えるだけです.

add_executable(pico_temp
   temp.c
  )

# pull in common dependencies
target_link_libraries(pico_temp pico_stdlib)

# create map/bin/hex file etc.
pico_add_extra_outputs(pico_temp)

# add url via pico_set_program_url
example_auto_set_url(pico_temp)

準備ができたら、pico/pico-example/build のディレクトリに戻って
下記の呪文を実行です. exportは一度するだけでよいようです.

$ export PICO_SDK_PATH=../../pico-sdk
$ cmake ..

これで準備完了です. build/pico_tempの中には色々なファイルが生成されます.

3)実行ファイルの作成
実行ファイルを生成するのはpico/pico-examples/build/pico_temp のディレクトリに移ったあと
下記の呪文を唱えます.

$make -j4

makeは一度目は結構な時間がかかりますが、2回目以降は早く終わります.
もちろん、ソースにエラーがあるとエラーメッセージがでてきます.
これでpico_temp.uf2なる実行ファイルが出来上がります.

あとはPICOに転送するだけです.

3.PICOの基本的な関数を整理 2022.7.12

基本的にはGPIOのIN/OUTだけなんとかなれば、大体のことはできるので
下記をみればわかるはずです(超手抜き。

全体はここ Raspberry Pi Pico SDK: API Documentation
GPIOに関する部分 Raspberry Pi Pico SDK: hardware_gpio

SDKを覗いていると、どうやら周波数カウンタの機能もあるようです。計数カウンターがないなあ〜と思っていましたが、
これを使えば大丈夫そうです。でも、使い方というか使えるまでの呪文を探すのに苦労しました。

1)周波数カウンタを動作させる
 I/Oポートに入力されるクロックの周波数を計数するためにはちょっとした呪文が必要です。
まず、使えるGPIOは20,21でそれぞれがGPIN0,GPIN1に定義されています。
そして、GPIN0(GPIOの20)を周波数計測の入力として使うには、まず下記の呪文が必要です。

gpio_set_function(20,GPIO_FUNC_GPCK);

そして、そのあとは周波数カウンターのサブルーチンを呼び出すわけですが、
引数にも長い呪文が必要です。

freq = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLKSRC_GPIN0);

これらは、ファイルを探し回ってみつけてきました。ふう〜疲れた!
でも、これでいままでPICでやっていたことがほとんどPICOでも実現できそうです。


周波数カウンタを動かすためには、動作確認ができるようにLCDを取り付けました。



24.576MHzの水晶発振器を計測したら24576という値がでてきました。


周波数カウンタの動作速度を調べると1kHzのようです。どうやら1ms時間でのクロック数を計数しているようです。
だから誤差が±1kHzということなんですね.

2)プルアップ抵抗はどれほど?

PICOのI/Oはすべてプルアップの指定ができます. プルアップ抵抗はどの程度か気になります.
というのも、あまり低いプルアップだとLOWレベルにしたときに電流が流れ過ぎるので、接点容量の
小さいエンコーダなんかは故障してしまう可能性があります. 小さいエンコーダだと接点電流が
0.5mA以下と小さいのものもあります.この場合でプルアップ抵抗はおよそ7kΩ以上が必要です.
で、調べてみるとおよそ30kΩでした. まあ、一般的なプルアップ抵抗の値でよかったです. 

3)ADCを動かしてみよう.

あれ?動かない-----,
adc_read()を実行したらフリーズしてしまう・・・なぜ?
こまった時のWEB頼みでです. 色々と調べると呪文が必要なことがわかりました.

呪文1
どうやらライブラリにhardware_adcnなる呪文を追加する必要がありました.
CmakeLists.txtを修正です. なくてもリンクは終了したんだけどな〜

# pull in common dependencies
target_link_libraries(pico_glcd128064
  pico_stdlib
  hardware_gpio
  hardware_adc
  )


呪文2
ソースのヘッダーに下記の呪文も必要でした.
#include "hardware/adc.h"

とりあえずこれらの呪文を唱えれば動きました.
ほんと、面倒くさいな〜.


とりあえず動きました.10kHzの正弦波を入れていますが3.25波くらい入っているので
変換速度は配列への代入を含めて5usくらいかな.

4)インターバルタイマ割り込みを動かす

これについては、以前に調べたものでよかった。
でも一つ落とし穴がありました。

#include "pico/stdlib.h"
#define GPIO_00 ( 0 )

bool timer_callback( repeating_timer_t *rt )
{
 // ここに割り込みプログラムを書く
 return ( true );
}

void main( void )
{
 static repeating_timer_t timer;
/* GPIO設定 */
 gpio_init( GPIO_00 );
 gpio_set_dir( GPIO_00, GPIO_OUT );
/* インターバルタイマ設定 */
 add_repeating_timer_ms( -2, &timer_callback, NULL, &timer );
 while( true )
 {
  // とりあえずループ
 }


割り込みルーチンの中でディレイ関数としてsleep_us()やsleep_ms()を使うと
フリーズしてしまいました。その代わりにbusy_wait_us_32()、busy_wait_ms()を
使う必要があるようです。 sleepとbusy_waitの違いは、どうやら前者が
ローパワー状態になって”寝る”のに対して、後者は”忙しく空回り”という
感じらしい。すなわち、寝てしまうとインターバルタイマなんかも寝てしまうのかもです。
知らんけど・・・・・。
 とりあえずは動く関数を使うようにしましょう。

5)フラッシュメモリを読み書きする!

PICのEEPROMの代替としてPICOのフラッシュメモリーをつかった記録を
試してみましょう。 以前に検討したときは、そもそも関連するサブルーチンが
リンクできなくて( お気楽オーディオキット資料館 (fc2.com) )、頓挫しましたが
この辺は解決できそうです。

まず、コンパイル&リンクを正常に行うためにCMakeLists.txtに呪文を追加です。
下記のhardware_flashを追加です。

add_executable(pico_glcd128064
  temp.c
  )

# pull in common dependencies
target_link_libraries(pico_glcd128064
  pico_stdlib
  hardware_gpio
  hardware_adc
  hardware_flash
)

# create map/bin/hex file etc.
pico_add_extra_outputs(pico_glcd128064)

# add url via pico_set_program_url
example_auto_set_url(pico_glcd128064)


ほぼサンプルプログラム通りを書き込んで動作することが確認できました。
定数の値も表示させてみましたが、フラッシュメモリの消去はセクターサイズ(4096byte)
毎で、書き込みサイズはページサイズ(256Byte)毎になります。
書き込まれる位置はフラッシュメモリの開始アドレス(0x100000000)からオフセット(0x40000)
のポジションになります。オフセットについてはプログラムサイズより大きな値を設定すれば
いいのでしょう。普段作る程度のプログラムであればオフセットに256kByteもとれば
十分なような気がします。でも、フラッシュ自体は2MBありますから、定常的にオフセット値は
1MBあたりに設定しておいてもいいかもしれません。


フラッシュメモリへの書き込みもできました。

これで、普段のプログラムで使う機能はほぼ網羅できました。
で、何をしようとしているかといえばPICをPICOに置き換えてみようかと
思っています。

PICO→PICの変換ソケットを作ってみる

プログラムとしてはほとんどがI/Oをビット操作をしているので、28PinのPICとくらべてI/.O数が
多いPICOに置き換えることは容易です.ただ、カウンターやAD入力など特定機能に割り当てられる
I/.Oもあるのでそれらに注意して変換する必要があります.それらさえ気を付ければ、あとは
配線がしやすいようにPICとPICOのピン間つなぐだけです. 

ピン間の接続は下表のようにしてみました.

PICO PICのピン PICO
1 E0 B7 28 GP2
GP26 2 A0(AN0) B6 27 GP3
GP27 3 A1(AN1) B5 26 GP4
GP28 4 A2(AN2) B4 25 GP5
GP22 5 A3 B3 24 GP6
GP21 6 A4 B2 23 GP7
GP19 7 A5 B1 22 GP8
8 Vss B0 21 GP9
GP18 9 A7 VDD 20
GP17 10 A6 Vss 19
GP20 11 C0(T1CK) (RX)C7 18 GP1
GP16 12 C1 (TX)C6 17 GP0
GP15 13 C2 C5 16 GP10
GP14 14 C3 C4 15 GP11


見た目はよくありませんが、変換ソケットです.

PICは3.3Vで動かすことがほとんどですが、PICO自体は5V供給なのでメーカの推奨回路どおり
VSYSにショットキーダイオードを介して電源を供給します.


USBからの電源との衝突を防ぐために外部給電はショットキーダイオードを介して行います.


これを5Vラインに接続して使用します.

(つづく、かな?)