#面白そうなのでなんかよくわからんまま買ってしまった
飲みの席にて、自作キーボードの民である友人氏からノリと勢いで買い取ってしまったOLEDディスプレイ。「いい感じに描画できるイケてる小型液晶」くらいの認識でどうしたら使えるかもわかってなかったんですが、LCDキャラクタディスプレイじゃなんかショボいよねとか言って少し前から欲しかったので即決で電子マネーを送金して強奪しました。
#今回やりたいこと
ちっこい液晶にサークルロゴ表示できたらかっこいいよね!
ということでこれを描画しようとわちゃわちゃしました。
サンプルコードを見るとSPIでもI2Cでも実装できるみたいです。今日はI2Cでいきますのでお手持ちのArduinoのSDA、SCLがどこのピンか調べておきましょう。
#型番がわからないので使い方もわからない
さて、初めて使うパーツはいつも型番をググってサンプルやらライブラリやら探しますが、今回はそれができませんでした。
(https://yushakobo.jp/shop/oled/)
遊舎工房さんのページにはこんな感じで「商品コード: A01OL」とあるんですが商品コードってことはこれどこでも通用する「型番」じゃあないんですね。で、しかもよくよく見てみたら自作キーボードキットに含まれてるパーツで、専用のファームウェアからの操作に関する情報しか見当たらないんですよ(もしかしたら僕が気付かなかっただけでどっかにはあったのかもしれません)。他に流通ルートが無いパーツなのか……?
自力での解決を諦め泣く泣く友人氏に相談しました。
##「Adafruit_SSD1306」と「Adafruit_GFX」
(https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examples)
エイダフルーツと読むらしいです。この2つのライブラリを使えばOLEDディスプレイと仲良くなれるそうで、A01OL君もその例に漏れずこいつでなんとかなることがわかりました。ちゃっちゃか導入しちゃいましょう。
画像を出すだけなら「Adafruit_GFX」は必要ありませんがサンプルコードでincludeしてるんで入れといた方が無難だと思います。
#いざ、任意の画像を描画
適当にググればいつもぱっと何かしら古くさい個人ブログとかQiitaのイケイケ記事なんかが出てきていい感じにあれこれ知ることができますが、まだ「デキる人はすぐ解決できるので困らないしデキない人がわらわら来るほど出回ってるパーツではないので記事が無い」状況なのか、なーーーーんにも出てきません。
とりあえずサンプルコードをそのまま書き込んでデモを動かしてニヤニヤしてはみましたが問題はここから先です。私は勘違いやら何やらもあって何時間も溶けましたがこの記事を読めばそんな目に遭うことは無い(はず)です。
##STEP0:繋げちゃうよ
A01OLとArduinoでSCL、SDA、VCC、GNDを繋ぎます。
##STEP1:BMPイメージをテキスト化
ペイントでもフォトショでもGIMPでもなんでもいいんで、まずはBMP形式の画像を用意します。サイズは128×32以内なら問題ありません。それより大きなサイズになると、極端な数字でしか試していませんが上手く動作しませんでした。このあたりは仕様も仕組みも何も知らないまま脳筋トライしかしていないのでだいぶガバです。コメント等で補足なり訂正なりいただけると嬉しいです。
こしらえた画像はこのページでテキスト化します。→ http://javl.github.io/image2cpp/
保護されていないらしいので環境や設定によっては弾かれるかもしれません。最終的にテキスト化できればなんでもいいので駄目そうなら代替ツールを探してください。
英語ではありますがこれといって丁寧に説明する必要がある項目は無いのですいすいと進むはずです。
「Horizontal」「Vertical」はテキストの並びと描画方向が一致しない際に切り替えます。まずはデフォルトのままでいいと思います。
ここで「Arduino code」を選択しておくとコピペが楽です。
生成ボタンをクリックして吐き出された「const unsigned char myBitmap [] PROGMEM = {...}」をどっかにキープしておきましょう。
##STEP2:下記テンプレをコピペ
サンプルコードから必要最低限と思われる部分だけ切り出しました。ぶっちゃけよくわかってないとこもありますがとりあえず動かさんことにはどうにもならんので、細かいとこは後で気が向いたら見りゃいいんです。
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BMP_WIDTH 128
#define BMP_HEIGHT 32
const unsigned char myBitmap [] PROGMEM = {...};
void setup() {
Serial.begin(9600);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(2000); // Pause for 2 seconds
}
void loop() {
drawbitmap();
}
void drawbitmap() {
display.clearDisplay();
display.drawBitmap(
0,
0,
myBitmap, BMP_WIDTH, BMP_HEIGHT, 1);
display.display();
delay(1000);
}
##STEP3:画像サイズの定義を書き換え
11、12行目ですね。
#define BMP_WIDTH 128
#define BMP_HEIGHT 32
ここの数値が実際の画像サイズと一致しないと正常に描画されません。忘れずに書き換えましょう。
##STEP4:画像データ追記
14行目です。
const unsigned char myBitmap [] PROGMEM = {...};
STEP1で生成したテキストをここにぶち込みます。
#おつかれさまでした
以上の手順を経てボードに書き込めば晴れてお好みの画像
がA01OLに表示されます。ほれこの通……り……
うーーーーーーーーーん……このディスプレイじゃ狭いですね、残念。
ロゴ全体はやめて文字部分だけにしたらまあそれなりって感じです。
#おまけ
37行目について。
display.drawBitmap(
0,
0,
myBitmap, BMP_WIDTH, BMP_HEIGHT, 1);
一目見てお察しと言った感じですがここ弄れば描画位置を変えられます。センタリングとかして遊んでみてください。
アニメーション表示に関してはサンプルコードや公式ページ( https://learn.adafruit.com/adafruit-gfx-graphics-library/graphics-primitives )を見れば実装できるかと。