Library for 128x64 I2C

I bought this module: https://store.ncd.io/product/oled-128x64-graphic-display-i2c-mini-module/

I am upgrading a project that previously used this module: https://www.adafruit.com/product/931

But I am having difficulty getting the new display to behave.

At this time, I have not changed any code.

If I don't plug in the weather sensors, then the screen will display as the program intends/commands for it to display. As soon as I plug the weather sensors in, the arduino/program freezes.

I am using an Arduino Pro Mini (5V/16M) as the host.

Part of me wants to think this is a data conflict, but since the display works by itself, I assume that I can rule out an addressing or command issue?

I get Booting1 and Booting2 in Serial Monitor, but no Booting3.

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

  Serial.println("Booting1");
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  display.display();
  delay(500);
  display.clearDisplay();

  Serial.println("Booting2");
  
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Booting Up");
  display.display();
  Serial.println("Booting3");

  delay(5000);

}

If i start commenting things out, I find out that it hangs at display.display(). Setting the text color, size, origin works fine. If I change the address from 3C to 3D, the display does not turn on but the program runs as it should properly in serial monitor. If i use 3C but change the 1306.h file from 128x32 to 128x64, the program still freezes, and I get this error at compile:

Sketch uses 24,322 bytes (79%) of program storage space. Maximum is 30,720 bytes.
Global variables use 2,040 bytes (99%) of dynamic memory, leaving 8 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.

So i basically just need guidance for modifying the library for twice the lines and fix this issue. I am hoping somebody here can be of assistance. I am strictly writing text. I don't need the fancy adafruit boot graphic or anything else.

Hi, Can you please post your complete code, including how you are powering the ProMini and the peripherals.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :)

I’m using NCD CPS120 and SHT30 boards, plus the display linked above. They connect i2c using 4-pin ribbon cables. I de-pinned one connector to connect to pin (tack-soldered) on the Pro Mini.

I’m powering the Pro-Mini using the 5V FTDI cable.

I figured out a few things, specifically that I had to enable the jumper pull-ups for i2C to get the screen to command. However, I am wondering if I am indeed encountering buffer overrun.

This first block of code work. The code that I have attached does not. The only difference is that my test file is just reading the 2 sensors and writing it to the screen (19k program, 1.7k memory), while my long program does a big pile of math on the 2 sensor readings (24.5k program, 2.0k memory).

