0.96 OLED not updateing content - Adafruit SSD1306

Hello,

I'm have an 0.96 OLED Display (like this one).

I use the "Adafruit_SSD1306" library.
The example code works fine, but I can't seem to get it to work outside the "void setup"

I found a few examples, but most of them use code to display in there setup or use a different screen / library.

Sort intro what I'm trying to do:
Check 2 temperatures, compare them, turn a relay on or off and display the temperature and relay status to the LCD.

My Problem:
The display stays black, after it displayed the logo.
The Serial Monitor only outputs 3 blank lines, where it is suppose to show the Display content.

My code:

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

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
// http://www.pjrc.com/teensy/td_libs_OneWire.html
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

// If using software SPI (the default case):
#define OLED_MOSI   9 //D1
#define OLED_CLK   10 //D0
#define OLED_DC    11 //DC
#define OLED_CS    12 //CS
#define OLED_RESET 13 //RES
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

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

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16

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

OneWire  ds(8);  // on pin 8 (a 4.7K resistor is necessary)
const int relaispin = 5;
bool ticktock = TRUE;
float tempout, tempin, tempinzone;
float tempdiv = 2;
bool relais = FALSE;
String relaistxt = "off";
String firstline = "firstline";
String secondline = "secondline";
String thirdline = "thirdline";


void setup(void) {
  Serial.begin(9600);
  pinMode(relaispin, OUTPUT);
  display.begin(SSD1306_SWITCHCAPVCC);
  display.display(); // show splashscreen
  delay(1000);
  display.clearDisplay();   // clears the screen and buffer 
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;

  if ( !ds.search(addr)) {
    ds.reset_search();
    delay(250);
    return;
  }
  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
  }
  ds.reset();
  ds.select(addr);
  ds.write(0x44);
  delay(1000); 
  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE); 
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }
  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;

  if (ticktock) {
    tempout = celsius;
    ticktock = FALSE;
  }
  else {
    tempin = celsius;
    ticktock = TRUE;
  }
  tempinzone = tempin + tempdiv;
  if (tempout > tempinzone) {
    relais = TRUE;
    digitalWrite(relaispin, HIGH);
  }
  else {
    relais = FALSE;
    digitalWrite(relaispin, LOW);
  }
  Serial.print("  Temperature = ");
  Serial.print(tempin);
  Serial.print(" Celsius insite and ");
  Serial.print(tempout);
  Serial.print(" Celsius outsite. The Relais is");
  if (relais) {
    Serial.println(" on.");
  }
  else {
    Serial.println(" off.");
  }
  char buffer[5];
  String tempintxt = dtostrf(tempin, 5, 1, buffer);
  String tempouttxt = dtostrf(tempout, 5, 1, buffer);
  String firstline = "IN: " + tempintxt;
  String secondline = "OUT: " + tempouttxt;
  if (relais) {
    relaistxt = " on";
  }
  else {
    relaistxt = "off";
  }
  String thirdline = "Fan: " + relaistxt;

  Serial.println(firstline);
  Serial.println(secondline);
  Serial.println(thirdline);

  // display text
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println(firstline);
  display.println(secondline);
  display.println(thirdline);
  display.display();
  delay(2000);
  display.clearDisplay();
}

And the Serial Output:

  Temperature = 28.50 Celsius insite and 29.50 Celsius outsite. The Relais is off.



  Temperature = 28.50 Celsius insite and 29.50 Celsius outsite. The Relais is off.



  Temperature = 28.50 Celsius insite and 29.50 Celsius outsite. The Relais is off.

Thank you,
Alex

Try these out and see if they help.

Change:

void loop(void) {

to

void loop() {

and try commenting out the very last line of your code

display.clearDisplay();

You shouldn't need to clear the display every pass through the loop. You are already resetting your cursor position to 0,0 each pass through the loop, so whatever has been written to the screen from the last pass will be overwritten with the data from the current pass. You don't have to clear it manually.

Matt

EDIT: I'm new but trying to help! After looking at these above again, I'm not sure if they will fix your OLED problems. The syntax for your "Strings" doesn't look right to me, and they are common to both the serial monitor and OLED outputs, so you might look there.

Hello Matt,

I will give that a try as soon as I get home.
(sorry didn't have notification enabled for the Forum yet)

Cheers,
Alex

Hey Matt,
I did the changes you recommended, but as you expected yourself, id didn't fix the problem.
I used the library example to get one working, but in that version, all the display stuff is done in the setup method.

I'll debug step by step and see if that helps.

EDIT: -- got it to work --

Your reference to the serial output gave me the idea to just use the same format and it worked.
The clear display is required, as otherwise the text overlay's each other.

here is my working code:

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

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
// http://www.pjrc.com/teensy/td_libs_OneWire.html
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

// If using software SPI (the default case):
#define OLED_MOSI   9 //D1
#define OLED_CLK   10 //D0
#define OLED_DC    11 //DC
#define OLED_CS    12 //CS
#define OLED_RESET 13 //RES
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

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

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16

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

OneWire  ds(8);  // on pin 8 (a 4.7K resistor is necessary)
const int relaispin = 5;
bool ticktock = TRUE;
float tempout, tempin, tempinzone;
float tempdiv = 2;
bool relais = FALSE;
String relaistxt = "off";
String firstline = "firstline";
String secondline = "secondline";
String thirdline = "thirdline";


void setup(void) {
  Serial.begin(9600);
  pinMode(relaispin, OUTPUT);
  display.begin(SSD1306_SWITCHCAPVCC);
  display.display(); // show splashscreen
  delay(1000);
  display.clearDisplay();   // clears the screen and buffer 
}

void loop() {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;

  if ( !ds.search(addr)) {
    ds.reset_search();
    delay(250);
    return;
  }
  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
  }
  ds.reset();
  ds.select(addr);
  ds.write(0x44);
  delay(1000); 
  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE); 
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }
  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;

  if (ticktock) {
    tempout = celsius;
    ticktock = FALSE;
  }
  else {
    tempin = celsius;
    ticktock = TRUE;
  }
  tempinzone = tempin + tempdiv;
  if (tempout > tempinzone) {
    relais = TRUE;
    digitalWrite(relaispin, HIGH);
  }
  else {
    relais = FALSE;
    digitalWrite(relaispin, LOW);
  }
  Serial.print("  Temperature = ");
  Serial.print(tempin);
  Serial.print(" Celsius insite and ");
  Serial.print(tempout);
  Serial.print(" Celsius outsite. The Relais is");
  if (relais) {
    Serial.println(" on.");
  }
  else {
    Serial.println(" off.");
  }
  // display text
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("IN: ");
  display.println(tempin);
  display.print("OUT:");
  display.println(tempout);
  display.print("Fan: ");
  if (relais) {
    display.println("on");
  }
  else {
    display.println("off");
  }
  display.display();
  delay(2000);
  display.clearDisplay();
}

Thanks,
Alex