SH1106 weird output with UNO R4 Wifi

Good evening everybody!

I´ve built an automatic watering system with soil moisture, dht22 and sgp30 sensors.
Today I added an 1,3 inch SH1106 OLED display connected to A4 and A5 pins with u8g2 library. The first image I get from the display works as intended but after the first data output to the display it shows weird pixels where some text is working but the rest looks like in the attached pictures. Sometimes it only shows a few wrong pixels and 95% is good. It has the same behavior with example sketches from the u8g2 library. Also the sgp30 which is connected to SCL and SDA pins shows very high Co2 values like 15000 ppm, normal range is between 400-700 ppm. On the UNO R3 it's working fine. Somebody have an advise how to fix this?



#include "arduino_secrets.h"
/*
  Sketch generated by the Arduino IoT Cloud Thing "Untitled 2"
  https://create.arduino.cc/cloud/things/96bcc51b-9f5d-46b6-9d18-0ccbd11a1b3e

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  String message;
  int moistureLevel;
  CloudPercentage moisturePercent;
  CloudRelativeHumidity hum;
  CloudTemperature temp;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "thingProperties.h"
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include "sensirion_common.h"
#include "sgp30.h"
#include <U8g2lib.h>
#include <Wire.h>
#define DHT_SENSOR_PIN 3
#define DHT_SENSOR_TYPE DHT22
#define PUMP_PIN 2
DHT dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);

int soilMoistureLevel;
int soilMoisturePercent;

int airValue = 585;
int waterValue = 295;

const unsigned long DhtInterval = 5000;
const unsigned long SoilInterval = 10000;
const unsigned long VocInterval = 5000;
const unsigned long PumpInterval = 5000;
const unsigned long PumpPauseInterval = 15000;
const unsigned long DisplayInterval = 10000;
unsigned long DhtStartMillis;
unsigned long SoilStartMillis;
unsigned long VocStartMillis;
unsigned long WateringStartMillis;
unsigned long DisplayStartMillis;
unsigned long currentMillis;

void setup() {
  pinMode(DHT_SENSOR_PIN, INPUT);
  dht_sensor.begin();
  s16 err;
  u16 scaled_ethanol_signal, scaled_h2_signal;
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  delay(1000);
  pinMode(PUMP_PIN, OUTPUT);
  digitalWrite(PUMP_PIN, HIGH);

  while (sgp_probe() != STATUS_OK) {
    Serial.println("SGP failed");
    while (1)
      ;
  }
  /*Read H2 and Ethanol signal in the way of blocking*/
  err = sgp_measure_signals_blocking_read(&scaled_ethanol_signal,
                                          &scaled_h2_signal);
  if (err == STATUS_OK) {
    Serial.println("get ram signal!");
  } else {
    Serial.println("error reading signals");
  }
  err = sgp_iaq_init();
  //Defined in thingProperties.h
  initProperties();
  //Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
  */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  delay(10000);

  DhtStartMillis = millis();
  SoilStartMillis = millis();
  VocStartMillis = millis();
  WateringStartMillis = millis();
  DisplayStartMillis = millis();

  u8g2.begin();
  u8g2.clearBuffer();                     // clear the internal memory
  u8g2.setFont(u8g2_font_tenfatguys_tr);  // choose a suitable font u8g2_font_9x15_tf
  u8g2.drawStr(0, 10, "TEMP");            // write something to the internal memory
  u8g2.drawStr(52, 10, ":");
  u8g2.setFont(u8g2_font_synchronizer_nbp_tf);
  u8g2.drawStr(111, 5, "o");
  u8g2.setFont(u8g2_font_tenfatguys_tr);
  u8g2.drawStr(118, 10, "C");
  u8g2.drawStr(0, 28, "HUM");
  u8g2.drawStr(52, 28, ":");
  u8g2.drawStr(114, 28, "%");
  u8g2.drawStr(0, 46, "SOIL");
  u8g2.drawStr(52, 46, ":");
  u8g2.drawStr(114, 46, "%");
  u8g2.drawStr(0, 64, "Co2");
  u8g2.drawStr(52, 64, ":");
  u8g2.setFont(u8g2_font_resoledbold_tr);
  u8g2.drawStr(111, 63, "ppm");
  u8g2.sendBuffer();
}

void loop() {
  currentMillis = millis();
  Dht();
  Soil();
  Voc();
  Watering();
  Display();
  ArduinoCloud.update();  // Update the Cloud's data
}

