Arduino Nano Freezing with SSD1306 OLED library

The goal of this piece of code was to read data from a BMP280, MQ4, LDR and DHT22 sensors. Initially all the sensors are turned off state. When the value '1' is sent from the Serial monitor, the sensors are turned on via a transistor and reading is taken after certain interval of time. And when '0' is sent by the Serial monitor the sensors are turned off.

//Intended board Arduino Nano. 

#include <DHT_U.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <MQUnifiedsensor.h>

#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiWire oled;


/*
Hardware connections. Board; Arduino Nano. 
Analog Pins. 
-------------------------------------
A0   
A1   ldr 
A2   MQ4 output.
A3   DHT22 output. 
A4   SDA of BMP280
A5   SCL of BMP280
A6
A7

Digital Pins (PWM 3, 5, 6, 9, 10, 11)
-------------------------------------
D0(TX)     Software Serial RX A1 of arduino Uno
D1(RX)     Software Serial TX of A2 of Arduino Uno
D2
~D3
D4         Transistor switching pin. 
~D5
~D6
D7
D8
~D9
~D10
~D11
D12
D13

#define ldrPin A1


*/
// Use Ctrl+R to compile code. 

#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)
Adafruit_BMP280 bmp;  // I2C


#define powerPin 4
#define ldrPin A1
#define DHTPIN A3  // Digital pin connected to the DHT sensor
// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --
// Pin 15 can work but DHT must be disconnected during program upload.

// Uncomment the type of sensor in use:
//#define DHTTYPE    DHT11     // DHT 11
#define DHTTYPE DHT22  // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)
// See guide for details on sensor wiring and usage:
//   https://learn.adafruit.com/dht/overview

DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;



/************************Hardware Related MQ4 Macros************************************/
#define Board ("Arduino Nano")
#define Pin (A2)  //Analog input 4 of your arduino
/***********************Software Related MQ4 Macros************************************/
#define Type ("MQ-4")  //MQ4
#define Voltage_Resolution (5)
#define ADC_Bit_Resolution (10)  // For arduino UNO/MEGA/NANO
#define RatioMQ4CleanAir (4.4)   //RS / R0 = 60 ppm
/*****************************Globals***********************************************/
//Declare Sensor
MQUnifiedsensor MQ4(Board, Voltage_Resolution, ADC_Bit_Resolution, Pin, Type);


void initializeSensors()
{
    // Initialize humidity and temperature sensor. .
  dht.begin();
  // Print temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  dht.humidity().getSensor(&sensor);
 

  bmp.begin();
  /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

  //Set math model to calculate the PPM concentration and the value of constants
  MQ4.setRegressionMethod(0);  //_PPM =  pow(10, (log10(ratio)-b)/a)
  MQ4.init();
  //MQ-4 calibration
  float calcR0 = 0;
  for (int i = 1; i <= 10; i++) {
    MQ4.update();  // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ4.calibrate(RatioMQ4CleanAir);
  }
  MQ4.setR0(calcR0 / 10);

  //MQ-4 calibration error warnings.
  if (isinf(calcR0)) {
     //Serial.println("Warning: Conection issue, R0 is infinite (Open circuit detected) please check your wiring and supply");
      }
  if (calcR0 == 0) { 
    //Serial.println("Warning: Conection issue found, R0 is zero (Analog pin shorts to ground) please check your wiring and supply");
     }
}

byte displaySetupComplete = 0; 

void setup() {
  Serial.begin(600);
  pinMode(powerPin, OUTPUT);
  digitalWrite(powerPin, LOW);

  oled.begin(&Adafruit128x64, I2C_ADDRESS);
 delay(2000); 
 oled.setFont(System5x7);
 oled.clear();
 oled.print("Hello world!");

}


byte sensorOn = 0; //Whether sensor power is on or off. 
byte lastReadTime = millis()/1000; //Last time in millis we accessed the sensor reading. 
#define readingInterval  5   //The interval between successive readings in second. 


