DHT not working at all with XOD, but ok with Arduino IDE

#1

Continuing the discussion from DHT-11 and DHT-22 not working at all!:

Update, Update, Update for the third time. Here is some great or not so great information.
I wrote a small program for the Arduino IDE, parts borrowed from the Arduino Samples files.
In a couple of lines of code I now can read the Humidity %, the Temperature in Celsius and Fahrenheit on the output of the Serial Monitor. All works great. I checked all of my previous DHT-11’s and DHT-22’s and all work as they should.
On the Scope I can see the Start pulse and the Data coming back from the DHT. BUT, there is a BIG difference of the Start Pulse coming from the XOD program versus the Arduino IDE, DHT library.
The XOD IDE sends a 50 ms pulse but the Arduino sends a 1 ms pulse. Here is a pix of the working DHT with the Arduino.

As you can see the start pulse and the 40 bits of data coming back, I did not count them but I will take the spec sheets word for it. I looked at the spec sheet and it does not say, in english anyway, what are the minimum and max pulse width limits. “Must be Chinese”

Is there something wrong with my layout of the DHT-22 or is it the way it is hooked up?
Any Ideas out there ?
I am open for any suggestions.

#2

I still don’t get it. You made it work with HANDWRITTEN code.
Then the XOD code doesn’t work…

Can’t you compare the codes ? any calls to DELAY ? INTERRUPTS?
I’d rather you POST the two codes here so I can ACTUALLY “see” the diff between the two.
Maybe I can have a better answer for you.

Oh wait! Is the XOD generating a BINARY block for upload to the board??? So you don’t have a clue what it does WRONG, then? Oh my!

#3

Beep, bop! @dawreski, thank you for the research. The problem is that there’s a variety of DHT sensors (even two DHT-11’s can be different inside) and libraries for them.

What Arduino library do you use in Arduino IDE which gives you the successful readings show on the photo?

I’ve checked the code of dhtxx-read-raw used in XOD and there’s seemingly nothing that forces the start pulse to be as long as 50ms:


struct State {
    bool reading;
};

{{ GENERATED_CODE }}

enum DhtStatus
{
    DHT_OK = 0,
    DHT_START_FAILED_1 = 1,
    DHT_START_FAILED_2 = 2,
    DHT_READ_TIMEOUT = 3,
    DHT_CHECKSUM_FAILURE = 4,
};

unsigned long pulseInLength(uint8_t pin, bool state, unsigned long timeout) {
    unsigned long startMicros = micros();
    while (digitalRead(pin) == state) {
        if (micros() - startMicros > timeout)
            return 0;
    }
    return micros() - startMicros;
}

bool readByte(uint8_t port, uint8_t* out) {
    // Collect 8 bits from datastream, return them interpreted
    // as a byte. I.e. if 0000.0101 is sent, return decimal 5.

    unsigned long pulseLength = 0;
    uint8_t result = 0;
    for (uint8_t i = 8; i--; ) {
        // We enter this during the first start bit (low for 50uS) of the byte

        if (pulseInLength(port, LOW, 70) == 0)
            return false;

        // Dataline will now stay high for 27 or 70 uS, depending on
        // whether a 0 or a 1 is being sent, respectively.

        pulseLength = pulseInLength(port, HIGH, 80);

        if (pulseLength == 0)
            return false;

        if (pulseLength > 45)
            result |= 1 << i; // set subsequent bit
    }

    *out = result;
    return true;
}

DhtStatus readValues(uint8_t port, uint8_t* outData) {
    // Stop reading request
    digitalWrite(port, HIGH);

    // DHT datasheet says host should keep line high 20-40us, then watch for
    // sensor taking line low.  That low should last 80us. Acknowledges "start
    // read and report" command.
    delayMicroseconds(30);

    // Change Arduino pin to an input, to watch for the 80us low explained a
    // moment ago.
    pinMode(port, INPUT_PULLUP);

    if (pulseInLength(port, LOW, 90) == 0)
        return DHT_START_FAILED_1;

    // After 80us low, the line should be taken high for 80us by the sensor.
    // The low following that high is the start of the first bit of the forty
    // to come. The method readByte() expects to be called with the system
    // already into this low.
    if (pulseInLength(port, HIGH, 90) == 0)
        return DHT_START_FAILED_2;

    // now ready for data reception... pick up the 5 bytes coming from
    // the sensor
    for (uint8_t i = 0; i < 5; i++)
        if (!readByte(port, outData + i))
            return DHT_READ_TIMEOUT;

    // Restore pin to output duties
    pinMode(port, OUTPUT);
    digitalWrite(port, HIGH);

    // See if data received consistent with checksum received
    uint8_t checkSum = outData[0] + outData[1] + outData[2] + outData[3];
    if (outData[4] != checkSum)
        return DHT_CHECKSUM_FAILURE;

    return DHT_OK;
}

void enterIdleState(uint8_t port) {
    // Restore pin to output duties
    pinMode(port, OUTPUT);
    digitalWrite(port, HIGH);
}

void evaluate(Context ctx) {
    State* state = getState(ctx);
    uint8_t port = (uint8_t)getValue<input_PORT>(ctx);

    if (state->reading) {
        uint8_t data[5];
        auto status = readValues(port, data);
        if (status == DHT_OK) {
            emitValue<output_D0>(ctx, data[0]);
            emitValue<output_D1>(ctx, data[1]);
            emitValue<output_D2>(ctx, data[2]);
            emitValue<output_D3>(ctx, data[3]);
            emitValue<output_DONE>(ctx, 1);
        } else {
            emitValue<output_ERR>(ctx, 1);
        }

        enterIdleState(port);
        state->reading = false;
    } else if (isInputDirty<input_UPD>(ctx)) {
        // initiate request for data
        pinMode(port, OUTPUT);
        digitalWrite(port, LOW);
        // for request we should keep the line low for 18+ ms
        setTimeout(ctx, 18);
        state->reading = true;
    } else {
        enterIdleState(port);
    }
}

A very careful comparison is required. However, it is a good idea to know what we should compare to :slight_smile:

#4

Hello Nkrkv,

Thank you so much for your reply.

Here is the Arduino code that works on all my DHT-22’s and DHT-11’s. I tried two different models and all works fine.

It will take me awhile to figure the difference from the earlier version of XOD to this one that does not work.

I do not know what was changed in the newer version’s ,but the new versions do not work.

Here is my Arduino code.

Have a GREAT weekend, my friend. Stay well.

Thank you for all your HARD work for this.

Dave

(Attachment Dave_DHT-22.ino is missing)

#5

Here is my Third try to get you the file.

// DHT-22 Sensor Temperature and humidity readings

//Libraries

#include <DHT.h>;

//Constants

#define DHTPIN 7 // what pin we’re connected to

#define DHTTYPE DHT22 // DHT 22 (AM2302)

// #define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

//Variables

int chk;

float hum; //Stores humidity value

float temp; //Stores temperature value

float fahern; // Calculation from C to F

void setup()

{

Serial.begin(9600);

dht.begin();

}

void loop()

{

delay(5000);

//Read data and store it to variables hum and temp

hum = dht.readHumidity();

temp= dht.readTemperature();

fahern=(1.80*temp+32);

//Print temp and humidity values to serial monitor

Serial.print("Humidity: ");

Serial.print(hum);

Serial.println(" Percent");

Serial.print("Temperature: ");

Serial.print(fahern);

Serial.println(" Fahrenheit");

Serial.print("Temperature: ");

Serial.print(temp);

Serial.println(" Celsius");

Serial.println();

delay(10000); //Delay 2 sec.

}

#6

Hello Victor,

This last time I copied and pasted my entire code I used for the Arduino test that worked for all of my DHT sensors.

All worked well. The other three messages I sent did not go through due to the wrong file type. Even PDF.

I hope this will help find the timing problem with the latest version.

It seem 50 ms it much too long and misses the incoming dats from the DTH sensor.

Thank you again for all your hard work. You are SUPER to help so much.

There is so much for me to learn about XOD. But I am trying hard.

Please let me know if you did not get my last three messages.

Dave