秋月のI2C接続有機ELディスプレイをラズパイ４に接続する

秋月で売ってる[有機ＥＬキャラクタディスプレイモジュール 20字x2行](https://akizukidenshi.com/catalog/g/gP-08279/)をRaspberry Pi4に取り付けて制御したメモ。

先人の記事のプログラム（参考文献）をもとに色々改良してみる。

# 組み立て
16文字版も20文字版もピンの形は違う(16文字は１列、20文字は２列）
が機能は一緒。接続は次のとおりとした。

|I2C側|ラズパイ側|備考|
|:--|:--|:--|
|1 VSS|7 GND|１−３で短絡|
|2 VDD|1 3.3V|２−４で短絡|
|3 /CS|7 GND|１−３で短絡|
|4 SA0|1 3.3V|今回はSアドレスは１に設定。|
|7 SCL|5 SCL| |
|8 SDAin|3 SDA|８−９で短絡|
|9 SDAout|3 SDA|８−９で短絡|

将来的な拡張（ディスプレイ２枚差し）と短絡（分岐）のやりやすさを考え、ラズパイからユニバーサル基板を経由してI2Cのディスプレイに接続するようにした。

![イメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214012/9c66ba4b-7ea3-4033-5748-e2985580cd36.png)

ラズパイからユニバーサル基板間はそのまま４本線を出して、
ユニバーサル基板上でI2Cのピンヘッダ用に分岐して、
ユニバーサル基板からI2C間は７本（[コネクタ付きコード３本](https://akizukidenshi.com/catalog/g/gC-15384/)、[コネクタ付きコード４本](https://akizukidenshi.com/catalog/g/gC-15383/)）で接続する形とした。

ちなみに、接続して電源いれても表示が変わらない（暗転のまま）なので
接続されているか不安になるが、気にしない。

# 必要なプログラムのインストール
I2Cを操作するためのsmbus(python3用）とpip、日本語変換用モジュール（後述）をインストールする。

``` 
sudo apt install python3-smbus python3-pip python3
sudo python3 -m pip install jaconv
```

補足：
smbusは管理者権限で動かす必要があるので、pipで入れるjaconvもrootユーザとしてインストールするため管理者権限でインストールする。

# プログラムの修正1
細かい動きの解説は先人の記事を参照。
ただ、このプログラムは16x2のプログラムで日本語（半角カナ）に対応していないため
20×2のディスプレイで再生＋日本語化対応のための修正

先人の[プログラム](https://gist.github.com/uhey22e/2a4d676363722d59428a937ac729def0)をダウンロードする。

20文字でも問題なく動作する様に22行目を`while (len(str) < 20):`に変更する。

半角カナでも対応できるように34行目を`self.bus.write_byte_data(self.addr, 0x40, int(str[i].encode('shift-jis').hex(),16))`に変更する。

今回のSA0は１にしているため、54行目を`oled = SO1602A(sa0 = 1)`にする。

補足：
元々のソースだとord関数を使ってました。
これだとUnicodeの番地を整数を返します。
半角英字（大文字小文字）については、このままでいいのですが、半角カナに限っては違う番地が返されるのでこのままやっても文字化けします。
単純にordから逆算しても、ヲがアより前にあったりするなど非常に複雑になります。
そのため、一度shift-jisでエンコード（バイナリ文字列）にし、hex()メゾットで文字列の16進数にし、10進数の整数に変換しています。
ただ、これでもShift-jisにない独自領域(0x10~0x1F、0x7E〜0x9F、0xE0〜0xFF）については出せないため、この領域の文字が必要があれば関数で実装する必要があるかもしれません。
今後プログラム改良（特殊記号とか漢字非表示とか）したらまた投稿します。

#試運転
まず、i2cの通信ができているか確認するため、`sudo i2cdetect 1`で認識されているか確認する。
![i2c](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214012/c83c899b-b932-47b5-dc91-3fc5430df247.png)

修正したプログラムを管理者権限で実行する。
`sudo python3 sa1602a`

これで正常にディスプレイの表示が変わったら一応はOK。
OSError: [Errno 121] Remote I/O error　というエラーが出たら、SA0の指定が間違っているので、54行目を修正する。
PermissionError: [Errno 13] Permission denied　というエラーが出たら、管理者権限で実行する。

#プログラムの修正２
一応、前章のプログラムの56、58行目を書き換えれば自由に表示を変えることはできる。
ただし、半角カナは半角カナで入力する必要がある。
ところで、私の環境(macbook)は半角カナ入れるのがめんどくさいので、全角かな（カナ）でも自動で表示する様に改修する。

```python3:so1602a.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import smbus
import time
import datetime
import jaconv

#（中略）

    def writeLine(self, str = '', line = 0, align = 'left'):
        str=jaconv.z2h(jaconv.hira2hkata(str),digit=True,ascii=True)[0:20]
        while (len(str) < 20):
            if (align == 'right'):
                str = ' ' + str
#（以下略）
```

jaconvをimportして、writeLine関数の最初でstrの文字を　ひらがな→全角カタカナ、全角文字→半角文字　に変換して最大２０字に切り落とし（して再度strに代入）する処理を１行追加。

これにより、「こんにちわ」で入力しても、文字化けせずに半角カナにして表示してくれるようになるし、字数オーバーしても次の行に影響されることもない。

#おわり
今後、このプログラムをベースに（プログラムをいじりつつ）いろいろ遊んでいきたいと思います。
・・・ってか元々Raspberry Pi Zeroが制御する監視盤作ったのにzeroがなかなか買えないっす。（4でテストしてるのですが、直接zeroに接続する設計なので、LAN端子とユニバーサル基板が干渉してしまうため、オスメスのジャンパ線で繋いでる状況っす）

#参考文献
[Raspberry Piから秋月のI2C接続の有機ELディスプレイを制御する](https://qiita.com/uhey22e/items/14d3e1d95d6ddc90fb2c)
[文字コード表 シフトJIS(Shift_JIS)](http://charset.7jp.net/sjis.html)
[Python から I2C 接続のディスプレイを操作する](https://qiita.com/jkawamoto/items/4f67779c13dfb34e5dbf)
[有機ELキャラクタディスプレイモジュール　取扱説明書](https://akizukidenshi.com/download/ds/akizuki/so2002awyb-uc-wb-u_akizuki_manu.pdf)