RobTillaart / DHT20

Arduino library for DHT20 I2C temperature and humidity sensor.
MIT License
21 stars 6 forks source link

Sensor does not initalize correctly if I2C LCD is initalized first #14

Closed Error504TimeOut closed 1 year ago

Error504TimeOut commented 1 year ago
#include "WiFi.h"
#include <LiquidCrystal_I2C.h>
#include "DHT20.h"
#define DHTDPIN 23
#define DHTCPIN 32
#define BPIN 13

int lcdc = 16;
int lcdr = 2;
bool bpress = false;
bool bon = true;

LiquidCrystal_I2C lcd(0x27, lcdc, lcdr);
DHT20 DHT;

void handleButtonPress() {
  bpress = true;
}

void setup() {
  lcd.init();
  DHT.begin(DHTDPIN, DHTCPIN);
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
 /* Connect to WiFi
 ...
 */
 attachInterrupt(digitalPinToInterrupt(BPIN), handleButtonPress, FALLING);
}

void loop() {
  int status = DHT.read();
  if (bpress) {
    Serial.println(bpress);
    if (bon) {
      return;
    }
    else {
      lcd.backlight();
      delay(2000);
      lcd.noBacklight();
    }
  }
  lcd.setCursor(0, 0);
  lcd.print("Temp. (C): ");
  lcd.setCursor(11,0);
  lcd.print(DHT.getTemperature());
  delay(1000);
  Serial.println("redraw");
  switch (status)
    {
      case DHT20_OK:
        Serial.print("OK");
        break;
      case DHT20_ERROR_CHECKSUM:
        Serial.print("Checksum error");
        break;
      case DHT20_ERROR_CONNECT:
        Serial.print("Connect error");
        break;
      case DHT20_MISSING_BYTES:
        Serial.print("Missing bytes");
        break;
      case DHT20_ERROR_BYTES_ALL_ZERO:
        Serial.print("All bytes read zero");
        break;
      case DHT20_ERROR_READ_TIMEOUT:
        Serial.print("Read time out");
        break;
      case DHT20_ERROR_LASTREAD:
        Serial.print("Error read too fast");
        break;
      default:
        Serial.print("Unknown error");
        break;
    }
}

If I use this Code, the LCD will display the Text it should, but the Sensor values will result in an Time Out. If I init the DHT first and the LCD after that, the DHT will read correctly but the LCD will fail to init. A delay between the two commands does not help. Any advice?

RobTillaart commented 1 year ago

Thanks for reporting this issue, I will look into it asap but it might take a few days.

RobTillaart commented 1 year ago

A minor point for your buttonpress

bool bpress = false;
==>
volatile bool bpress = false;

Which board are you compiling?

Don't know the details of the LCD library, but does it not need a Wire.begin()?

Error504TimeOut commented 1 year ago

I'm using a ESP32. The LCD library seems to not need a Wire.begin() at least none of the Examples use it.

RobTillaart commented 1 year ago

Makes sense, if it was needed it should never work. Do you have pull ups in place?

Error504TimeOut commented 1 year ago

Yes, however not for the Display nor the DHT. I only use the internal for the Button.

RobTillaart commented 1 year ago

The SDA and SCL need pull ups to improve signal quality. The DHT lib has a function isConnected. Can you see the dht ?

Error504TimeOut commented 1 year ago

In the example? Yes. In my Code? No. Also I can only see the Sensor if I don't use pull ups. I think the ones I used are too strong. Which values should they have for the SDA & SCL?

RobTillaart commented 1 year ago

Depends on length of the wires. 4k7 is a good value for up to 1meter (4 feet)

Error504TimeOut commented 1 year ago

I will try that. But why can I, even if I don't use pull ups, init the Sensor correctly if alone and not if combined with the LCD? That seems pretty strange to me. Although I'm not experienced with such things

RobTillaart commented 1 year ago

The initialization is often a short communication so chances it fails are smaller. But no it does not explain the problem that you have. I have no clue yet and must exclude some common problems and try to understand what happens. Software wise I do not see a cause yet.

An option you may also try is to give the LCD a separate 5V powder supply. Do connect GND from lcd and esp as common reference. It could be a "simple" power problem.

Error504TimeOut commented 1 year ago

I tried both a stronger power adapter and to power the LCD seperately, both of which did not work so this does not seem to be a power issue.

RobTillaart commented 1 year ago

Sorry, had other priorities today. No idea what is the cause so far. To be continued later this week.

RobTillaart commented 1 year ago

If you have both devices connected to your board, and you run an I2C scanner are both devices detected?

RobTillaart commented 1 year ago

just before the line

lcd.print(DHT.getTemperature());

Add a call to check connectedness.

if (! DHT.isConnected()) 
{
  Serial.println("connect failed");
}
lcd.print(DHT.getTemperature());