void loop() {
  // Delay between measurements.
 // delay(3000);
  if (Serial.available()) {
    char command;
    
    command = Serial.read();
    if (command == '1')
     {
      digitalWrite(powerPin, HIGH);
      delay(1000); //Having a short delay before initializing the sensors. 
      sensorOn = 1; 
      initializeSensors(); 
      delay(1000); 
     } 
    else if (command == '0') 
    {
      digitalWrite(powerPin, LOW);
      sensorOn = 0; 
    }
    //Serial.println("Got serial command!"); 
  }

  if(sensorOn==1)
  {
    String sensorReadings = ""; 
     if(millis()/1000 - lastReadTime > readingInterval)
     {
        lastReadTime = millis()/1000; 
        //initializing the reading containing string. 
            //sensorReadings = ""; 
            // Get temperature event and print its value.

                  sensors_event_t event;
                  dht.temperature().getEvent(&event);
                  // Get humidity event and print its value.
                  dht.humidity().getEvent(&event);
                  if (isnan(event.relative_humidity)) {
                    //Serial.print(F("ReadError"));
                    sensorReadings+="ReadError"; 
                  } else {
                    //Sending humidity reading from DHT22
                      // Serial.print(event.relative_humidity);
                      // Serial.print(F("%"));
                      // Serial.print("|"); 
                      sensorReadings+= String(event.relative_humidity) + "%|"; 
                  }
                  //Sending BMP280 temperature reading
                    // Serial.print(bmp.readTemperature());
                    // Serial.print(F("°C"));
                    // Serial.print("|"); 
                    sensorReadings+= String(bmp.readTemperature()) + "°C|"; 
                   
                  
                  
                //Sending BMP280 barometric pressure reading;
                  // Serial.print(bmp.readPressure());
                  // Serial.print(" Pa");
                  // Serial.print("|"); 
                   sensorReadings+= String(bmp.readPressure()) + "Pa|"; 



                  //MQ4 reading part.
                  MQ4.update();  // Update data, the arduino will read the voltage from the analog pin
                  MQ4.setA(-0.318);
                  MQ4.setB(1.133);               // A -> Slope, B -> Intersect with X - Axis
                  // Serial.print(MQ4.readSensor());
                   sensorReadings+= String(MQ4.readSensor()) + " ppm|"; 

                  //Sending LDR reading.
                  sensorReadings+= String(analogRead(ldrPin)) + "!"; 
                  
                   Serial.print(sensorReadings); 
     }

  }
 
  
}

Everything worked as expected until I wished to attach an OLED display to show the readings on it along with the Serial monitor. So I added following piece of code in their respective position:

#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiWire oled;

//Following part is inside void setup()


  oled.begin(&Adafruit128x64, I2C_ADDRESS);
 delay(2000); 
 oled.setFont(System5x7);
 oled.clear();
 oled.print("Hello world!");

Then I get no response from the Arduino and no desired functionality is active.
Please provide some insight on it. Thank you.

First thing you need to do is run the I2C scanner and let us know what it reports. Also let us know what I2C address each of the hardware items is set for. Can you post an annotated schematic showing how all of this is connected?

How much memory (code, Ram) is reported to be left by the compiler. That message at the end of the compile process will tell you.

The I2C scanner successfully identifies both the OLED and BMP280 at 0x3C and 0x77 respectively. I don't have a schematic to share right now. But I'll be working on it and post here shortly.

I got this output:

This sketch works well with my Arduino NANO, OLED(128x32), BME280, and Serial Monitor.
image

#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>//#include <Adafruit_SH110X.h>

Adafruit_BME280 bme; // I2C

#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define SCREEN_WIDTH 128 // OLED width in pixels
#define SCREEN_HEIGHT 32 // OLED height in pixels
#define OLED_RESET -1    // 
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

float         Temp       = 0;    // Temperature
float         Humid      = 0;    // Humidity

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

  bool communication = bme.begin(0x76);
  if (communication)
  {
    Serial.println("BME280 is found.");
  }
  else
  {
    while (1); //wait for ever
  }
  //----------------------------------

  if (display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
  {
    Serial.println("SSD1306 is found.");
  }
  else
  {
    while (1); //wait for ever
  }

  display.display();
  delay(2000); // Pause for 2 seconds

  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
}


void loop()
{
  Temp = bme.readTemperature();
  Humid = bme.readHumidity();

  Serial.print("Temperature: ");
  Serial.print(Temp); Serial.println(" degC");

  Serial.print("Humidity: ");
  Serial.print(Humid); Serial.println(" %");
  Serial.println("=========================================");

  display.clearDisplay();
  display.display();
  //--------------------------
  display.setCursor(5, 8);
  display.print("Temp: ");
  display.print(Temp, 2); display.println(" degC");
  //-------------------------
  display.setCursor(5, 20);  //x, y
  display.print("Humi: ");
  display.print(Humid, 2); display.println(" %");
  //---------------------------
  display.display();
  delay(2000);//2-sec refreshing is ok t0 avoid ghost characters
}

That indicates to me you compiled the code but did not upload it. You need to use the other button.

I uploaded it.

Put this is just after serial.begin. Serial.print("\n\n\tHello shanto_Kushtia\n"); Then when you upload you will get a message that the code has been loaded.

How does that helps solve the mentioned problem?

Simple it sends a message to the terminal letting you know your code has loaded and is running.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.