128×64ドットで、多数jの文字を表示するのは、1画面ならOKだが、2画面だとダメだった。
ということで、次のような実験をした。
これだと、ディスプレイの上半分だけが使われるのだろうか。
プログラム全体を以下に示す。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET 4
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);
displayText(display1, "Arduino is an open-source hardware and software company,"
"project and user community ");
displayText(display2, "that designs and manufactures "
"single-board microcontrollers and microcontroller kits " );
}
void loop() {
}
void displayText(Adafruit_SSD1306 disp, char* text) {
disp.setTextColor(WHITE);
disp.clearDisplay();
disp.setTextSize(1);
disp.setCursor(0,0);
disp.print(text);
disp.display();
}
すると、結果はこうなった。
文字が縦に倍に伸ばされているようだ。1行の文字数には変化がない。
さて、どうして、128×64では動かず、128×32にしたら動いたのであろうか。
たぶん、以下のような理由ではないかと思う。
画面が128x64ドットということは、128×64 = 8192画素なので、モノクロ画面イメージを保持するには8192ビット、つまり1KBのメモリが必要になる。
すると、次の2行で、
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
2つのオブジェクトが作られ、各オブジェクトには画面イメージ1024バイト必要で、オブジェクトにはその他の値も少しは保持されるので、1オブジェクトが1KBよりやや大きいはずである。
ところで、Arduinoのメインメモリ(SRAM)は2048バイトしかない。
一部の特殊なものは多数のメモリを搭載している。例えば、Arduino Zeroは32ビットCPUのArmが載っていて、SRAM 32KBとなっている。Zeroがついていると、性能が落ちると思い込んではいけない。
ということは、それぞれの画面毎にオブジェクトを作ったら、それだけでメモリが足りなくなるので、動作しないのは当然だ。
それでも、それぞれの画面に、小さい字で8行表示したいと思い、次のように変更した。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
displayText(0x3C,"Arduino is an open-source hardware and software company,"
"project and user community that designs and manufactures "
"single-board microcontrollers and microcontroller kits " );
displayText(0X3D,"for building digital devices and interactive objects "
"that can sense and control both physically and digitally.");
}
void loop() {
exit(0);
}
void displayText( int addr, char* text) {
display.begin(SSD1306_SWITCHCAPVCC, addr );
display.setTextColor(WHITE);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0,0);
display.print(text);
display.display();
}
そして結果は、めでたくこうなった。
要するに、オブジェクトは1つ作るだけで、displayText
関数には、I2Cのアドレスと文字列を渡すことにした。
そして、displayText
()では、最初に渡されたI2Cアドレスを指定して初期化してから表示処理をするようにした。
蛇足だが、このOLEDでは、送られてきた画面データはずっと保持されているので、最初のOLEDは放置して、次のOLEDの処理を行うことができる。
これを上手く使えば、多数のOLEDの表示を、1つのArduinoで制御できる。
OLEDの話が予定より長くなってしまった。次からは、別の話題にする。