Closed treyus30 closed 10 months ago
I think you need an instance for each display.
There is a bit of state in the instance and each instance thinks it controls CS and DC.
Edit: You probably need a separate pin for reset on each display. I think one DC pin might work.
You could connect all displays to a reset line and pull it low for 10 ms before calling
begin(&Adafruit128x64, OLED_CS[n], DC_PIN)
for each instance.
I think you need an instance for each display.
There is a bit of state in the instance and each instance thinks it controls CS and DC.
Edit: You probably need a separate pin for reset on each display. I think one DC pin might work.
You could connect all displays to a reset line and pull it low for 10 ms before calling
begin(&Adafruit128x64, OLED_CS[n], DC_PIN)
for each instance.
Thanks, I'll try that. :) Multiple instances is out of the question due to memory restrictions of the overall program. I'm barely running with the one.
So ultimately the suggestions didn't work, and I found that since I was using begin() with the reset pin defined, it was already delaying 10ms (x2). However, they gave me the motivation to start strategically experimenting with placing delays and focusing on the RESET function itself. The initialization seems to be a lot more stable now, and fails maybe 1 in 10 times instead of 8 in 10. I think the remaining issues could be stemming from the high impedance of my breadboard and/or less than ideal power supply rail.
Additional perspective came from the SSD1306 datasheet:
More stable code:
//SETUP
void setup() {
pinMode(RST_PIN, OUTPUT); //attempt to stabilize the reset pin immediately
digitalWrite(RST_PIN, HIGH);
delay(500); //give time to stabilize initial voltages
///bunch of unrelated stuff...
//SPI display
//digitalWrite(RST_PIN, LOW); //added these two at the recommendation of the library creator, but they didn't seem to do anything. Using the reset pin in the declaration below does this anyway..
delay(10);
oled.begin(&Adafruit128x64, OLED_CS_0, DC_PIN, RST_PIN); //start primary instance
oled.setFont(Adafruit5x7);
//setup all possible Chip Selects
for (int n=0; n < maxDisplays; n++){
pinMode(OLED_CS[n], OUTPUT);
digitalWrite(OLED_CS[n], HIGH);
delay(1); //seemed to stabilize display startup
}
for (int n=0; n < maxDisplays-1; n++){
digitalWrite(OLED_CS[n], LOW);
delay(5); //seemed to stabilize display startup @ >=1ms
oled.clear();
oled.setContrast(64); //64 = 25uA, 160 = 69uA, 255 = 100uA
oled.setCursor(0,0);
oled.set1X();
oled.print(F("Screen ")); oled.print(n+1); oled.print(F(" (A")); oled.print(n); oled.println(F(")"));
oled.println(F("Initializing..."));
oled.setCursor(29,3);
oled.set2X();
oled.print(F("Please"));
oled.setCursor(40,5);
oled.print(F("Wait"));
digitalWrite(OLED_CS[n], HIGH);
delay(5);
}
delay(250); //brief pause after startups
Notably, there is a approximately 0.1V drop on the RES pin (2) referenced to VCC from having 4 displays. Not sure if that is an additional problem, or telling of the real problem, but the drop goes up with more displays.
Closing because this seems to be a physical issue. Thanks for the help!
About 80% of the time, my displays initialize like the attached or some combination of correct and corrupt. They initialize left to right in the code, and display 1 always appears correct. 20% of the time they all initialize perfectly, but usually display 3 or 4 have the issue. Sometimes they just appear black.
Once initialized, all further updates occur successfully, just vertically offset like pictured, so I've ruled out my wiring. What might need to change either in my code or the library?
Here is the relevant code section. I use one instance of the library and vary the CS pin to update one display at a time.