If connection works, you might try a DHT.resetSensor(); call

Still no clue

Error504TimeOut commented 1 year ago

If you have both devices connected to your board, and you run an I2C scanner are both devices detected?

  • display at 0x27
  • DHT at 0x38

Sorry for taking so long. I tried the default WireScan Sketch and I can only see the LCD. If I disconnect the LCD and have only the DHT connected, it reports that no I2C Device is found, which is even weirder as your DHT Example-Sketch works as normal so the Sensor shouldn't be broken or anything. DHT.isConnected() returns 0 both in setup() and loop() DHT.resetSensor() does not help either.

RobTillaart commented 1 year ago

Mmm, that makes the DHT prime suspect.

if you start setup() with a delay(5000) to give the devices some extra time to "wake up".

I am gonna read the datasheet if it mentions something that could explain the behaviour.

Error504TimeOut commented 1 year ago

I tried the delay(5000) in the first line after setup() and it seems to be ignoring that and skips right to connecting to WiFi, at least if I just reset the ESP32. If I do a full power cycle however it does seem to wait, but it still fails in a reading time out. And I don't know if it's important but the DHT32 is connected to the 3.3V Pin but according to the Datasheet that should be enough, if not, I could try 5V

RobTillaart commented 1 year ago

DHT32 ? slip of the pen 😁

RobTillaart commented 1 year ago

3V3 should work.

RobTillaart commented 1 year ago

image

100ms wait seems mandatory, you might need to call resetSensor() or readstatus()

Error504TimeOut commented 1 year ago

So if I understand this correctly I need to wait 100ms after power-on and wait until readStatus() returns 0x18? And even if I don't, shouldn't it still work because I wait 5000ms before I do anything? Either way the this is the Code I now use

  delay(500);
  // put your setup code here, to run once:
  Serial.begin(115200);
  lcd.init();
  lcd.backlight();
  DHT.begin(DHTDPIN, DHTCPIN);
  lcd.setCursor(0,0);
  while(DHT.readStatus() != 0x18){
    lcd.print(".");
    Serial.println(DHT.readStatus());
    delay(100);
  }

now it just hangs in the while loop. Serial.println(DHT.readStatus()); just returns 255

RobTillaart commented 1 year ago
delay(500);
  // put your setup code here, to run once:
  Serial.begin(115200);
  lcd.init();
  lcd.backlight();
  DHT.begin(DHTDPIN, DHTCPIN);
  lcd.setCursor(0,0);
  while(DHT.readStatus() != 0x18){
    lcd.print(".");
    Serial.println(DHT.resetSensor());  //  <<<<<<<<<<<
    delay(100);
  }

try this

RobTillaart commented 1 year ago

Nothing more seen in the datasheet that I could associate with observed behavior.

Error504TimeOut commented 1 year ago

Sadly still not working. Serial.println(DHT.resetSensor()); returns 255. I was also thinking about removing the display, as I technically don't need it and while technically a valid solution it's not really nice and doesn't really solve the issue. What I could try is maybe use another LCD-Library as the original repo is archived and the GitLab-Link in the README.md results in a 404.

RobTillaart commented 1 year ago

Can you test this minimalistic version, it tries to read the DHT before and after the initialization of the LCD.


#include <LiquidCrystal_I2C.h>
#include "DHT20.h"

#define DHTDPIN 23
#define DHTCPIN 32

int lcdc = 16;
int lcdr = 2;

LiquidCrystal_I2C lcd(0x27, lcdc, lcdr);
DHT20 DHT;

void setup() 
{
  Serial.begin(115200);
  Serial.println(__FILE__);
  delay(100);

  //  First read a temperature measurement.
  DHT.begin(DHTDPIN, DHTCPIN);

  int status = DHT.read();
  Serial.println(status);
  Serial.println(DHT.getTemperature());

  // Then we initialize the LCD
  lcd.init();

  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Hello world");

  status = DHT.read();
  Serial.println(status);
  Serial.println(DHT.getTemperature());
}

void loop() 
{
}

(minor edits)

Error504TimeOut commented 1 year ago
20:22:45.359 -> /tmp/arduino_modified_sketch_805545/sketch_aug01a.ino
20:22:45.458 -> -15
20:22:45.458 -> 0.000
20:22:46.583 -> 23.27

It seems that it only reads the temperature correctly after the LCD init, but even after a reset the LCD-Code didn't seem to run/work, as the LCD did not clear. I also did a full power cycle, which did clear the LCD, but didn't display anything and the LCD displayed full blocks in the first row, meaning that it didn't initalize.

RobTillaart commented 1 year ago

I normally use this I2C LCD library? - https://github.com/fmalpartida/New-LiquidCrystal Is that the same as you?

Error504TimeOut commented 1 year ago

