1

I have a 0.96" OLED display hooked up to my Arduino Mega via SPI. I installed the Adafruit library and GFX library. I can run through the little graphical demo from Adafruit just fine as well as display static text with no problem.

However, I am trying to put together a project I thought would be simple and straight forward. I am trying to use a DHT22 to collect temperature and humidity and then display it on the OLED. The problem I am running into is that the Arduino freezes after an indeterminate amount of time. The most it has been able to run is about 6 minutes.

Here is the code I am using:

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

#define DHTPIN 7
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

// If using software SPI (the default case):
#define OLED_MOSI   8
#define OLED_CLK   9
#define OLED_DC    10
#define OLED_CS    11
#define OLED_RESET 12
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16

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

long previousMillis = 0;
long interval = 5000;

    String temperature;
    String humidity;

void setup(){    
  dht.begin();

  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC);

  display.clearDisplay();

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

  display.println(" Madgayrah");
  display.display();
  while(millis()<2000);
}


void loop() {

  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;

    float h = dht.readHumidity();
    float f = dht.readTemperature(true);

    if(isnan(h) || isnan(f)){
      int x = 6;
      String dashes = "";
      for(int y=1; y<=x; y++){
        dashes += "-";
      }
      temperature = humidity = dashes;
    }else{
      temperature = String(f)+(char)248;
      humidity = String(h)+"%";
    }

    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setCursor(0,0);

    display.setTextSize(1);
    display.println(String(previousMillis/1000));
    display.println("");

    display.println("Temperature:");
    display.setTextSize(2);
    display.println(temperature);

    display.setTextSize(1);
    display.println("Humidity:");
    display.setTextSize(2);
    display.println(humidity);

    display.display();
  }
}

In my attempt at debugging I discovered that NOT printing out the temperature and humidity variables allows the program to run indefinitely. However, for some reason turning on either one of those lines and printing out that variable leads to the issue of the Arduino freezing.

ADDITIONAL INFORMATION: I am using a 12 volt external power supply hooked up to the barrel of the Mega. The Mega is providing 5 volts and ground to a bread board which powers/grounds both the OLED and the DHT22.

Any ideas as to what could be causing the freezing issue on what "should be" a simple and straightforward project? Thanks.

2
  • How much current does the OLED pull? It may be too much to pull through the Arduino. It may need it's own power.
    – Delta_G
    Commented Jun 6, 2017 at 3:08
  • having a problem where even with watchdog the device never recovers until i unplug the LCD Commented Jul 22, 2020 at 2:32

2 Answers 2

5

Because your program uses various String objects in several different sizes, there's a good chance that heap memory (in RAM) is getting fragmented to the point that String allocation begins to fail, or begins to allocate on top of stack variables. (Typically, heap and stack work toward each other, from opposite ends of memory that is free after static variables are allocated.)

For example, the code for(int y=1; y<=x; y++){ dashes += "-"; } with x=6 creates half a dozen String objects, all of different lengths.

To avoid this problem, you could carefully release each heap allocated object when done with it, or more effectively, could avoid using String objects, which actually aren't needed in this program.

For example, instead of display.println(String(previousMillis/1000)); say display.println(previousMillis/1000); and instead of building dashes a character at a time before using it, just say "------" in place of dashes.

1

I had exact same problem and james's answer helped me realize the problem is related to heap memory.

In addition to what he has already commended, I found here that you should also wrap all your constant strings in F() function.

For example instead of

display.println(" Madgayrah");

You write

display.println(F(" Madgayrah"));

This will store the string in the flash memory instead of SRAM.

Also if you only use OLED display for printing text, I strongly recommend the more lightweight SSD1306Ascii library

It output text to oled display without buffering which causes slight flickering but massively reduce the amount of memory required to drive the OLED.

Another helpful tip is to use arduino's watchdog. Basically after you enable that you need to constantly call wdt_reset(); function and if you failed to call it for certain amount of seconds, arduino will automatically reset.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.