/*********************************************************************
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 size display using I2C to communicate
3 pins are required to interface (2 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.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

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

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

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

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);
}


void loop() {

// Clear the buffer.
  display.clearDisplay();

  // text display tests
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
    static String tempHum = SHT30();
    static String temp = tempHum.substring(0,tempHum.indexOf("*"));
    static String hum = tempHum.substring(tempHum.indexOf("*")+1);
    int temperatureC = temp.toInt();
    float temperatureK = temperatureC + 273.15;
    int temperatureF = int(((temperatureC * 9)/5) + 32);
  display.print(temperatureF);
  display.print(" F, ");
  display.print(hum);
  display.println("%");
    float pascals = CPS120(); // in pascals
    float atm = pascals / 101325; // "standard atmosphere atms"
    float baro_millibars = pascals / 100;
    float baro_inHg = pascals * 0.0002953;
  display.print("B ");
  display.print(baro_inHg);
  display.println("\"");
  display.display();
  delay(10000);
  display.clearDisplay();
  display.display();

delay(1000);
  
}

String SHT30() {

  static byte state;
  static long temp1;
  static long temp2;
  static double temperature;
  static long hum1;
  static long hum2;
  static int humidity;
  static int buff[6] = {0,0,0,0,0,0};
  //static int address = 0x44;
  String output = "";

  Wire.beginTransmission(0x44);
  Wire.write(0x27);
  Wire.write(0x37);

  state = Wire.endTransmission();
  if (state != 0){
    //Report sensor failure
    Serial.println("SHT30 Failure");
    return "0";
  } 
  
  delay(10);
  Wire.requestFrom(0x44,6);
  delay(50);

  buff[0] = Wire.read();
  buff[1] = Wire.read();
  buff[2] = Wire.read();
  buff[3] = Wire.read();
  buff[4] = Wire.read();
  buff[5] = Wire.read();

  temp1 = (buff[0] * long(256));
  temp2 = temp1 + buff[1];
  temperature = int((temp2*0.00267) - 45);
  
  hum1 = buff[3]*long(256);
  hum2 = hum1 + buff[4];
  humidity = int(hum2*0.001526);

  output = String(temperature) + "*" + String(humidity);

  return ( output );
  
}

double CPS120(){

  //static int address = 0x28;
  static byte state;
  static int buff[2] = {0,0};
  float barometer;
  static long baro1;
  static long baro2;

  Wire.beginTransmission(0x28);
  Wire.write(0x80);

  state = Wire.endTransmission();
  if (state != 0){
    //Report sensor failure
    Serial.println("CPS120 Failure");
    return 0;
  } 

  delay(10);
  Wire.requestFrom(0x28,2);
  delay(50); 

  buff[0] = Wire.read();
  buff[1] = Wire.read();

  baro1 = buff[0] & 0x3F;
  baro1 = baro1* 256;
  baro2 = baro1 + buff[1];
  barometer = 1000 * ((( baro2 / 16384.00)*90) + 30) ;
 
  //Serial.print(barometer); 
  //Serial.print(" pascal = ");

  return barometer;
  
}
(Test File)
Sketch uses 19,012 bytes (61%) of program storage space. Maximum is 30,720 bytes.
Global variables use 1,690 bytes (82%) of dynamic memory, leaving 358 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.
(Actual Program)
Sketch uses 24,368 bytes (79%) of program storage space. Maximum is 30,720 bytes.
Global variables use 2,046 bytes (99%) of dynamic memory, leaving 2 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.

Wx-Station-V4.ino (10.2 KB)

Through troubleshooting, I think it was a memory issue.

This code now works (after alot of thinning)

/*********************************************************************
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 size display using I2C to communicate
3 pins are required to interface (2 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.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

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

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

void setup()   {                
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
  delay(2000);
}


void loop() {

    float temperatureC = SHT30T();
    int temperatureF = int(((temperatureC * 9)/5) + 32);
    float temperatureK = temperatureC + 273.15;

    float humidity = SHT30H();
  
    float pascals = CPS120(); // in pascals
    float baro_inHg = pascals * 0.0002953;
    float baro_millibars = pascals / 100;
    float atm = pascals / 101325;

    float vaporPres = vapor(temperatureC);
    float vaporInHg = vaporPres / 33.86;
    float vaporPres2 = vaporInHg * (humidity/100);
    float vaporInHg2 = vaporPres2 / 33.86;

    float dewPointC = (243.5 * log(vaporPres2/6.112))/(17.67 - log(vaporPres2/6.112));
    float dewPointF = (dewPointC * (9/5)) + 32;

    float virTemp_r = virTemp(baro_millibars,vaporPres,temperatureK);

    int wgrains = int(grains(vaporPres2, atm, temperatureC) * (humidity/100.00)); 

    //int airDensity_r = int(airDensity(baro_inHg,virTemp_r));
    int airDensity_r = int(airDensity(baro_inHg,temperatureF));
    
    
    display_OLED(temperatureF, int(humidity), baro_inHg, vaporInHg2, int(dewPointF), wgrains, airDensity_r);
  
}

void display_OLED(int tempF, int hum, float baro, float vapor, int dewPoint, int grains, int DA){

      Serial.print("Sending to Display: ");
      Serial.print(tempF);
      Serial.print(",");
      Serial.print(hum);
      Serial.print(",");
      Serial.print(baro);
      Serial.print(", ");
      Serial.print(vapor);
      Serial.print(", ");
      Serial.print(dewPoint);
      Serial.print(", ");
      Serial.print(grains);
      Serial.print(", ");
      Serial.println(DA);

      // text display tests
      display.setTextSize(2);
      display.setTextColor(WHITE);

  for (int i=0;i<5;i++){

      display.clearDisplay();
      display.setCursor(0,0);
      
      display.print("T ");
      display.print(tempF);
      display.println(" F");

      display.print("H ");
      display.print(hum);
      display.println("%");
      
      display.print("B ");
      display.print(baro);
      display.println("\"");
      display.display();

      display.print("DA ");
      display.print(DA);
      display.display();
      
      delay(5000);
      
      display.clearDisplay();
      display.setCursor(0,0);
      
      display.print("V ");
      display.print(vapor);
      display.println("\"");
      display.display();
      
      display.print("DP ");
      display.print(dewPoint);
      display.println(" F");
      display.display();

      display.print("G ");
      display.print(grains);
      display.println("");
      display.display();

      display.print("DA ");
      display.print(DA);
      display.display();
      
      delay(5000);

  }

  return;
}

float SHT30T() {

  static byte state;
  static long temp;
  static float temperature;
  static int buff[6] = {0,0,0,0,0,0};

  Wire.beginTransmission(0x44);
  Wire.write(0x27);
  Wire.write(0x37);

  state = Wire.endTransmission();
  if (state != 0){
    //Report sensor failure
    Serial.println("SHT30 Failure");
    return 0.0;
  } 
  
  delay(10);
  Wire.requestFrom(0x44,6);
  delay(50);

  buff[0] = Wire.read();
  buff[1] = Wire.read();
  buff[2] = Wire.read();
  buff[3] = Wire.read();
  buff[4] = Wire.read();
  buff[5] = Wire.read();

  temp = (buff[0] << 8) | buff[1];
  temperature = (temp*0.00267) - 45;

  Serial.print("Temp: ");
  Serial.println(temperature);
  return ( temperature );
  
}

float SHT30H() {

  static byte state;
  static long hum;
  static float humidity;
  static int buff[6] = {0,0,0,0,0,0};

  Wire.beginTransmission(0x44);
  Wire.write(0x27);
  Wire.write(0x37);

  state = Wire.endTransmission();
  if (state != 0){
    //Report sensor failure
    Serial.println("SHT30 Failure");
    return 0.0;
  } 
  
  delay(10);
  Wire.requestFrom(0x44,6);
  delay(50);

  buff[0] = Wire.read();
  buff[1] = Wire.read();
  buff[2] = Wire.read();
  buff[3] = Wire.read();
  buff[4] = Wire.read();
  buff[5] = Wire.read();
  
  hum = (buff[3] << 8) | buff[4];
  humidity = hum*0.001526;

  Serial.print("Hum: ");
  Serial.println(hum);
  Serial.print("Humidity: ");
  Serial.println(humidity);
  return ( humidity );
  
}

float CPS120(){

  //static int address = 0x28;
  static byte state;
  static int buff[2] = {0,0};
  float barometer;
  static long baro1;

  Wire.beginTransmission(0x28);
  Wire.write(0x80);

  state = Wire.endTransmission();
  if (state != 0){
    //Report sensor failure
    Serial.println("CPS120 Failure");
    return 0;
  } 

  delay(10);
  Wire.requestFrom(0x28,2);
  delay(50); 

  buff[0] = Wire.read();
  buff[1] = Wire.read();

  baro1 = ((buff[0] & 0x3F) << 8) | buff[1];
  barometer = 1000 * ((( baro1 / 16384.00)*90) + 30) ;

  Serial.print("Baro: ");
  Serial.println(barometer);
  return barometer;
  
}

float vapor(float tempC){ // Saturated

  float power = (7.5 * tempC) / (237.3 + tempC);
  float saturated = 6.1078 * pow(10,power);
        
        Serial.print("saturated: ");
        Serial.println(saturated);
        return saturated;

}

float virTemp(float millibar,float vapor,float tempK){

  float denom = (1 - ((vapor / millibar) * 0.378));
  float virTemp = tempK / denom;
        virTemp = ((9/5) * (virTemp - 273.15) + 32) + 459.69;
  return virTemp;

}

float grains(float vapor, float atm, float tempC){
 
        float atmPres = atm * 14.696;
        float power = 8.07131 - ( 1730.63 / (233.426 + tempC));
        float vaporPres = 0.0193367747*(pow(10,power));
        float waterGrains = (((7000*18.02)/28.85) * vaporPres) / (atmPres - vaporPres);
        
        return waterGrains;
  
}

float airDensity(float inHg,float airTemp){

  float inner = (17.326 * inHg) / (airTemp+459.67);
  float middle = 1 - pow(inner,0.235);
  float density = 145366 * middle;
  return density;

}
Sketch uses 17,290 bytes (56%) of program storage space. Maximum is 30,720 bytes.
Global variables use 1,731 bytes (84%) of dynamic memory, leaving 317 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.