void Dht() {

  if (currentMillis - DhtStartMillis >= DhtInterval) {
    hum = dht_sensor.readHumidity();
    temp = dht_sensor.readTemperature();
    if (isnan(hum) || isnan(temp)) {
      Serial.println("Failed to read from DHT Sensor!");
    } else {
      Serial.print("Humidity: ");
      Serial.print(hum);
      Serial.print("%");
      Serial.print(" | ");
      Serial.print("Temperature: ");
      Serial.print(temp);
      Serial.println("°C");  //ALT 0176

      DhtStartMillis = currentMillis;
    }
  }

  if (hum > 75)

  {
    //Send message to Arduino Cloud messenger on dashboard
    Serial.print("Luftfeuchtigkeit zu hoch!");
    message = "Luftfeuchtigkeit zu hoch!";
  }
}

void Soil() {
  if (currentMillis - SoilStartMillis >= SoilInterval) {

    //Read data from Analog Pin 1 on Nano 33 IoT and print to Serial Monitor for debugging
    soilMoistureLevel = analogRead(1);
    Serial.println(soilMoistureLevel);

    //Convert soilMoistureLevel integer into percentage by using air and water values defined above and mapping with 0 - 100
    soilMoisturePercent = map(soilMoistureLevel, airValue, waterValue, 0, 100);
    Serial.println(soilMoisturePercent);  //Print to Serial Monitor for debugging

    //Update Arduino IoT Cloud values
    moistureLevel = soilMoistureLevel;
    moisturePercent = soilMoisturePercent;

    SoilStartMillis = currentMillis;
  }
}

void Voc() {
  if (currentMillis - VocStartMillis >= VocInterval) {

    s16 err = 0;
    u16 tvoc_ppb, co2_eq_ppm;
    err = sgp_measure_iaq_blocking_read(&tvoc_ppb, &co2_eq_ppm);
    if (err == STATUS_OK) {
      Serial.print("tVOC  Concentration:");
      Serial.print(tvoc_ppb);
      Serial.println("ppb");

      Serial.print("CO2eq Concentration:");
      Serial.print(co2_eq_ppm);
      Serial.println("ppm");
    } else {
      Serial.println("error reading IAQ values\n");
    }

    //Update Arduino IoT Cloud values
    vocLevel = tvoc_ppb;
    co2Level = co2_eq_ppm;

    VocStartMillis = currentMillis;
  }
}

void Display() {
  if (currentMillis - DisplayStartMillis >= DisplayInterval) {
    delay(200);
    u8g2.setFont(u8g2_font_tenfatguys_tn);
    u8g2.setDrawColor(0);
    u8g2.drawBox(62, 0, 35, 18);
    u8g2.drawBox(62, 12, 40, 18);
    u8g2.drawBox(62, 30, 40, 18);
    u8g2.drawBox(62, 48, 50, 18);
    u8g2.sendBuffer();
    u8g2.setDrawColor(1);
    u8g2.drawStr(62, 10, (String(temp).c_str()));
    u8g2.drawStr(62, 28, (String(hum).c_str()));
    u8g2.drawStr(62, 46, (String(soilMoisturePercent).c_str()));
    u8g2.drawStr(62, 64, (String(co2Level).c_str()));
    u8g2.sendBuffer();

    DisplayStartMillis = currentMillis;
  }
}


