Cannot run LCD and OLED display concurrently

Hi! I wonder if any one can help with this problem please?

I have built a supply voltage checker and display. The code is intended to display the measured voltage on an LCD and OLED displays at the same time. (The idea was to send it to my son to show how both worked whether he used an LCD or OLED display.) In practice only the LCD displays the voltage UNLESS I comment out all the bits about the LCD screen, and the Oled works as designed.

I am guessing there is some sort of address conflict but an i2s address checker shows two devices at 0x27 and 0x3C and by disconnecting them, they are the LCD and OLED displays.

I cannot get the Oled to display as well. Any suggestions would be very helpful. Here is my code:

/* Battery_Checker.io

  This sketch displays the supply voltage up to a maximum on 25 Volts. It is written as a called procedure so you can copy
  it into another sketch or add additonal code for other functions.

  The following libraries are required:

    LiquidCrystal I2C by Marco Schwarz or the Arduino Sensor Kit if the OLED screen is to be used.

    ArduinoSensorkit


  Three LEDs are required: Red; Blue and Green, to indicate over voltage; under voltage and sufficient voltage from the supply.

  If it is rerquired for the Arduino to be shut down to protect it from over voltage supply, pin D7 must be connected to the
  relay shown in the circuit diagram in Battery_Checker.pdf.

  IMPORTANT: This sketch works with a 20x4 or a 16x2 character LDC screen via an I2C interface, or the Arduino Sensor Kit OLED
  screen. Be sure to uncomment out the screen required and comment out the unrequired screens.


  The following options are included:

    1. Minimum voltage warning (useful for LiPo and lead-acid batteries that must not be discharged below a specified voltage.)
    2. Over voltage warning.
    3. Optional add on circuit to power down the attached Arduino device to protect excessively discharging a battery and
       excess supply voltage from damaging the Arduino.


  LCD and OLED Connections:        Battery Test Connections:                          LED Connections:

  GND - GND                         R1 4.7K between A3 and supply voltage.            Red LED from D2 via 330R to Ground.
  Vcc - 5V                          R2 1.2K between GND and A3.                       Blue LED from D3 via the same 330R to Ground.
  SDA - Pin A4                      (use the Arduino's regulated 5V for tests.)       Green LED from D4 via the same 330R to Ground.
  SCL - pin A5

  Measure the voltage between the supply and ground with a digital multimeter and adjust the fraction (100/100) in line 49 until
  the LCD display value agrees with the multimeter.
*/

#include <Arduino_SensorKit.h>                                // Required to run the OLEDscreen.
#include <LiquidCrystal_I2C.h>                                // Required to run the LCD screens via the I2C piggy back board.
// LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);    //Addresses the 20x4 character LCD.
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);      //Addresses the 16x2 character LCD.

float MinSupplyVoltage = 9;         // This is the miminum regulatable voltage for an Arduino Uno. Adjust for the battery used.
float MaxSupplyVoltage = 13;        // !! piut back to 20V This is the maximum external input voltage for the Arduino Uno. Adjust for the specific model.
unsigned int SupplyVoltage = 0;
float correctionFactor = (100/100); // Change the values of this fraction to compensate for inaccuracies in R1 and R2.


void setup()
{
  pinMode(2, OUTPUT); // Red LED on pin D2.
  pinMode(3, OUTPUT); // Blue LED on pin D3.
  pinMode(4, OUTPUT); // Green LED on pin D4.
  pinMode(7, OUTPUT); // From pin D7 to supply relay.

  lcd.init();           // Initialises the LCD.
  lcd.backlight();      // Turns on the backlight.
  lcd.begin(16, 2);     // Tells the lCD it is a 16x2 display. (you'd think it would know!)
  // lcd.begin(20, 4);    // Tells the LCD it is a 20x4 display.
  lcd.clear();          // Clears the screen, just in case.

  //Uncomment this section if an OLED screen is to be used AND comment out the section above.
  Oled.begin();
  Oled.setFlipMode(true);
  //
}


void loop()
{
  //... Replace this line with the code you want to run...
  checkBattery();   // This calls the checkBattery function below. Once the function has competed it returns to continue from the line below.
  //... and replace this line with any other code you want to run...
  delay(100);      // Just because every sketch has one somewhere!
}


void checkBattery()
{
  digitalWrite(2, LOW); // Ensures all of the LEDs and the relay are off.
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(7, LOW);

  SupplyVoltage = analogRead(A3);        // Reads the supply voltage.
  SupplyVoltage = correctionFactor * (map(SupplyVoltage, 0, 1023, 0, 250)); // The last value 250' is 'Maximum accepted input voltage * 10.)

  if (SupplyVoltage / 10 > MaxSupplyVoltage) { // The maximum external supply for the Arduino Uno is 20V, so set to 19V.
    digitalWrite(2, HIGH);       //RED
    delay(500);
    digitalWrite(7, HIGH);       // Opens the NC (normally closed) relay on the supply.
    digitalWrite(2, LOW);        // This line is redundant if the relay depowers the Arduino. Left in in case it fails!
  }
  if (SupplyVoltage / 10 >= MinSupplyVoltage and SupplyVoltage <= MaxSupplyVoltage ) ; {
    digitalWrite(4, HIGH);  //GREEN
  }
  if (SupplyVoltage / 10 < MinSupplyVoltage) {
    digitalWrite(3, HIGH);  //BLUE
  }

  lcd.setCursor(0, 0);                   //Sets the start position on the LCD screen. The format is (column, row).
  lcd.print("Battery: ");
  if (SupplyVoltage < 100) {
    lcd.print(" ");
  }
  if (SupplyVoltage < 10) {
    lcd.print(" ");
  }
  lcd.print((SupplyVoltage / 10), DEC); // The command DEC ensures the value is decimal.
  lcd.print(".");
  lcd.print((SupplyVoltage) % 10, DEC);
  lcd.print("v");

  // Uncomment this section if an OLED screen is to be used AND comment out the LCD code above.
  Oled.clearDisplay();  // !! May not be needed !!
  Oled.setFont(u8x8_font_chroma48medium8_r);
  Oled.setCursor(0, 3);
  Oled.print("Batt: ");
  Oled.print(SupplyVoltage/10);
  //
}

with many thanks

I didn't see the OLED version of:

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); //Addresses the 16x2 character LCD.

Your attempt at code tags did not work. Suggest you use the </> from the window ribbon.

Did the compiler give any warnings about the size of the whole thing ?
Can you find a more specific library for your oled display. Arduino_SensorKit.h appears to bring in a lot of clutter with it which you do not appear to be using.


Not where I can look at the library at the moment, but guessing the Adafruit library uses their Adafruit_GFX library to run the display, try putting Oled.display(); after the last Oled statement.

Sorry, read the sketch wrong, I see you are using Arduino Sensor Kit and not Adafruit.

Thanks David_2018 - It might be a lot better for me to use the Adafruit library. So I shall give it a go!

Hi John! Thanks for your reply. I've finally managed to sort out the proper way of showing my code! Thank you for the heads up - SteveS

Hi 6v6GT (Presumably a thermionic valve fan!) - There were no errors on compilation but I shall try the Adafruit library, since as you say the Arduino sensor library brings in a lot of other stuff I do not need. - Thanks for the suggestion - SteveS

Attached is the code I used to prove I could display data to the OLED.

I only needed text and numerals (no graphics) so I used Bill Greiman's ASCII only library

It might help.

// Simple I2C test for ebay 128x64 oled.
// Uses the standard Wire.h class as we think the BME680 will already use wire. was: Use smaller faster AvrI2c class in place of Wire.
// Edit AVRI2C_FASTMODE in SSD1306Ascii.h to change the default I2C frequency.
// 2019-05-17 added Bill Greiman's comment regarding the addition of "Wire.begin()"  now working at 100Khz

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

#define I2C_ADDRESS 0x3C	// 0x3C alt add = 0x3D
SSD1306AsciiWire oled;		// create an "oled" object

//------------------------------------------------------------------------------
// Setup displays variable names and units.
//  We still have to identify the location and length for variable values.
//  We should in the future create functions to do the length and position calc.

void setup() {

  Wire.begin();
  Wire.setClock(100000);
  
  oled.begin(&SH1106_128x64, I2C_ADDRESS);
  oled.setFont(ZevvPeep8x16);  // results in 4 lines X 16 characters
  oled.clear();

// Fill display so we can see what is being cleared.
  oled.println("----------------");
  oled.println("----------------");
  oled.println("----------------");
  oled.println("----------------");
  delay(1000);

//							  (C,R)
  oled.SSD1306Ascii::setCursor(0,0);
  oled.print("Temp");				// leaves cursor at next char in row.
  oled.SSD1306Ascii::setCursor(8*14,0);
  oled.print("$F");
  oled.clearField(8*4,0,10);

  oled.SSD1306Ascii::setCursor(0,2);	// note rows are 8 pixels and our font is 16 pixels
  oled.print("Humidity");				// leaves cursor at next char in row.
  oled.SSD1306Ascii::setCursor(8*15,2);
  oled.print("%");
  oled.clearField(8*8,2,7);
  
  oled.SSD1306Ascii::setCursor(0,4);
  oled.print("Pressure");				// leaves cursor at next char in row.
  oled.SSD1306Ascii::setCursor(8*13,4);
  oled.print("hPa");
  oled.clearField(8*8,4,5);
 
  oled.SSD1306Ascii::setCursor(0,6);
  oled.print("IAQ   both");				// leaves cursor at next char in row.
  oled.clearField(8*3,6,13);
} 

void loop() {}