1

I am trying to get my DHT20 and OLED (both from the Arduino Sensor Kit) to work at the same time. I am able to get them working separately with their respective test codes, but when I try to combine the codes the OLED display no longer works. Both are I2C connections but I checked and each device has a different address so that shouldn't be a problem.

Here is my DHT20 test code:

#include "Arduino_SensorKit.h"

//uncomment line below if using DHT20
#define Environment Environment_I2C

void setup() {
  //uncomment line below if using DHT20
  Wire.begin();
  Serial.begin(9600);
  Environment.begin();
}

void loop() {
  Serial.print("Temperature = ");
  Serial.print(Environment.readTemperature()); //print temperature
  Serial.println(" C");
  Serial.print("Humidity = ");
  Serial.print(Environment.readHumidity()); //print humidity
  Serial.println(" %");
  delay(2000);
}

Here is my OLED display test code:

#include "Arduino_SensorKit.h"

void setup() {
  Oled.begin();
  Oled.setFlipMode(true);
}

void loop() {
  int random_value = random(0, 1023); // create a random value
  Oled.setFont(u8x8_font_chroma48medium8_r);
  Oled.setCursor(0, 3);
  Oled.print("Value: ");
  Oled.print(random_value);
  delay(1000);
}

This is the code where I tried to get both devices working at the same time:

#include "Arduino_SensorKit.h"

#define Environment Environment_I2C

void setup() {
  Oled.begin();
  Oled.setFlipMode(true);
  Wire.begin();
  Serial.begin(9600);
  Environment.begin();
}

void loop() {
  Oled.setFont(u8x8_font_chroma48medium8_r);
  Oled.setCursor(0, 3);
  Oled.print("Testing");
  Serial.print("Temperature = ");
  Serial.print(Environment.readTemperature()); //print temperature
  Serial.println(" C");
  Serial.print("Humidity = ");
  Serial.print(Environment.readHumidity()); //print humidity
  Serial.println(" %");
  delay(2000);
}

When I use this code the temp and humidity values are printed in the serial monitor but the OLED does not display anything.

Any help is much appreciated!

2
  • what happens if you reverse the order of the two module intialization in setup()?
    – jsotola
    Nov 26, 2023 at 1:24
  • Unfortunately reversing the order of the initialization in setup() doesn't change anything. Nov 27, 2023 at 18:39

2 Answers 2

3

The basic problem

I don't have this sensor kit. But am able to observe what you're describing with substitutes and stand-ins. There seem to be two things you can do.

The basic problem is that the Arduino_SensorKit library is written to use software/bit-banged I2C for the display. Or rather, it tells U8G2LIB to do this, for what reason I don't know. When the ATmega328P I2C peripheral is enabled the GPIO hardware is no longer driving the pins. So the moment you enable the hardware I2C (via the DHT20 code) the GPIO bit-banging code in U8G2LIB cannot work correctly.

So, there are at least two ways this can be made to work.

  • Modifying your code so it works with how the Arduino_SensorKit library is written.

  • The other is modifying the Arduino_SensorKit library to use hardware I2C, in which case your original code works verbatim.

Modifying the sketch

You can modify your sketch as follows:

#include "Arduino_SensorKit.h"
#define Environment Environment_I2C

void setup() {
  Oled.begin();
  Oled.setFlipMode(true);

  Serial.begin(9600);

  Wire.begin(); // only here to match the subsequent .end() 
}

void loop() {
  Wire.end();  // make I2C release control back to GPIO
  {
    Oled.setFont(u8x8_font_chroma48medium8_r);
    Oled.setCursor(0, 3);
    Oled.print(millis()); //Oled.print("Testing");
  }
  Wire.begin(); // re-enable I2C for use by DHT20 ("Environment")

  Serial.print("Temperature = ");
  Serial.print(Environment.readTemperature()); //print temperature
  Serial.println(" C");
  Serial.print("Humidity = ");
  Serial.print(Environment.readHumidity()); //print humidity
  Serial.println(" %");

  delay(2000);
}

For the most part the AVR Wire library doesn't care if you use repeated begin() or repeated end() calls. It may affect your speed setting though. The braces around the Oled usage are just there for visual effect.

Anyway, it works when you make sure Oled can use GPIO.

Modifying Arduino_SensorKit

With the following changes to Arduino_SensorKit library version 1.2.1 (current as of writing) I am able to use your sketch code verbatim. I also modified it to print millis() rather than "Testing" to be sure it was continuing to update the display.

Arduino_SensorKit.h

On line 24 of the libraries Arduino_SensorKit.h file, change:

extern U8X8_SSD1306_128X64_NONAME_SW_I2C Oled;

to

extern U8X8_SSD1306_128X64_NONAME_HW_I2C Oled;

Note HW (hardware) rather than SW (software).

Arduino_SensorKit.cpp

Likewise make the counterpart change to the definition of Oled corresponding to above change in extern declaration of Oled, from:

U8X8_SSD1306_128X64_NONAME_SW_I2C Oled(/* clock=*/ _PIN_SCL, /* data=*/ _PIN_SDA, /* reset=*/ U8X8_PIN_NONE);

to:

U8X8_SSD1306_128X64_NONAME_HW_I2C Oled(/* clock=*/ _PIN_SCL, /* data=*/ _PIN_SDA, /* reset=*/ U8X8_PIN_NONE);

You can probably remove the arguments from the constructor call here; the ATMega328P has no options with respect to configuring TWI/I2C for more than one set of pins.


There's also nothing stopping you from leaving it as U8X8_SSD1306_128X64_NONAME_SW_I2C, but changing the pins so that the software I2C uses pins other than A4/A5 so as not to conflict with the DHT20 libraries use of hardware I2C.


For reference the U8G2LIB version I tested with was 2.33.15. arduino-cli version 0.32.2. arduino:avr core 1.8.7. I don't think you need these. I'm just being complete in case someone finds this 5 years from now or whatever.

1
  • 1
    Thank you so much! I modified the sketch and it works perfectly now! Nov 28, 2023 at 20:50
1

I use a variable to store the readings.

#include "Arduino_SensorKit.h"

#define Environment Environment_I2C

void setup() {
  Oled.begin();
  Oled.setFlipMode(true); // Sets the rotation of the screen
  // uncomment line below if using DHT20 (black sensor)
  Wire.begin();
  // uncomment line below if you're connecting your DHT20 to pin a different than 3 
  Serial.begin(9600);
  Environment.begin();
}

void loop() {
  Wire.begin();

  // You need variable to keep the reading because Enviroment will not work when LED in operation
  float temp= Environment.readTemperature();
  float hum= Environment.readHumidity();
  Serial.print("Temperature = ");
  Serial.print(temp); //print temperature
  Serial.println(" C");
  Serial.print("Humidity = ");
  Serial.print(hum); //print humidity
  Serial.println(" %");
  
  delay(2000);
    
  // int random_value = analogRead(A0);
  Wire.end();

  {
    Oled.setFont(u8x8_font_chroma48medium8_r); 
    Oled.setCursor(0, 0);    // Set the Coordinates 
    Oled.print("temp: ");   
    Oled.print(temp); // Print the Values  

    Oled.setCursor(0, 3); // Set the Coordinates 
    Oled.print("Humidity: ");   
    Oled.print(hum); // Print the Values  
    Oled.refreshDisplay(); // Update the Display 
  }
}

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.