Raspberry Pi PicoでI2C通信

Raspberry Pi PicoでI2C通信を使ってLCD (液晶ディスプレイ) を動作させる。

# I2C通信について
この図のように１つのマスタとたくさんのスレーブの間を2つの線 (SDA,SCL) で結び，データのやり取りをする。
データのやり取りの権限はマスターが持っており,マスタが送信するクロック信号 (SCLから出る信号) を基準にしてデータ信号がSDAを通って送られる。
![スクリーンショット 2022-02-26 18.41.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231863/a1f06965-556a-766b-1ba7-7094b9e4b09d.png)
※I2C通信の参考文献は以下↓
http://www.picfun.com/c15.html


# Raspberry Pi Picoについて

ハードウェアは以下のように設定される。
![Pico-R3-A4-Pinout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231863/f3d87edf-2072-8256-6be7-bd51ccf6bdb9.png)
※画像引用元↓
https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html

# Raspberry Pi PicoをPC上で操作する
USB接続でPCとRaspberry Pi Picoを接続するとデバイスとしてRaspberry Pi Picoが認識される。以下のサイトをクリックするとサイトの真ん中あたりに**MiCroPython (Getting started with MicroPython)** があるのでそれをクリックする。
https://www.raspberrypi.com/documentation/microcontrollers/?version=E0C912952D54
![スクリーンショット 2022-02-26 19.36.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231863/eb142295-d123-f0e4-410f-2a67e97e811a.png)

クリックした先のサイトの下の方に行くと、以下のように **Download the MicroPython UF2 file.** があるので赤くなっている所をクリックしUF2ファイルをダウンロードする。
![スクリーンショット 2022-02-26 19.39.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231863/4411d86e-fd41-db08-ed6f-e3228c123605.png)
ダウンロードしたファイルをUSBメモリにデータを移行する感覚でデバイスとして認識されたフォルダに移動 (ドラッグ＆ドロップ) する。
するとRaspberry Pi Picoのフォルダが閉じられて、USBデバイスが外されたという表示になるが、これは正常な動作である。  

次に、一度PCとRaspberry Pi PicoのUSB接続を外し再び接続する。すると，先ほどとは違いデバイスとしてRaspberry Pi Picoが認識されなくなるが，問題はない。接続した状態のままにしておく。

Raspberry Pi Picoでプログラミングをする時は，Pythonを使用する。プログラミング及び, コンパイルには,**Thonny**というアプリケーションを使用する。
ダウンロードについては以下のサイトを開き、右上の **Download version~~~for~~~** からダウンロードする。
https://thonny.org
![スクリーンショット 2022-02-26 19.54.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231863/d032d977-bc8f-d348-ad93-95c19fe8c161.png)
ダウンロードしたファイルを開きインストールした後，**PCとRaspberry Pi PicoのUSB接続がされているのかを確認** してからアプリケーションを開く。
開いたのちウィンドウの右下の方にある文字列をクリックして **MicroPython (Raspberry Pi Pico)** にチェックを入れる。
![スクリーンショット 2022-02-26 20.02.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231863/58283a37-de1d-30fb-c17e-36ff2de5b7fa.png)
これでPCとの接続完了である。


 # Lチカ (LED点灯プログラム作成) で正常な接続の確認 
**Thonny** 上で以下のようなサンプルプログラムを作成する。

    from machine import Pin
    LED = Pin(25, Pin.OUT)
    LED.value(1)

RunボタンをクリックするとRaspberry Pi Pico上のボード上にはんだ付けされた緑のLEDが点灯する。
![スクリーンショット 2022-02-26 20.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231863/912a5c09-a8f2-b161-3ad2-3ffce43ebd04.png)
![スクリーンショット 2022-02-26 20.18.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231863/9f825ef8-0457-a5dd-3c7a-6ec55c6a8e0d.png)

# LCDとRaspberry Pi Picoとの接続方法について
LCDとRaspberry Pi PicoとのI2C接続及び，VCCとGNDを以下のようにする。
LCDのSDA-----Raspberry Pi PicoのGP0 (Pin番号:1)
LCDのSCL-----Raspberry Pi PicoのGP1 (Pin番号:2)
LCDのVCC-----Raspberry Pi PicoのVBUS (5Vを出力させるため)
LCDのGND-----Raspberry Pi PicoのGND (GNDと書かれたPinであればどこでもいい)

# I2C通信を活用してLCDに文字を表示
プログラムを作成する。なおこのプログラムは以下から引用している。
https://jhalfmoon.com/dbc/2021/05/17/micropython的午睡22-ラズパイpico、aqm1602-lcdパネル接続/

    import time
    from machine import Pin, I2C


    i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100)
    adrAQM1602 = 0x3E
    datAQM1602 = 0x40
    comAQM1602 = 0x00

    def writeDatAQM1602(dat):
        i2c.writeto_mem(adrAQM1602, datAQM1602, bytes([dat & 0xFF]), addrsize=8)
        time.sleep_ms(1)    

    def writeComAQM1602(com):
        i2c.writeto_mem(adrAQM1602, comAQM1602, bytes([com & 0xFF]), addrsize=8)
        time.sleep_ms(1)    

    def initAQM1602():
        time.sleep_ms(100)
        writeComAQM1602(0x38)
        time.sleep_ms(20)
        writeComAQM1602(0x39)
        time.sleep_ms(20)
        writeComAQM1602(0x14)
        time.sleep_ms(20)
        writeComAQM1602(0x73)
        time.sleep_ms(20)
        writeComAQM1602(0x56)
        time.sleep_ms(20)
        writeComAQM1602(0x6C)
        time.sleep_ms(20)
        writeComAQM1602(0x38)
        time.sleep_ms(20)
        writeComAQM1602(0x01)
        time.sleep_ms(20)
        writeComAQM1602(0x0C)
        time.sleep_ms(20)

    def writeLineAQM1602(nL, lin):
        buf = bytearray(lin)
        if len(buf) <= 0:
            return False
        if len(buf) > 16:
            buf = buf[0, 16]
        if nL == 0:
            writeComAQM1602(0x80)
        else:
            writeComAQM1602(0xC0)
        for idx in range(0, len(buf)):
            writeDatAQM1602(buf[idx])
        
    initAQM1602()
    writeLineAQM1602(0, "aaaaaaaaaaa")
    writeLineAQM1602(1, "bbbbbbbbbbb")