void Watering() {
  if (currentMillis - WateringStartMillis >= PumpInterval) {
    if (soilMoisturePercent < 30) {
      message = "Wasserlevel niedrig, Gießvorgang gestartet!";
      ArduinoCloud.update();
      digitalWrite(PUMP_PIN, LOW);
      Serial.println("Pumpe an");
      message = "Pumpe an";
      ArduinoCloud.update();
      delay(PumpInterval);
      digitalWrite(PUMP_PIN, HIGH);
      Serial.println("Pumpe aus");
      message = "Pumpe aus";
      ArduinoCloud.update();

      hum = dht_sensor.readHumidity();
      temp = dht_sensor.readTemperature();

      soilMoistureLevel = analogRead(1);
      Serial.println(soilMoistureLevel);
      soilMoisturePercent = map(soilMoistureLevel, airValue, waterValue, 0, 100);
      Serial.println(soilMoisturePercent);

      moistureLevel = soilMoistureLevel;
      moisturePercent = soilMoisturePercent;

      s16 err = 0;
      u16 tvoc_ppb, co2_eq_ppm;
      err = sgp_measure_iaq_blocking_read(&tvoc_ppb, &co2_eq_ppm);

      vocLevel = tvoc_ppb;
      co2Level = co2_eq_ppm;
      ArduinoCloud.update();

      delay(200);
      u8g2.setFont(u8g2_font_tenfatguys_tn);
      u8g2.setDrawColor(0);
      u8g2.drawBox(62, 0, 35, 18);
      u8g2.drawBox(62, 12, 40, 18);
      u8g2.drawBox(62, 30, 40, 18);
      u8g2.drawBox(62, 48, 50, 18);
      u8g2.sendBuffer();
      u8g2.setDrawColor(1);
      u8g2.drawStr(62, 10, (String(temp).c_str()));
      u8g2.drawStr(62, 28, (String(hum).c_str()));
      u8g2.drawStr(62, 46, (String(soilMoisturePercent).c_str()));
      u8g2.drawStr(62, 64, (String(co2Level).c_str()));
      u8g2.sendBuffer();

      delay(PumpPauseInterval);

      while (soilMoisturePercent < 70) {
        ArduinoCloud.update();
        digitalWrite(PUMP_PIN, LOW);
        Serial.println("Pumpe an");
        message = "Pumpe an";
        ArduinoCloud.update();
        delay(PumpInterval);
        digitalWrite(PUMP_PIN, HIGH);
        Serial.println("Pumpe aus");
        message = "Pumpe aus";
        ArduinoCloud.update();
        delay(PumpPauseInterval);

        hum = dht_sensor.readHumidity();
        temp = dht_sensor.readTemperature();

        soilMoistureLevel = analogRead(1);
        Serial.println(soilMoistureLevel);
        soilMoisturePercent = map(soilMoistureLevel, airValue, waterValue, 0, 100);
        Serial.println(soilMoisturePercent);

        moistureLevel = soilMoistureLevel;
        moisturePercent = soilMoisturePercent;

        s16 err = 0;
        u16 tvoc_ppb, co2_eq_ppm;
        err = sgp_measure_iaq_blocking_read(&tvoc_ppb, &co2_eq_ppm);

        vocLevel = tvoc_ppb;
        co2Level = co2_eq_ppm;
        ArduinoCloud.update();

        delay(200);

        u8g2.setFont(u8g2_font_tenfatguys_tn);
        u8g2.setDrawColor(0);
        u8g2.drawBox(62, 0, 35, 18);
        u8g2.drawBox(62, 12, 40, 18);
        u8g2.drawBox(62, 30, 40, 18);
        u8g2.drawBox(62, 48, 50, 18);
        u8g2.sendBuffer();
        u8g2.setDrawColor(1);
        u8g2.drawStr(62, 10, (String(temp).c_str()));
        u8g2.drawStr(62, 28, (String(hum).c_str()));
        u8g2.drawStr(62, 46, (String(soilMoisturePercent).c_str()));
        u8g2.drawStr(62, 64, (String(co2Level).c_str()));
        u8g2.sendBuffer();

        if (soilMoisturePercent >= 70) {
          message = "Wasserlevel i.O., Gießvorgang beendet!";
          ArduinoCloud.update();
          digitalWrite(PUMP_PIN, HIGH);
        }
      }
    }
  }
}

Same advice as always!

Do you mean Google or add code?

No, not Google.

Add code, yes. And schematic.

You are not new to this forum.

Sorry. added the code.

I've read through the code. So far, I can't see anything that would cause the problem. My best theory at the moment is some RAM memory problem. They are common enough with Uno R3 which has very little RAM, and when it is all used up, weird things can happen. But R4 has much more, and I can't see that being the problem here. Another common cause of problems can be exceeding the index bounds of arrays, but there aren't any obvious problems like that in your code either.

What about that schematic?

dht22: digital 2
soil moisture sensor: A2
sgp30: SCL and SDA
display: SDA -> A4, SCL -> A5

Hi! Same problem!
A simple test code with a SH1106 I2C works perfectly with the Uno R3, while with the Uno R4 WiFi the display has random weird output.
Another code with 3x SH1106 I2C via TCA9548A I2C Multiplexer works perfectly with Uno R3, while with Uno R4 WiFi the displays have random weird outputs.
Tried everything possible for me, but no difference, always weird outputs...

It seems like the problem is related to the SH1106. Tried it with SSD1306 and it works fine on the R4.

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