MicroPythonを使ってみる（その１：LCD制御）

# ESP32にてMicroPythonを使ってLCD制御
組み込みソフトウェア開発にMicroPythonを用いるのはトレンディの一つ。Pythonをまともに使ったことがなかったので、LCD制御を題材にトライ。

## 使ったもの
- 秋月電子などで売られている[ESP32 DevKitボード](https://akizukidenshi.com/catalog/g/gM-15674/)
- IO Expander PCF8574を搭載した、20x4 LCD。例えば、[これ](https://www.amazon.co.jp/HiLetgo®-キャラクタ-LCDディスプレイ-インタフェース-並行輸入品/dp/B010SHNMW2/ref=asc_df_B010SHNMW2/?tag=jpgo-22&linkCode=df0&hvadid=210048980331&hvpos=&hvnetw=g&hvrand=2181937791919576613&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009343&hvtargid=pla-441284818448&psc=1)。
- 5Vを供給するためだけのArduino（使用するLCDが5V駆動のため）

## ESP32でのMicroPython開発環境
環境構築には、[こちらのサイト](https://wak-tech.com/archives/1008)などを参照した。また、ESP32用のMicroPython Firmwareは、[本家サイト](https://micropython.org/download/esp32/)にある次のもの
- [esp32spiram-20210902-v1.17.bin](https://micropython.org/resources/firmware/esp32spiram-20210902-v1.17.bin)
を利用。

まず、各種ツールをインストールする。

#### Python
WindowsにてPythonをインストール。詳細略。

#### コマンド系ツール
MicroPython FirmwareをESP32に書き込むためのesptoolをpipにてインストール。

```
> pip install esptool
```

コマンドラインから、プログラムを操作するampyをインストール。（オプション）

```
> pip install adafruit-ampy
```

#### uPyCraft IDE
GUI上で、FirmwareやProgramの書き込みを行うアプリケーション。今回はこれを多用。[ここから](https://randomnerdtutorials.com/uPyCraftWindows)ダウンロードできる。

## uPyCraft操作
### ESP32用MicroPython Firmwareの書き込み
![BurnFirmware1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/bf7ae023-54b7-8fde-d3cf-88f2a0a7b5f8.png)
「BurnFimrware」を選ぶと、
![UpdateFirmware.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/947a069e-dd98-f37f-85a2-4be04d60b9a5.png)
または
![WriteFlash.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/a7f5a19c-8b5d-494b-508c-53a0fb5579a3.png)
が表示されるはず。ここでは、すでに”choose”をクリックして書き込むFirmwareを選択済みとなっている。burn_addrは0x1000、COMポートを確認して、OKで書き込み。すると、
![初期状態.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/5c96460f-2dba-921a-0199-1a584c954bf8.png)
となる（boot.pyが見える）。また、uPyCraftを再起動したときは、適切なCOMポートを選択する。
![シリアルポート選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/964d1f9f-3d2a-ccc3-dc50-15df6ce90295.png)

## LCD制御
IO Expander PCF8574を搭載したLCDをMicroPythonから制御する。[このサイト](https://techtotinker.blogspot.com/2021/01/008-micropython-technotes-16x2-lcd.html)にあるコードをほぼそのまま利用。

### LCD APIおよびI2Cライブラリのインストール
上記サイトにある「lcd_api.py」および「i2c_lcd.py」をそのままCopy&Pasteしてファイル化する。これらをuPyCraftでOpenし、ESP32に書き込む（Downloadをクリック）。
![Download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/eb313047-03e7-42cf-a7d8-cf03acaa1010.png)
両ファイルのDownload後には次のようになる。
![Downloadあと.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e484a359-cf0a-a1c0-6f63-081f9042673c.png)

### サンプルコード
次に先ほどのサイトのを参考にコードを作成。

```python:LcdTest.py
from time import sleep_ms, ticks_ms 
from machine import I2C, Pin 
from i2c_lcd import I2cLcd 

I2C_ADDR = 0x27
COLUMN = 20
LINE = 4

i2c = I2C(scl=Pin(22), sda=Pin(21), freq=400000) 
lcd = I2cLcd(i2c, I2C_ADDR, LINE, COLUMN)

lcd.clear()
lcd.putstr('LCD TEST')
sleep_ms(3000)
count = 0

while True:
    print('Counter: {}'.format(count))
    lcd.clear() # Clears the LCD,
                # Sets the cursor position to 0,0 
    lcd.putstr('Counter: {}' .format(count))
    lcd.move_to(count%10+2, 1)
    lcd.putstr('Wait ...')
    lcd.move_to(count%10+4, 2)
    lcd.putstr('.....')
    lcd.move_to(count%10+6, 3)
    lcd.putstr('Soon')
    count = count + 1
    sleep_ms(1000)
```
ESP32のI2Cのピン（SCL:22, SDA:21）を設定し、LCD（PCF8574）のI2Cアドレスはデフォルトの0x27、20列および4行を設定する。このファイルをuPyCraftでOpenし、DownloadAndRunすれば実行できる。
![Download＆Run.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/55c749e9-e8ad-1b90-30e6-580f4621147e.png)

### 実行
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/bfad5766-af67-313e-2b1d-7a071243cace.png", width=80%>

## 備考
### LCD制御API
先ほどのサイトの情報から引用。

```
# 1. To print a string to the LCD:
#    lcd.putstr('Hello world')
# 2. To clear the display:
#	 lcd.clear()
# 3. To control the cursor position:
# 	 lcd.move_to(2, 1)
# 4. To show the cursor:
#  	 lcd.show_cursor()
# 5. To hide the cursor:
#	 lcd.hide_cursor()
# 6. To set the cursor to blink:
#	 lcd.blink_cursor_on()
# 7. To stop the cursor on blinking:
#	 lcd.blink_cursor_off()
# 8. To hide the currently displayed character:
#	 lcd.display_off()
# 9. To show the currently hidden character:
#	 lcd.display_on()
# 10. To turn off the backlight:
#	 lcd.backlight_off()
# 11. To turn ON the backlight:
#	 lcd.backlight_on()
# 12. To print a single character:
#	 lcd.putchar('x')
# 13. To print a custom character:
#	 happy_face = bytearray([0x00, 0x0A, 0x00, 0x04, 0x00, 0x11, 0x0E, 0x00])
#	 lcd.custom_char(0, happy_face)
#	 lcd.putchar(chr(0))
```

### uPyCraft
#### 実行中プログラムの強制Stop
![Program Stop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/7023b198-0d93-b10f-eb49-f2cee48496dc.png)

#### ファイルの操作
アプリケーションを右クリックすると各種操作が可能。下記はプログラム削除の選択。
![Delete.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/fe945446-86e9-2ec4-e046-049a7e62a8ca.png)

#### 起動（電源ON）時プログラムの選択
プログラムを選んで右クリックし、
![DefaultRun選択前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/ea782109-d1e2-a600-05de-96d85ea65614.png)

「Default Run」を選択する。すると、そのProgramが赤字表示となり、電源ON時に起動される「main.py」が作成される。
![DefaultRun選択後(main.pyができる).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/56d4343a-8eaf-354d-664b-4398f52779d9.png)