google-site-verification: google3bd66dd162ef54c7.html
FC2ブログ

2つの0.96インチOLEDをArduino UNO で同時に表示

今回の記事は、youtube に0.96インチのOLEDをArduino UNO から二つ同時に表示する、という動画を見つけました。面白そうなので、そこに書かれている方法をやってみたけど、あまりうまく行きませんでした。と言う締まりの無い話になっています。



▼2つ同時に表示している様子(上記動画からキャプチャ)
表示結果

128 x 64 画素のOLEDは1024バイトのバッファを使いますが、これを二つ同時に使うと倍の2048バイトが必要になるはずです。一方でArduino UNO のRAMは2kバイト、つまり2048バイトで同じです。プログラムを動かすために、画像バッファ以外に変数用などにもRAMが必要なので、普通にやったらうまく動かないと思います。

ということで、何か特殊なテクニックが使われているのでは?と思ってやってみました。幸いFREE CODE と唄っていてソースは公開されています。それにOLEDも二つ余っています。

▼I2Cアドレスの設定
I2Cアドレスの設定
OLEDの基板上にあるアドレス設定用の抵抗の位置を変えて、アドレスが0x78と0x7Aの物を作ります。なお、左側のOLEDの3.3Vラインにはセラコンが追加されていますが、これは今回の話には関係ありません。

配線してプログラムをyoutubeの記事に書かれているリンク先から落としてきて動かしてみると、ちょっと動作が変です。

▼プログラムが間違っている
プログラムが間違っている
ソースを見ると、Display1 を表示した後で Display2 の表示を行っていますが、Display2 を表示するプログラムの途中でDisplay1 を触っている行があって、明らかに間違っています。動画の中にもプログラムを映している部分があるので、ひょっとしてと思って見たらこっちも間違っていました。上の画像はその部分の動画のキャプチャーです。

プログラムを修正して動かした結果が次の写真です。

▼実行結果
表示結果
横方向はいいのですが、縦方向が 2倍に引き伸ばされています。よく見ると水平に1ライン毎に黒い線が入っています。つまり、横は128画素有りますが、縦は32画素相当の表示になっています。RAMのアロケーションを調べるプログラムを追加してメモリーの使用状態を見てみると、ヒープ領域に約1030バイトが確保されているだけだったので、表示結果と矛盾しない量になっていました。(128 x 32 画素 x 2 画面 = 8192 ビット = 1024 バイト)
つまり、期待していた特殊なテクニックは使われていないようです。

プログラムの初期化をやっている部分は下記です。
#include 

#define OLED_RESET 4
Adafruit_SSD1306 Display1(OLED_RESET);
Adafruit_SSD1306 Display2(OLED_RESET);

int i, j;

void setup() {

//Serial.begin(9600);

Display1.begin(SSD1306_SWITCHCAPVCC, 0x3D);
Display1.clearDisplay();
Display1.display();

Display2.begin(SSD1306_SWITCHCAPVCC, 0x3C);
Display2.clearDisplay();
Display2.display();

}
SSD1306の画素数の設定がされていません。たぶんこういう書き方をすると、デフォルトの設定が選択されて、それが128x32画素になる、ということなんでしょうか。

ともかく繰り返しになりますが、実際にやってみたらたら謎は深まりました。

◆まとめ
この画素数のOLEDを2つ同時に使うと、arduino UNOではRAMが不足するはず。ということは、バッファメモリーの共用などのテクニックが使われているのではないだろうかと思って調べてみました。しかし特にそういうことをやっている感じではありませんでした。というか、それ以前に2つのOLEDを本来の解像度で動かすことが出来ませんでした。

デモの画面を見ると128x64画素で2画面表示しているのは間違い無い気がします。ひょっとしたら、この動画が投稿された頃と現在ではadafluit のライブラリの造りが変わっているのかも知れません。

ついでに書きますが、adafluit のグラフィックのライブラリの使い方の解説ページが見つからないのでいつも不便な思いをしています。公式ページはたぶんここ⇒https://github.com/adafruit/Adafruit-GFX-Library
事例などを見ればおよその使い方は判ります。でも例えば今回のように引数の数が少なかった場合の挙動などは、なかなか判らないです。ひょっとしたら皆さんは、ライブラリのソースをその都度読んでるのでしょうか?そんなことは無いですよね。
関連記事

