OLED Module IIC I2C Display

Hi,
I have an IIC I2C OLED module. Everything works fine until I try to use a function twice. Here is my Setup method:

void setup() {
  mySerial.begin(9600);
  Serial.begin(9600); 

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  //Set up bluetooth device name and role etc
  initBluetooth();

  //Screen 1
  startupScreen();
  delay(5000);

  //Screen 2
  versionScreen();
  delay(5000);

  //Screen 3 - Start to test the BT device
  commandScreen("AT+NAMEalexbt2", "+NAMEalexbt2", "OK");
  delay(5000);

  //Screen 4
  NextScreen();
  delay(5000);

  //Screen 5 - Second test
  //commandScreen("AT+ROLE0", "+ROLE0", "OK");

}

Now that works fine until I uncomment Screen 5 function. The commandScreen function. It works if it is only used once (Screen 3). Once Screen 5 function is uncommented, I lose the smaller text on both Screen 3 and 5.

Youtube showing it working: https://youtu.be/W1Ep4Sl5XKU

And here it is again using the same function twice with a 5 second delay between them: https://youtu.be/SvYiK9T40Ao and the smaller text disappears.

Here is the commandScreen function:-

void commandScreen(String Cmnd, String St, String OC){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.setCursor(3,0);
  display.println("BT COMMAND");
  display.drawLine(0, 16, 127, 16, SSD1306_WHITE); 

  display.setCursor(0, 23);
  display.setTextSize(1);
  display.drawLine(0, 16, 127, 16, SSD1306_WHITE); 
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.println("SEND: " + Cmnd);

  display.setCursor(0, 34);
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.print("SENT: " + St);

  display.setCursor(0, 45);
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.print("REPLY: " + OC);
 
  display.display();
}

The only thing that changes with the reuse of commandScreen are the strings passed to it.

I hope that makes sense!!!

Post the complete sketch in one block. (do not split it up)

Nope, taking it out of context only adds confusion. Follow @xfpd's suggestion and post the full sketch using code tags. Adding an annotated schematic will also be very helpful. Saying "I have an OLED connected to my" doesn't provide enough information to understand your setup.

Here's the full sketch. I've been messing around with it quite a lot, commenting out code gradually until I can find the issue so I can fix it. Some of the functions listed are not called, including the bluetooth functions, and some variables are not used now also:

/**************************************************************************
 This is an example for our Monochrome OLEDs based on SSD1306 drivers

 Pick one up today in the adafruit shop!
 ------> http://www.adafruit.com/category/63_98

 This example is for a 128x64 pixel display using I2C to communicate
 3 pins are required to interface (two I2C and one reset).

 Adafruit invests time and resources providing this open
 source code, please support Adafruit and open-source
 hardware by purchasing products from Adafruit!

 Written by Limor Fried/Ladyada for Adafruit Industries,
 with contributions from the open source community.
 BSD license, check license.txt for more information
 All text above, and the splash screen below must be
 included in any redistribution.
 **************************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

SoftwareSerial mySerial(2,3);//Purple Tx / White Rx

void setup() {
  mySerial.begin(9600);
  Serial.begin(9600); 

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  //Set up bluetooth device name and role etc
  //initBluetooth();

  //Screen 1
  startupScreen();
  delay(5000);

  //Screen 2
  versionScreen();
  delay(5000);

  commandScreenHeader();
  delay(100);
  //Screen 3 - Start to test the BT device
  commandScreen("AT+NAMEalexbt2", "+NAMEalexbt2", "OK");
  delay(5000);

  //Screen 4
  NextScreen();
  delay(5000);

  commandScreenHeader();
  delay(100);
  //Screen 5 - Second test
  commandScreen("AT+ROLE0", "+ROLE0", "OK");

}

void loop() {

  //checkSerial();
  
}

//**** Send commands to BT device
void sendCommand(const char * command) {
//String Success = "";
  //Serial.print("Command send :");
  //Serial.println(command);
  //mySerial.println(command); //Send command to BT Device
  //wait some time
  //delay(100);
/*
  char reply[100];
  int i = 0;
  while (mySerial.available()) {
    reply[i] = mySerial.read();
    i += 1;
  }
  //end the string
  reply[i] = '\0';
  //Serial.print(reply); //Print reply to Sketch Serial Monitor
  Success = reply;
  */
  //Serial.println("Reply end");
  delay(50);

  commandScreen("AT+NAMEalexbt2", "+NAMEalexbt2", "OK");
  //commandScreen("SentCommand", "CommandVerifucation", "Success");
}

