-
Notifications
You must be signed in to change notification settings - Fork 649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Two OLED Displays 128x64 #138
Comments
Same problem here :( Thomas
|
Yeah, the problem is when you do that in a loop it makes the display flash, and eventually it stops working altogether until you reset it. |
True! :( Not pretty, but it seems to work...
|
Nice work! yes, ugly but it works :) |
Connect the displays to one I2C bus (identical pins). But before that, set them different addresses. |
agree, same to me, both OLEDs work fine on the same i2c bus (by arbitrary i2c GPIOs): #include "SSD1306.h" void setup() { // snip as usual, at 1 single bus one always needs different i2c bus addresses for either device, instead one may use i2c port splitters, e.g. PCA9548A chip from NXP IMO solved, issue can be closed. |
You init'd the same display twice: |
sure, a typo, sorry! |
I can't change the addresses on my displays, so I am using different bus pins. (2 SH1106 - 128x64) When displaying for each display, I still have to init each one before use. Works great, but after 18 inits, the ESP errors on (3,6). No amount of I'm going to try the Is there something I'm just not getting? |
so which is actually the way how it works now, for identical dev addresses, by explicite source code? |
This is my simple test with ESP8266, OTA, Neopixels, and two identical 1106's. #include "SH1106.h"
// Initialize the OLED displays using Wire library
SH1106 display1(0x3c, 4, 5);
SH1106 display2(0x3c, 13, 12);
// Setting up some timers
unsigned long timer1, timer2;
#define INTERVAL1 6000
#define INTERVAL2 1000
uint8_t ledState = LOW;
uint8_t r, g, b;
#define OFF 0, 0, 0
void setup() {
Serial.begin(115200);
timer1 = timer2 = millis();
}
void loop() {
if ((millis() - timer1) > INTERVAL1) {
timer1 += INTERVAL1;
// Initialize the first display -- If we don't do this, all the info will be displayed on the last initialized display.
displayOne();
// Set font
display1.setFont(ArialMT_Plain_24);
// Set alignment
display1.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
// Set what to display and where
display1.drawString(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, "Rainbow");
// Go put that stuff on the screen
display1.display();
timer2 = millis();
}
if ((millis() - timer2) > INTERVAL2) {
timer2 += INTERVAL2;
if (ledState == LOW) ledState = HIGH;
else ledState = LOW;
if (ledState == LOW) {
// Generate a new RGB color
r = random(127);
g = random(127);
b = random(127);
// Initialize the second display -- If we don't do this, all of the info will be displayed on the last initialized display.
displayTwo();
// Set font
display2.setFont(ArialMT_Plain_16);
// Set alignment
display2.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
// Set what to display and where
display2.drawString(DISPLAY_WIDTH/2, 22, "Timer 1: " + String(timer1 / 1000));
display2.drawString(DISPLAY_WIDTH/2, 42, "Timer 2: " + String(timer2 / 1000));
// Set font
display2.setFont(ArialMT_Plain_10);
// Set alignment
display2.setTextAlignment(TEXT_ALIGN_CENTER);
// Set what to display and where
display2.drawString(DISPLAY_WIDTH/2, 53, String(count2) + " inits!");
// Go put that stuff on the screen
display2.display();
}
else {
// Initialize the first display -- If we don't do this, all the info will be displayed on the last initialized display.
displayOne();
display1.setFont(ArialMT_Plain_16);
display1.setTextAlignment(TEXT_ALIGN_CENTER);
display1.drawString(DISPLAY_WIDTH/2, 0, "LED: " + String(LEDnum));
display1.drawLine(40, 18, 90, 18);
display1.setFont(ArialMT_Plain_10);
display1.setTextAlignment(TEXT_ALIGN_LEFT);
if (r >= 100) display1.drawString(44, 24, "*");
if (g >= 100) display1.drawString(44, 35, "*");
if (b >= 100) display1.drawString(44, 46, "*");
display1.drawString(50, 24, "R: " + String(r));
display1.drawString(50, 35, "G: " + String(g));
display1.drawString(50, 46, "B: " + String(b));
display1.display();
}
}
}
void displayOne() {
display1.init();
// These have to be set after `init()`
display1.flipScreenVertically();
// This only needs to be set if other than 255
display1.setContrast(255);
}
void displayTwo() {
display2.init();
// This has to be set after `init()`
display2.flipScreenVertically();
// This only needs to be set if other than 255
display2.setContrast(255);
} |
@ Tannoo: |
Sure, I'll just edit the previsous post. |
FYI: I’m adding this feature to the library. You should be able to transparently use many displays in parallel. It works on my local branch |
Are we going to be able to display to a specific one without sending an init() first? |
I want to integrate this into the library. Now the question is how to do this best. First I thought I could just instantiate the TwoWire object in the display driver, but the sda and scl pins are static and shared between all instances. |
Is there a way to elimate the default pins unless none are define in any instance? |
I say that because
|
What about a Wire object, which is initialized with the proper pins and hand that to the constructor of the Display class (or those classes inheriting it)? |
Hi guys. I don't like static variables either, but the problems come from the fact that Arduino/ESP8266 wire library uses two static variables to store the pins which makes it a lot harder for us to keep two or more separate instances of the Wire/I2C driver. Have a look here: https://github.com/esp8266/Arduino/blob/master/libraries/Wire/Wire.cpp#L55 So the 100 Mio dollar question is how to we get around this nasty fact? The brute force solution is to always call Wire.begin(...) whenever we communicate over I2C. But that probably will be very inefficient @igrr: Do you have a suggestion? Do you know why those static variables were introduced in the first place? I think the ESP32 code base doesn't have them anymore... |
Can't both display objects share the same I2C bus? |
@squix78 The reason these were introduced is for the sketch to allow setting pin numbers of I2C bus, even if a 3rd party library is not aware of the way to set pins. For example, a library written for normal Arduino boards calls |
having even more i2c devices attached to the esp8266, such as ADS1115 or PCF8574, they have to be initialized by static Wire pins.
|
Here is my suggestion (and currently available on the unreleased master branch). By setting setI2cAutoInit(true) the driver always calls Wire.begin(..) before writing to the I2C bus. This only properly works if we are only using display drivers, not if we are using other I2C devices:
There is a new demo for this called SSD1306TwoScreenDemo. What do you guys think? |
Why not just use 2 screens on the same I2C bus, just with a different address? That's what this bus is for, right? |
@TD-er : @squix78 : I think the best way would be to make it like I showed in my example above, that is easy and handsome both for beginners with single display and those who use 2 of them
and then But for backward-compatiility you may create such an overloaded function additionally to |
@Tannoo the "1" and "2" positions near the connector have some SMD resistors connected either to Vdd or GND. |
I have just run into an issue with two 128*64 displays connected to a common bus. They are addressed 60 and 61, and I use What I noted was that at an earlier point in testing, Display2 was "exposed" to random signals on the I2C, so I have a suspicion that some internal registers were set to a timeout? Is this feasible? HOWEVER, powering off the board for 60 secs seemed to "cure" the timeout issue. (making the re-initialization unnecessary) So the question remains.. Is there a "I2C Timeout" register somewhere in the SSD, and if so, can we have a function to use (or reset!) it?? |
What happens if you swap both displays? |
Just to give background: I was developing code that works with both addresses, but only had my display2 (61) connected at first. So my only conclusion was that there might be a software timeout in the driver chip to turn off the display (save power??) a set time after initialization. This seemed a sensible forum to ask if such a thing exists.. If it does not, then its at least a good place to note that random input to the displays can potentially result in some very strange, but repeatable, behavior that is not corrected until a power off. Cheers |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
I also have a problem with this display, I can’t change the address. I tried to change the position of jumpers 1 and 2 of Vdd GND, but this did not help. Does anyone know how to change the address of this display? The display address cannot be changed without alteration. The 15th contact is pulled up to G, and to change the address you need to apply 3.3 Volts to it. |
Hi!
I cant get two displays to work. Basically write to one, and then the other. As soon as the 2nd one gets initialized the first one no longer works.
SSD1306 display1(0x3d, D3, D5);
SSD1306 display2(0x3c, D1, D2);
display1.init();
display1.flipScreenVertically();
display1.setFont(ArialMT_Plain_10);
display2.init();
display2.flipScreenVertically();
display2.setFont(ArialMT_Plain_10);
display1.clear();
display1.setTextAlignment(TEXT_ALIGN_CENTER);
display1.setFont(ArialMT_Plain_10);
display1.drawString(64, 5, "test");
display1.display();
display2.clear();
display2.setTextAlignment(TEXT_ALIGN_CENTER);
display2.setFont(ArialMT_Plain_10);
display2.drawString(64, 5, "test");
display2.display();
The text was updated successfully, but these errors were encountered: