Raspberrypi pico（ラズパイピコ）を MicroPython でペリフェラル制御する。

## はじめに
　Raspberrypi pico（ラズパイピコ）を MicroPython で動かすための、環境構築～ペリフェラル制御をまとめる。
Raspberrypiでのペリフェラル制御は別記事の下記参照。

 https://qiita.com/tapitapi/items/db16b106c54a66c49606
 

## 目次
- [RaspberryPiPicoとは](#raspberrypipicoとは)
- [MicroPythonとは](#micropythonとは)
- [初期設定ファームウェア書き込み](#初期設定ファームウェア書き込み)
- [開発環境Thonny](#開発環境thonny)
- [rshell](#rshell)
- [ペリフェラル制御 (GPIO/I2C/SPI/UART/ADC)](#ペリフェラル制御)
- [コードサンプル](#コードサンプル)



## RaspberryPiPicoとは
　組み込み開発に特化したラズベリーパイ。1000～2000円程度で購入可能。Amazonでも販売されている。264kBの内臓RAMと、16MBのFlashを搭載している。C言語、MicoroPythonでも開発できる。GPIO /I2C /SPI /UART /ADCのペリフェラルと、3.3Vの出力も備えており、これ一つで、様々な電子デバイス制御をすることができる。
　タイプは2個あり、無線LANなしの「Raspberry Pi Pico」、無線LANありの「Raspberry Pi Pico W」が販売されている。この記事では、無線LANなしの「Raspberry Pi Pico」を「MicroPython」で動作確認した内容をまとめる。公式サイトは下記。

https://www.raspberrypi.com/products/raspberry-pi-pico/

[戻る](#目次)

## MicroPythonとは
　MicroPythonは組み込み機器上で動作させることのできるPython。C言語のようなコンパイルが不要なので、サクッとスクリプトを書いて、すぐに動作確認をできるのがメリット。標準で、GPIO/I2C/SPI/UART/ADCなどのペリフェラル制御用のAPI(関数)が用意されていて、電子デバイス制御も簡単にプログラミングすることができる。
　ただし、C言語でコーディングしたソフトよりリアルタイム性は損なわれる。MicroPythonで作成したソフトでGPIO制御させたとき、msオーダで誤差が生じていた。1ms以下のリアルタイム性が必要なデバイス制御をする場合、また、デバイスマニュアルを片手にいろいろとチューニングしたい場合は、C言語でコーディングする方がよいと思う。

https://micropython.org/


[戻る](#目次)

## 初期設定ファームウェア書き込み
　MicroPythonでラズパイピコを使う場合、まず最初にBoot用のファームウェアuf2ファイルを書き込む必要がある。下記手順で、ダウンロードしたuf2ファイルをドラッグアンドドロップで書き込みできる。
1. 下記公式サイトから uf2 ファイルをダウンロード
https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/863a4ffb-f621-1037-9b5f-3af2de64aed6.png)
1. ラズベリーパイピコのBOOTSELLボタンを押しながらPCにUSB接続するとストレージとしてPCが認識。
1. ダウンロードしたuf2ファイルをドラックアンドドロップで保存。これで初期設定完了。



[戻る](#目次)



## 開発環境Thonny
　ThonnyはPythonの統合開発環境。Pythonスクリプトをコーディングし、Pythonスクリプトをラズパイピコに書き込むまでの一連の操作をこれ一つでできる優れもの。

https://thonny.org/

**①インストール後、ラズパイピコを使えるように初期設定をする。**
・ラズパイピコを接続してThonnyを起動
・[ツール]→[オプション]→[インタープリタ]で設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/d0231905-4bf3-3875-d730-b4a52e2d5071.png)


**②ファイルエクスプローラを開く**
・[表示]→[ファイル]
・PCとラズパイピコのファイル構成が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/661ddc7b-1240-4e8e-2797-138cf09a1963.png)


**③書き込み削除など**
・ファイルエクスプローラの"Rapberry Pi Pico"の領域で右クリックをして対象の操作をする。
・ファイルの追加、削除ができる。また、ファイルを選択するとファイルの編集も可能。
・新規ファイル作成時は、保存時にファイル作成される。ただし空ファイルは無効。
・注意点として、メイン文は ```main.py``` にする必要がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/faeadf64-8b49-f021-5381-9fc24d8bbf2c.png)



**④PC⇔ラズパイピコ間のファイル転送**
PC→ラズパイピコ
・PC側のファイルエクスプローラからラズパイピコへ転送したいファイルを右クリック。
・[/をアップロード]でファイル転送。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/2e302b60-af3a-646c-9feb-f003ad75cc1a.png)


ラズパイピコ→PC
・ラズパイピコ側のファイルエクスプローラからPCへ転送したいファイルを右クリック。
・[ダウンロード中..]でファイル転送。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/e914b492-37da-2e31-debe-5703e624406b.png)


[戻る](#目次)

## rshell
　Thonnyを使わず、CUIでラズパイピコを制御したい場合はrshellという手段もある。コマンドプロンプトでラズパイピコを制御、Pythonスクリプトのファイル書き込みをすることも可能。
rshell は下記方法でインストール。
```
python -m pip install --upgrade pip
pip install rshell
```
その他基本操作をまとめる。

**①起動**
picoをパソコンにつないだ状態で、コマンドプロンプト起動。```rshell```を打つ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/957ede2a-b4e0-009b-765e-13aa2a999cfb.png)

**②書き込み**
```/pyboard```がラズパイピコの書き込み先。```cp```で書き込み可能。

::: note warn 
書き込みがうまくいかない場合はufsとrshellの組み合わせがよくない？
:::

例)```cp -r ./* /pyboard/```現在のフォルダ配下のものをすべてコピー。```*```が使えない場合は、親階層から一つづずコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/9469081e-8395-8df6-36b0-23f1a8ae6c2e.png)

**③動作確認**
```repl```
```Ctrl+D``` で再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/c2eab9ad-854e-6e5c-1920-8f9971df5989.png)

[戻る](#目次)

## ペリフェラル制御
　ペリフェラルGPIO/I2C/SPI/UART/ADCの使い方をまとめる。I2C/SPI/UARTは通信時、bytearray型を扱うが、bytearray型と各種型への変換は下記記事を参考に。

https://qiita.com/tapitapi/items/e8ea6eb9b23785c42f8f

GPIO/I2C/SPI/UART/ADCの使い方はこのあたりも、参考に。

https://micropython-docs-ja.readthedocs.io/ja/latest/index.html

ラズパイピコのポート一覧は[こちら](#ポート表)


[戻る](#目次)

### GPIO
　GPIOは、ポート出力(High 3.3V /Low 0V)、ポート入力値の取得、ポートの割り込みを検出ができる。LEDを光らせたり、ボタンやスイッチの状態を取得する時などに使う。ポートの割り込みを使えば、ボタンを押された瞬間を検出することもできる。
　Pinをimport必要。ラズパイピコはGP25がLEDとつながっているので、GP25をポート出力設定にしてHigh/Low制御すると、LEDを点滅させることができる。

```Python:GPIO
from machine import Pin

#GP25ピンを、Out設定で、gpio25 に設定した値が出力される。
gpio25 = Pin(25, Pin.OUT)
gpio25.value(0) #Low入力
gpio25.value(1) #High出力
gpio25.toggle() #現在の反対値を出力

#GP22ピンを、In設定で、gpio22 に値が入る。
gpio22 = Pin(22, Pin.IN)
print(gpio22.value())

#GP4ピンを、割り込み設定で、gpio4を内蔵プルアップ設定、Lowが入力さるとgpio_callback()がコールバックされる。
def gpio_callback(pin):
    print(pin)

gpio4 = Pin(4, Pin.IN, Pin.PULL_UP)
gpio4.irq(trigger=Pin.IRQ_FALLING, handler=gpio_callback)
```
[戻る](#ペリフェラル制御)



### I2C
　I2Cは、組み込みデバイスを制御するときに使う通信手段。通信速度は数100kbps程度。組み込みデバイスのアドレスを指定して通信を行う。
　Pin,I2Cをimport必要。2系統(0/1)準備されている。内蔵プルアップ有無を設定できるので便利(無し設定は```Pin.PULL_UP```を記載しなければ良い)。I2Cラインに既にプルアップ抵抗がある場合は、内蔵プルアップをなし設定にする。
```Python:I2C
from machine import Pin,I2C

#I2C 0系統をOpen
#scl(クロックライン)=GP9、sda(データライン)=GP8、通信速度=100kHzで設定。
#SCL,SDAラインを内蔵プルアップ有り設定。
i2c0 = I2C(0, scl=Pin(9,Pin.PULL_UP), sda=Pin(8,Pin.PULL_UP), freq=100000)

#I2C write
#addrアクセス先アドレス。buffにデータ列、bytearray型で設定。
i2c0.writeto(addr, buff)

#I2C read
#addrアクセス先アドレス。sizeは読み出しサイズ。buffへデータがbytearray型で格納される。
buff = i2c0.readfrom(addr, size)
```
[戻る](#ペリフェラル制御)




### SPI
　SPIは、組み込みデバイスを制御するときに使う通信手段。通信速度は数Mbps程度。高速通信が可能。1対1で通信することが多いが、チップセレクトを使えば、デバイスを指定して通信することもできる。
　Pin,SPIをimport必要。2系統(0/1)準備されている。
```Python:SPI
from machine import Pin,SPI

#SPI 1系統をOpen
#scl(クロックライン)=GP10、mosi(送信ライン)=GP11、miso(受信ライン)=GP12、通信速度=1Mbps、8bit単位通信
#通信しないときの極性(polarity)=1、通信取り込みエッジ(phase)=1
spi1=SPI(id=1, sck=Pin(10), mosi=Pin(11), miso=Pin(12), baudrate=1000000, bits=8, polarity=1, phase=1)

#SPI送信 buffはbytearray型
spi1.write(buff)

#SPI受信 sizeが読み出しサイズ。 読み出したデータはbuffへ格納、buffはbytearray型
buff=spi1.read(size)
```
[戻る](#ペリフェラル制御)




### UART
　UARTは、組み込みデバイスを制御するときに使う通信手段。また、USBシリアル変換アダプタ経由を使えば、PCとの通信もできる。
　Pin,UARTをimport必要。2系統(0/1)準備されている。
```Python:UART
from machine import Pin,UART

#UART 0系統をOpen
#GP0=Tx、GP1=Rx、通信速度=38400bps
uart0=UART(0, tx=Pin(0), rx=Pin(1), baudrate=38400)

#UART送信 buffはbytearray型
uart0.write(buff)


#UART受信 sizeが読み出しサイズ。 読み出したデータはbuffへ格納、buffはbytearray型
buff=uart0.read(size)
```
[戻る](#ペリフェラル制御)




### ADC
　ADC(A/Dコンバータ)は、アナログの電圧値を読み取り、デジタルデータに変換する機能。Pin,ADCをimport必要。4系統のADCがある。4はラズパイピコの内臓温度センサーにつながっており、温度を取得することができる。
```Python:ADC
from machine import Pin,ADC

#ADC 4 をOpen
adc4=ADC(4)

#ADC 4の値を読む 16bit(0～65535)の値を読む
adc4.read_u16()

#℃変換
def temperature_picoadc(adc):
    volt = adc * (3.3/65535)
    temp = 27 - (volt -0.706)/0.001721
    return temp

volt=adc4.read_u16()
print( volt, '{:.2f}℃'.format( temperature_picoadc(volt) ) )
```


[戻る](#ペリフェラル制御)




### ポート表
PINはラズパイピコのピン番号。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/3c314493-61c4-2081-66e9-331789ba153f.png)
[戻る](#ペリフェラル制御)


## コードサンプル
　ラズパイピコのコードサンプルを作りました。

https://github.com/Titan365/pico_peripheral_sample

[戻る](#目次)