SPI接続でOLEDに文字出力した話【u8g2ライブラリ利用】

積みパーツを消化していく...

# はじめに
- 何で[これ](https://www.waveshare.com/wiki/1.3inch_OLED_(B))を買ったのか、いつ買ったのかも記憶にないけど、机の上に転がっているのを見て見ぬふりするのも嫌になったので、消化していく（＝とりあえず、動かしてみる）
![17130065667680.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/91eec31f-51a7-40d6-216c-a08334a6de6f.jpeg)

# 接続
- [公式HP](https://www.waveshare.com/wiki/1.3inch_OLED_(B))によれば、spiの3線式、4線式もしくはi2cに対応しているけど、デフォは4線式spiで、他に切り替えるためには半田ゴテ作業が必要なので、デフォのままとする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/ab6d248f-9d57-1ea4-b39f-74d57916b011.png)
- 4線spiといっても、教科書的な4線式spi（CS,SCLK,MOSI,MISO）と意味は異なり、ディスプレイの4線「CS,SCLK,MOSI,D/C(=Data/Command)」となる。また、RSTピン(RES)も存在する。なお、NCはNoConnectingの略称であり、何も繋がない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/2e03cca3-c323-0016-ef7b-26b673891e7b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/5036b4d8-a0c0-dee7-5c26-71bcf0120f65.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/7b3eb853-7c25-2b48-22af-adb62d6f8f13.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/fe87cbc0-41b6-46f7-89db-94f2afb7e033.png)
- [HP](https://www.waveshare.com/wiki/1.3inch_OLED_(B))の一番下の方を見ると、チップはsh1106みたい。HPにサンプルプログラムもあるけど、sh1106なら、u8g2ライブラリが対応しているから、サンプルプログラムは無視して、M5atomS3で[u8g2](https://www.arduino.cc/reference/en/libraries/u8g2/)を使ったプログラムを書く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/2a41d723-a028-bd70-b2c9-0790f5d27800.png)
- [u8g2の制御チップ毎のイニシャライザのリスト](https://github.com/olikraus/u8g2/wiki/u8g2setupcpp#sh1106-128x64_noname)のうち、4線のソフトウエアspi（atomS3はハードウエアspiの端子がないはず）から選ぶ感じかな。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/be740632-f505-8a0d-9b55-c0bf1109a915.png)
- M5atomS3の各ピンを下記の通り割り当てた
    - grove端子から、5V , GND , G2->DIN , G1->CLK
    - 底面の端子から、G5->CS , G6->D/C , G8->RST
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/233177d0-3a34-e9e4-8485-933d296dc18d.png)
- 底面の端子を使うため、[atomHAT](https://docs.m5stack.com/ja/atom/atom_mate)を使った。まあ、HATを使わずに、直接ぶっ刺してもいいけど。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/274e0384-9583-0079-62ea-71c5d7f6a168.png)
- arduinoIDEでは、SPIのデフォルト端子名「SS(上記CS),SCK(上記CLK),MISO(不使用),MOSI(上記DIN)」を使って設定する。

# 実際の動作
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/2368758a-d995-d197-9912-8fc54bb1d3fb.png)


# 書いたコード(arduinoIDE)
```cpp
#include <M5Unified.h>
#include <SPI.h>
#include <U8g2lib.h>

//予約語定義
#define SS 5
#define SCK 1
#define MOSI 2
#define MISO -1  //不使用

//自由定義
#define DC 6
#define RST 8

//waveshare_1.3inch用の設定
U8G2_SH1106_128X64_NONAME_F_4W_SW_SPI u8g2(/* No rotation */ U8G2_R0, SCK, MOSI, SS, DC, RST);

void setup() {
  M5.begin();
  SPI.begin();

  digitalWrite(DC, HIGH);   //HIGHでディスプレイデータ、LOWでコマンドデータ
  digitalWrite(RST, HIGH);  //通常はHIGHのまま。LOWのときリセット。
  digitalWrite(SS, LOW);    //LOWでセレクト状態

  u8g2.begin();         // 初期化
  u8g2.setFlipMode(1);  // 画面の向き(0:標準、1:逆向き)

  u8g2.clearBuffer();                       // バッファのクリア
  u8g2.setFont(u8g2_font_cu12_t_cyrillic);  // キリル文字(utf8)
  u8g2.drawStr(0, 15, "Hello World!");      // 文字列格納
  u8g2.drawUTF8(0, 30, "Привет мир!");      // 文字列格納(utf8の場合)
  u8g2.sendBuffer();                        // バッファを画面反映
}

void loop() {
}
```

# コードの解説
- 接続設定が面倒なだけで、コード自体はたいしたことをしていない。
- 注意点としては、[接続](https://qiita.com/kei2y/items/ef1e95bb9adaf805e9d2#%E6%8E%A5%E7%B6%9A)で書いたu8g2のイニシャライザ三つのうち、NONAME_1を使うと、表示がおかしくなること。ページバッファーサイズが1番小さい(128bytes)のせいかな？
- 下記は、最初に標準の画面の向きでNONAME_1のイニシャライザでHello Worldしたときの表示。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/63d81bf3-277b-7d24-f1ad-fbeb5cd79549.png)
- よって、実際のコードは、もっともバッファの大きいNONAME_Fを使った。

# おわりに
- 週1回のペースで投稿していたから、今週も何もしないのは気持ち悪いから投稿してみた。
- まあ、投稿する方が真面目にコードも書くから、自分のevernoteに作業を残すだけよりいいかも。
- 中身薄くてゴメンだけど...