No, I currently use this one I will try to set the other one up and try if that works.

RobTillaart commented 1 year ago

No, I currently use this one I will try to set the other one up and try if that works.

Not familiar with that one, it is moved to GitLab, but when I follow the link it loops in some sign in procedure

Error504TimeOut commented 1 year ago

Well apart from me not getting the Backlight to work correctly and that if I try to print something on the LCD nothing happens or, if it does, the second block in the first row just blinks, I can still see that if I use the while loop, it still returns 255, and if not that the reading fails, still with a time out.

Not familiar with that one, it is moved to GitLab, but when I follow the link it loops in some sign in procedure

If I try to login into GitLab with GitHub, it does work technically, but it just returns a 404

RobTillaart commented 1 year ago

I'll wait for your tests with - https://github.com/fmalpartida/New-LiquidCrystal

RobTillaart commented 1 year ago
Error504TimeOut commented 1 year ago

Now I can't get the LCD to run either, but to be fair that's probably my fault 😅. This is the code I use now

  delay(500);
  Serial.begin(115200);
  lcd.begin(lcdc,lcdr);
  lcd.home();
  lcd.backlight();
  DHT.begin(DHTDPIN, DHTCPIN);

When I use the while loop it still prints 255 and if I don't use the while loop the LCDs backlight flashes a few times and when I'm lucky the second Block on the first row blinks. In the serial console I still see that the DHT readings time out :/

RobTillaart commented 1 year ago

Think you should start with running some examples from the LCD lib. Just to get some hands on experience. For instance I noticed the backlight is controlled slightly different.

Error504TimeOut commented 1 year ago

Okay. I try to use it for a little bit and if I feel I experimented enough I will try to add the DHT component to the code. I should report the results here within a few days.

Error504TimeOut commented 1 year ago

So I tried this library and it just doesn't work. Apart from not getting the Backlighting to work (which I solved by wiring it manually) it doesn't produce any output at all except from a blinking cursor. It may work for other non I2C LCDs or even other I2C LCDs but not with mine. I tried using the (Arduino)-Library from the store where I brought the LCD (here), which at least got the LCD to work again. It does not look like it differs a lot from the one I used originally, but some stuff changed like instead of lcd.init() I have to use lcd.begin(). It still only works the device that was initalized first :/

RobTillaart commented 1 year ago

Both libraries call Wire.begin() in their initialization. Could that interfere somehow?

Can you comment Wire,begin() in one of the libs and call that one as second?

Error504TimeOut commented 1 year ago

I tried it both ways and even commenting it out in both libs and put the Wire.begin() in my Code after the initial delay(500) resulting in no change. Could it be an issue that your lib is object oriented (at least i think that's what the -> mean) and the other is not?

RobTillaart commented 1 year ago

Could it be an issue that your lib is object oriented (at least i think that's what the -> mean) and the other is not?

OO should not be the problem, I use similar constructs in many other libraries so if that was the problem I would have heard before.

The -> means that you use a pointer to some object. In my library I have a pointer to the Wire object, that allows me to support boards that have more than one Wire port or even some software I2C implementations.

What I do is the following in code

Twowire *wire;  //  pointer to a Twowire object  (the type of Wire)
wire = &Wire;  //  point to the address of the Wire object, could also be Wire1, Wire2 etc
wire->begin();  // call the begin method() of the Wire object wire points to

Its called dependency injection (AFAIK), as my lib depends on Wire, I inject the right Wire object into it.

Error504TimeOut commented 1 year ago

If that's not the issue I could look if I have some sort of other sensor/part for the esp32 which requires a library and try to combine it with the DHT/LCD (e.g. DHT and IR-Sensor or LCD and IR-Sensor) to see if that works. If it does, there should be a problem with the LCD/DHT lib

Error504TimeOut commented 1 year ago

I think I also have an Arduino somewhere. I could try the LCD and DHT on there and see if that works

RobTillaart commented 1 year ago

Think I have a clue.

Do the LCD and the DHT use the same hardware pins? They should as they both should be on the Wire bus.

The DHT.begin(DHTDPIN, DHTCPIN); call resets the pins of the Wire object, causing the LCD to fail.

So

  1. Use the same pins for the LCD and the DHT20 (SDA and SCL)
  2. Use DHT.begin() without pin parameters.

Please give it a try

RobTillaart commented 1 year ago

Think on the ESP32 the SDA and SCL are 21 and 22 (from my head)?

Error504TimeOut commented 1 year ago

That's what it says in your example at least. Give me a sec I'll try that.

Error504TimeOut commented 1 year ago

The LCD displays the Text and the DHT values. Thanks for your help :)

RobTillaart commented 1 year ago

Welcome, So no bug in either library, the merging of functionality caused the Wire object to initialize in "two different ways" Learned something today.