コメントの投稿

管理者にだけ表示を許可する

No title

こんにちは

ご無沙汰しています。
あまのじゃく故、Adafruit_SSD1306ライブラリは使ったことがなかったのですが、先ほど中身を調べてみました。

GitHubにある、Adafruit_SSD1306.hの29行目をご覧ください。
「#define SSD1306_128_32」となっていて128x32のOLEDが生きています。一方、128x64のOLEDの定義は一つ上の行でコメントアウトされています。
これが原因ではないでしょうか(間違っていたらすみません)?

ちなみに私自身はPIC(メモリ環境が厳しい!)と最近手を出したRasPiでSSD1306 OLEDを使用しています(PIC用には自分で初期化ルーチンやテキスト表示のドライバを作成しました)。
こいつは表示がちっちゃいのがとても残念なのですが、広視野角、高コントラストが魅力だと思います。

No title

蛇足になりますが、以前のオシロの製作の記事ではスケッチ中で、
「SSD1306_LCDHEIGHT 64」
と定義されていたので何も問題が起きなかったのだと思います。
(私の勘違いかも知れませんが…)


vabenecosi さん、今晩は

ライブラリの中まで見て頂いてありがとうございます。当方で実際に使っているライブラリファイルの中身も同じであることを確認しました。
SSD1306のデフォルトの解像度は128x32と言うことなんでしょうね。あと、普通は、#define SSD1306_LCDHEIGHT 64 とかやっているのも自覚してます。

adafluitのライブラリは、画面全体のバッファを用意しているのでRAMを大食いしますが、デバイスに直接書くようなことをすれば、メモリーの大幅な節約が出来るんだろうなと思っています。たぶんそういうことをPICでやられているんでしょうね。

No title

私がコメントした点が原因で黒い線が入るんだということまでは確認していません。気になっているので追試していただけると有難いです。

私の方は、最近、ガジェットを作る方こと自体が忙しくてブログの記事にしてアップするのをさぼっていました。でも順次記事にしていくつもりです。とっかかりとしてPICの方の製作記事をアップすることにします(まず写真の準備ですね)。

No title

OLEDの定義部を下記のように変更してやってみました。

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 Display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 Display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

結果は、Display1だけ点滅してDisplay2には何も表示されない状態になりました。たぶんヒープとスタックがぶつかって、暴走しているのだと思います。

この挙動は予想通りなのですが、記事の先頭にリンクを置いたyoutubeの動画では128x64の2画面でちゃんと動いているのが謎です。というか、これなんで正常に動くの?と思ってやってみたのがこの記事なんですが、謎は深まりました。

なお、プログラムの全体は下記です。
https://blog-imgs-126.fc2.com/r/a/d/radiopench/20190621OLEDtest5.txt

ちなみに、Adafruit_SSD1306のライブラリ使って、128x64の設定のままで128x32画素のOLEDを繋ぐと、1ライン飛ばしで縦に圧縮されて表示されます。そんなことで、逆のことをやると黒線が挿入されて縦に延ばされるのだと思います。ライブラリの中で論理画素数と物理画素数をマップするような処理が入っているのではないかと想像しています。

No title

こんばんは

追試していただいて有難うございます。

問題のデモムービーへのTomasz Patelczykさんのコメントのスレッドに以下のようなものがありました。
やはりAdafruitのライブラリが変わったために現在は上手く動作しなくなってしまったということのようですね。

IronHide
2 か月前(編集済み)

@GalaXy` I had this issue, it seems the updated Adafruit library no longer works with this code. don't ask me why, still learning to use my Arduino. but if you change the library version to 1.2.7 it should work. it did for me at least. kris Kasprzak if you see this, might be worth throwing a note up on the video?

vabenecosi さん、おはようございます

youtubeのコメントまで調べて頂いてありがとうございます。

教えて頂いたコメントのスレッド読みました。ライブラリが新しくなってからうまく動かなくなっているんですね。
free code という触れ込みですが、warranty free code だったという落ちでした。
カレンダー
07 | 2019/08 | 09
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード