[SOLVED] OLED display not initializing

Bit of a strange one.

I am adding an oled screen into my project, serial information works fine but oled screen will not initialize. The screen works fine in a basic oled screen test sketch on it's own but does not work when introduced into my project. When I add display information in the loop it just seems to stop everything from doing what it is supposed to. Just seems a bit strange but I must be missing something.

Any ideas?

// Servo side

#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <BMP180MI.h>
#include <Servo.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Fonts/FreeSans9pt7b.h>

#define CE_PIN   7
#define CSN_PIN 8
#define GREEN 6
#define RED 5
#define I2C_ADDRESS 0x77

// OLED display TWI address
#define OLED_ADDR   0x3C
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     0 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


Servo myservo;  // create servo object to control a servo

int button1;
int button2;

int led1 = RED;
int led2 = GREEN;

int angle =180;    // initial angle  for servo
int angleStep =180;

BMP180I2C bmp180(I2C_ADDRESS);
RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};

struct data
{
  int button1State;
  int button2State;
} receivedData;

bool newData = false;

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second

// test data *******************************
float val2;
float temperature;
char dataToSend[20];

int val11;

void setup() {
 
 
 Wire.begin();
  // initialize and clear display
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay();
  display.drawRect(0, 0, 128, 64, WHITE);
  display.display();
  
 
  
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);


myservo.attach(4);
myservo.write(angle);

 Serial.begin(9600);
 Serial.println("Test Starting");
 

 radio.begin();
  radio.openWritingPipe(addresses[1]); // 00001
  radio.openReadingPipe(1, addresses[0]); // 00002
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate( RF24_2MBPS );



 //begin() initializes the interface, checks the sensor ID and reads the calibration parameters.  
  if (!bmp180.begin())
  {
    Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
    while (1);
  }

  //reset sensor to default parameters.
  bmp180.resetToDefaults();

  //enable ultra high resolution mode for pressure measurements
  bmp180.setSamplingMode(BMP180MI::MODE_UHR);
}
//====================

  

void loop() {
  
  
radio.startListening();
    while (!radio.available());
    radio.read(&receivedData, sizeof(receivedData));
    if (receivedData.button1State == LOW) {
    // turn LED on:
    myservo.write(180);
    delay(500);
    digitalWrite(RED, HIGH);
  digitalWrite(GREEN, LOW);
} else  { if (receivedData.button2State == LOW) {
    // turn LED on:
    myservo.write(0);
    delay(500);
    digitalWrite(GREEN, HIGH);
    digitalWrite(RED, LOW);
}
}
radio.stopListening();
  

float temp ; //Float..
val11 = analogRead (1) ; //Sets analog pin 1 as input
temp = val11 / 3.930 ; //Val1 divided by 4.092
val11 = (int) temp ; //get float
val2 = ((val11 % 200) / 11.18 ); //Value divider line. I set to 200% to read from a 12 volt system with a divider value of 11.18
Serial.println (val2) ; //Prints to serial monitor window
   
  
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        makePacket(val2, temperature);
        send();
        prevMillis = millis();

        if (!bmp180.measureTemperature())
  {
    Serial.println("could not start temperature measurement, is a measurement already running?");
    return;
  }

  //wait for the measurement to finish. proceed as soon as hasValue() returned true. 
  do
  {
    delay(100);
  } while (!bmp180.hasValue());

  Serial.print("Temperature: "); 
  Serial.print(bmp180.getTemperature()); 
  Serial.println(" degC");

  
    }
}



//====================

void makePacket(float val2, float temp)
{
  // convert data to int for easier transmission
  int batteryInt = val2 * 100;
  int tempInt = bmp180.getTemperature() * 100;
  // make packet
  sprintf(dataToSend, "%d,%d", batteryInt, tempInt);
}

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        Serial.println("  Acknowledge received");        
    }
    else {
        Serial.println("  Tx failed");
    }
    
   
}

What is this?#define OLED_RESET    0 // Reset pin # (or -1 if sharing Arduino reset pin)

NanoSmurf:
Any ideas?

Use Ctrl-T to make your code readable.

Let loop loop.

Do not use delay for timing.

Do not add wrong comments to confuse the reader.

const byte addresses[][6] = {"00001", "00002"};

  radio.openWritingPipe(addresses[1]); // 00001
  radio.openReadingPipe(1, addresses[0]); // 00002

Do not wait for things, react to things happening.

Do not force the NRF through each step, process received packets when they arrive.

As a (mostly) listener, you should call startListening in setup and only switch to sending
when necessary and call startListening when done sending.

J-M-L:
What is this?#define OLED_RESET    0 // Reset pin # (or -1 if sharing Arduino reset pin)

It was in the sketch I got for the OLED.

Whandall:
Use Ctrl-T to make your code readable.

Let loop loop.

Do not use delay for timing.

Do not add wrong comments to confuse the reader.

const byte addresses[][6] = {"00001", "00002"};

radio.openWritingPipe(addresses[1]); // 00001
 radio.openReadingPipe(1, addresses[0]); // 00002



Do not wait for things, react to things happening.

Do not force the NRF through each step, process received packets when they arrive.

As a (mostly) listener, you should call startListening in setup and only switch to sending
when necessary and call startListening when done sending.

So, is any of that relevant to my question?

1 Like

NanoSmurf:
So, is any of that relevant to my question?

No, but does it make it less true?

NanoSmurf:

#define OLED_RESET     0 // Reset pin # (or -1 if sharing Arduino reset pin)

It was in the sketch I got for the OLED.

pin 0 is attached to the Serial communication... that sounds suspicious to me and the comment states making it -1 if sharing Arduino reset pin...

Now it probably depends on which Arduino you are.... it could relate to GPIO0?

J-M-L:
pin 0 is attached to the Serial communication... that sounds suspicious to me and the comment states making it -1 if sharing Arduino reset pin...

Now it probably depends on which Arduino you are.... it could relate to GPIO0?

Hi J-M-L, thanks for your reply. The only reason i left that in was because it was already in a working sketch but on removing it just now it makes zero difference to the program, so i'll just leave it out! I'm using a couple of nanos for this project -

https://forum.arduino.cc/index.php?topic=604244.msg4114365#msg4114365

Still no joy :slightly_frowning_face:

What does it mean « leave it out »?

J-M-L:
What does it mean « leave it out »?

I deleted this line -

#define OLED_RESET     0 // Reset pin # (or -1 if sharing Arduino reset pin)

Made zero difference to program so deleted it. Like I said, it was in an oled screen test sketch so I just assumed I needed it.

And you kept that line as is ?Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define OLED_RESET 0 // Reset pin # (or -1 if sharing Arduino reset pin)

Setting a unused pin to -1 can result in unpredictable program behaviour.

As I recently discovered.

srnet:
Setting a unused pin to -1 can result in unpredictable program behaviour.

As I recently discovered.

the -1 has obviously to be handled by the library if they write this in the spec.

J-M-L:
And you kept that line as is ?Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

I did but I deleted OLED_RESET as it wouldn't compile. Sorry, I meant to say that in my earlier post.

have you tried with -1 ?

J-M-L:
have you tried with -1 ?

I did but it made zero difference :slightly_frowning_face:

try to see what's really going on in your I2C bus between the master and slaves

It really is strange but there must be something I am clearly missing.

On uploading the I2C scanner sketch, it picks up both the bmp180 and the oled screen. If I upload the following sketch, with only the sensor and the screen, both work perfectly alongside each other. When I try to integrate it into my original program.... :slightly_frowning_face:

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <BMP180MI.h>
#include <Fonts/FreeSans9pt7b.h>

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

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

// OLED display TWI address
#define OLED_ADDR   0x3C

//create an BMP180 object using the I2C interface
BMP180I2C bmp180(I2C_ADDRESS);


int val11;
float val2;



void setup() {

  // initialize and clear display
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay();
  




  // put your setup code here, to run once:
	Serial.begin(9600);

	//wait for serial connection to open (only necessary on some boards)
	while (!Serial);

	Wire.begin();

	//begin() initializes the interface, checks the sensor ID and reads the calibration parameters.  
	if (!bmp180.begin())
	{
		Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
		while (1);
	}

	//reset sensor to default parameters.
	bmp180.resetToDefaults();

	//enable ultra high resolution mode for pressure measurements
	bmp180.setSamplingMode(BMP180MI::MODE_UHR);
}



void loop() {
  // put your main code here, to run repeatedly:

	delay(1000);

	//start a temperature measurement
	if (!bmp180.measureTemperature())
	{
		Serial.println("could not start temperature measurement, is a measurement already running?");
		return;
	}

	//wait for the measurement to finish. proceed as soon as hasValue() returned true. 
	do
	{
		delay(100);
	} while (!bmp180.hasValue());

	Serial.print("Temperature: "); 
	Serial.print(bmp180.getTemperature()); 
	Serial.println(" degC");

display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE, BLACK);
display.setCursor(10,25);
display.setTextSize(1);
display.println("Temp");
display.drawRect(0, 0, 128, 64, WHITE);

display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE, BLACK);
display.setCursor(70,25);
display.setTextSize(1);
display.println("Batts");

display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE, BLACK);
display.setCursor(10,49);
display.setTextSize(1);
display.println(bmp180.getTemperature());

display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE, BLACK);
display.setCursor(70,49);
display.setTextSize(1);
display.println(val2);

display.display();
display.clearDisplay();
 float temp;
      val11=analogRead(1);
      temp=val11/4.182;
      val2=(temp/10);
Serial.println(val2);

}

so adding the NRF and the Servo gets things ugly?

how is the whole thing powered?