目次 [ Contents ]
Arduino電子工作で外部に値を表示したいときなんかディスプレイを使いますが、一般的なのは文字を表示するLCDディスプレイだと思います。でも、Amazonなんかを見ると小さい有機EL(OLED)ディスプレイがお手ごろな値段で売ってたりして使ってみたくなります。ただ、これはグラフィックタイプなので、文字タイプより大変そうです。
グラフィックディスプレイを動かすのに便利なu8glibというライブラリがあります。それを使おうとして自分も最初いろいろ四苦八苦してました。しかし勝手が分かれば、完璧ではないにしろ形に出来ます。
そんな自分なりのu8glibの使い方を解説していきたいと思います。間違っていたり、雑な部分はご了承ください。
u8glibとは
元々Arduino用ライブラリとしてGitHubなんかで公表されていたolikraus(oliver?)さんによるグラフィックディスプレイのライブラリです。Adafruitのライブラリかu8glibか見たいな感じで、グラフィック用のライブラリとしては有名だったみたいです。最近のIDEでは「ライブラリを管理」で検索すればアプリ内から簡単にインストールできるようになっています。もっと言えば、Version2があるみたいなんですけど、こちらは未確認です。とりあえず、Version1で解説します。自己解決能力があればV2で挑戦してください。
使用ディスプレイ
OLEDは有機ELのディスプレイで液晶よりも輝度が高く綺麗です。薄く出来たり、消費電力が低かったり、昔から次世代のモニタといわれてますが、どうも大型化が難しいらしくて、あまりテレビ製品としては見かけません。でも、こういった小型のものはかなり普及してきているので(携帯とか)、こういった小さいタイプが安く手に入るんじゃないでしょうか。
色々なサイトでさまざまなタイプのディスプレイが販売されていますが、自分が手に入れたものはAmazonのサイトで買える128x64ピクセルのI2C接続のOLEDです。
[GPG] 小型I2C 128×64 OLED ディスプレイ
また、値段が変わりますがSPI接続のものもあります。
EasyWordMall 3.3V-5V SPI ホワイトOLEDモジュール ディスプレイ
結構値段違いで安いものもあるので、自分で検索してみてください。ただし、上記の商品に関してのみ動作確認していますので、悪しからず。
I2C、SPIは共に機器のデジタル通信に使われる規格なんですが、基本的にSPI接続の方が通信速度が速いです。つまり、描画が早いです。SPIの方が高い転送速度をサポートしているからだと思いますが、詳しいことは分かりません。まあ、そんな知識の自分でもとりあえず動かすことはできるということで…。
検証した動画もあるので、よければご覧ください。
また、SPIの方がu8glibでの汎用性が高いです。というのも、SAMD21とかTeensyなどではI2C接続のディスプレイは動いてくれませんでした。自作フォローフォーカスでマイコンのスペックを上げようとしたら、そんな問題が出てしまって。ひょっとしたらVersion2のライブラリなら動くのかもしれませんが、Version1でI2C接続のものはArduinoUno、prominiでしか動作確認していないということも知っておいてください。
SPIがオススメですが、I2Cはピン2本、SPIは4本という点も悩みどころです。自分の環境に合わせて選んでください。
サンプルスケッチを見る
とりあえず、動作確認するため最初はサンプルスケッチを動かして見ます。
こんな感じで配線します。上記で紹介しているOLEDに関しては対応電圧は3-5Vらしいので、そのまま繋げて大丈夫だと思いますが、不安な人はちゃんと調べてください。
I2Cの場合はSCLとSDAをそれぞれ結線します。
次にライブラリをインストールします。
サンプルスケッチ、「GraphicTest」を開きます。
ドバドバとスケッチが開かれますが「サンプルなのでそのまま動くだろう…」、というのは勇み足で設定をチョッといじる必要があります。
冒頭の方にコメントアウトで書かれている部分は、動かすモニタのセッティングです。つまり自分が使うデバイスの設定を「生き」にする必要があります。これらは組み込まれているドライバチップの名前になっています。今回使っているのはSSD1306になります。
SPIの場合は、
//U8GLIB_SSD1306_128X64 u8g(4, 5, 6, 7);
I2Cの場合は以下のどちらか、
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);
環境に合わせて//を消し「生き」にします。あとは通常通り、スケッチを書き込めばサンプルが動いてくれると思います。分かりづらい感じもしますが、逆に言うとu8glibがこれだけ多くのディスプレイに対応しているということでもあります。
僕は最初このコメントアウトでつまづいてましたが、これが分かればとりあえず動くようになるので、とりあえずいろんなサンプルを試してみてください。
次は自分で描画をする方法について書きたいと思います。
次回 Part2
Arduino Serial.print()の表示用モニターに使えますか?また、設定方法があれば教えてほしいです。
コメントありがとうございます。
u8g.setPrintPos(x座標, y座業);
u8g.print(値);
の組み合わせで、基本的にSerial.printと同じような勝手で表示できます。ただ、型によってはオーバーフローする場合があり、上手くいかないこともあるようです。
また、一度に表示できる量はスクリーンのサイズに依存するので、表示させたいものが多ければフォントや表示方法を工夫する必要が出てくると思います。
Part4の「文字の描画」を参考にどうぞ。
先日はありがとうございました。一応、表示させたい文字とボリウムの値を表示させることができました。
気になるのは、ボタンカウントの数値とモーターの速度のボリウムを表示させているのですが、毎回カウント数が変わる時と変わらずに固まったような状態の時とがあります。
プログラム自体は表示に関わらず動いています。
その他のフレームレートという記事を参考にしましたが変わらずでした。
何か注意することはあるでしょうか?
具体的にプログラムを見ないと何とも言えないんですが、ボタンを押した瞬間がちょうどu8g描画のWhileループ中で、digitalReadでの判定に間に合ってないのかな、と。
強引なやり方なんですが、カウントさせる一連の命令を、描画のdo~while内にも追加で書いてみたらどうでしょうか?
https://jumbleat.com/2016/09/03/how_to_use_u8glib_part2/
最後の方「u8glibの問題点」に書いているので、参考にしてみてください(順を追って書いているので、最初から読まないと分かりづらいかもしれません)。
グラフィックテストは動くのですが、何故かハローワールドのサンプルが動きません。何か理由は考えられませんか???
コメントありがとうございます。
自分も新しいやつを手に入れてSPI接続を試していますが、結構規格に関して認識が違っていた部分があったみたいで…。
そこら辺はまたまとめるつもりですが、https://jumbleat.com/2017/03/16/amazon_cheap_oled_2/
とりあえず、“Hallo World”のサンプルスケッチに関してはあれっ?と思う箇所があり、
U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
リセットに関する引数(8)の記載がありません。設定文を“GraphicTest”からコピペするか、
U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9, 8);
としてみるとどうでしょうか?