void initBluetooth(){
  //Set Serial baud rates
  //mySerial.begin(4800);
  //Serial.begin(4800); 

  //Set up the BT accordingly
  
  //sendCommand("AT");
  
  sendCommand("AT+ROLE0");
  /*
  sendCommand("AT+UUID0xFFE0");
  sendCommand("AT+CHAR0xFFE1");
  sendCommand("AT+NAMEalexbt2"); //Set the name of the Bluetooth device to alexbt2. 
  */
  //This name is hard coded into the iPhone App
  //sendCommand("AT+HELP"); 
  //Delay for 3 seconds
  //delay(3000);
}


void NextScreen() {
  display.clearDisplay();
  display.setTextSize(2);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
  display.println(F("NEXT......")); 
  display.drawLine(0, 16, 127, 16, SSD1306_WHITE); 
  display.display(); 
}

void versionScreen() {
  display.clearDisplay();
  display.setTextSize(2);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
  display.println(F(" Alex Weir")); 
  display.drawLine(0, 16, 127, 16, SSD1306_WHITE);  
  display.setCursor(0,20);           
  display.println(F(" Bluetooth"));
  display.println(F("  Tester"));
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE); 
  display.setCursor(0,47);  
  display.println("");
  display.println("---- Version 1.1 ----");
  display.display();
  //delay(5000);
}

void startupScreen() {
  display.clearDisplay();
  display.setTextSize(3);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(25,0);             // Start at top-left corner
  display.println(F("SBSS")); 
  display.setTextSize(2);            
  display.println(F(" December"));
  display.println(F("   2024"));
  display.setTextSize(1); 
  display.println(F("   COPYRIGHT 2024"));
  display.display();
  //delay(5000);
}

void commandScreenHeader(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.setCursor(3,0);
  display.println("BT COMMAND");
  display.drawLine(0, 16, 127, 16, SSD1306_WHITE); 
  display.display();
}
void commandScreen(String Cmnd, String St, String OC){
  display.setCursor(0, 23);
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.println("SEND: " + Cmnd);

  display.setCursor(0, 34);
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.print("SENT: " + St);

  display.setCursor(0, 45);
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.print("REPLY: " + OC);
 
  display.display();
}

/*
  For use with HM-10 BLE Bluetooth Module
  When uploading the name seems to change. Sometimes leaves out the 2 from alexbt2
  The software on the lights app accommodates this.  
*/

char c = ' ';
boolean NL = true;
boolean AWReceived = false;
String Msg = "";
String LightSequence = ""; 
int LightSequenceDelay = 200; //Initial delay
long randNumber = 0; //Used for Random light sequence
long randNumber2 = 0; //Used for Random light sequence

String SentCommand = "";
String CommandVerifucation = "";
String Success = "";



void updateSerial(){
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
  
}

void TestmySerialRead(){
  if (mySerial.available())
    Serial.write(mySerial.read());
}

void checkSerial(){
  if (mySerial.available()) //If BT available
    {
        //The iOS app sends the string with a # at the end of it. The string is built
        //character by character (Msg) until the # is reached and then the complete message
        //is received. 

        //Read the a character
        c = mySerial.read();
        if (c == '#')
        {
          //The # received so message is completed - Msg
          Serial.print("FROM BLE: " + Msg);
          Serial.write("\n");

          //Get light sequence request received from iPhone as Msg or delay value
          if(isNumeric(Msg) == true){
            //Is numeric. Do whatever before Msg is set to ""
          }else{
            //If not numeric. Do whatever before Msg is set to ""
          }
          //Full message complete and processed, so set Msg to nothing
          Msg = "";
        }else{
          // No # received so carry on building the string
          Msg = Msg + c;
        }
    }

}

// check a string to see if it is numeric and accept Decimal point
bool isNumeric(String str) {
  for (byte i = 0; str[i]; i++)
  {
    Serial.print(str[i]);
    if (!isDigit(str[i])) return false;
  }
  return true;
}

boolean isDigit(char c) {
  return (((c >= '0') && (c <= '9')));
}




Impossible to tell from the bits of code in your post, but I would highly suspect you are using too much dynamic memory (ram).

The second video shows you are using the Adafruit display library, that needs 1024 bytes of ram at run-time for a display buffer, which is in addition to what the compiler shows as dynamic memory usage. Additionally, you use the String data type, which will consume some of the remaining ram.

String length issue. If you delete a few characters from arguments 0 and/or 1, your code will run without the "alexbt2" page being "blank"

  commandScreen("AT+NAMEalexbt2", "+NAMEalexbt2", "OK"); // original FAILS
  commandScreen("AT+Nalexbt2", "+alexbt2", "OK"); // FAILS see "N"
  commandScreen("AT+alexbt2", "+alexbt2", "OK"); // WORKS

Not so much the String length, but the use of ram by the String itself. Better to use char arrays instead.

Using the U8g2 library with a page buffer instead of the Adafruit_SSD1306 library will also save a considerable amount of memory.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.