Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Well documented example to read DHTxx sensor on any Pinguino.
22-10-2013, 03:18 PM,
#1
Smile  Well documented example to read DHTxx sensor on any Pinguino.
Hi folks,

I've created this example for reading a DHTxx sensor on any Pinguino board. I have tested it with a DHT11 on a PIC4550 custom Pinguino board.

Every part is fully documented and clearly explained, so can serve as a good example for creating your own routines for reading proprietary 1-wire sensors.

Code:
/*-----------------------------------------------------
Author:  Niki Murkett
Date: Tue Oct 22 09:40:08 2013
Description: Simple example to read a DHTxx Temp/Humidity sensor.
Tested with a DHT11, but should work with DHT15 and DHT22.
This example makes no special demands on hardware, so should
work with any Penguino board.

-----------------------------------------------------*/

#define DHTxxBUS 1 // Read DHT11 on Penguino pin 1

#define DHTxxRESULT 0
#define DHTxxNOTCONNECTED 1
#define DHTxxCHECKSUMFAILED 2

// Define the structure to hold the returned data.
// This will only be filled out on a successful reading.
  
struct DHTxxStruct {
    u8 intRH;
    u8 decRH;
    signed short intTemp;
    u8 decTemp;
} DHTxxData;

// Data in this example will be sent to the hardware serial port.
// Change to CDC if you wish
void setup() {
    Serial.begin(57600);
    Serial.printf("\r\nReading DHTxx sensor on pin %d.\r\n", DHTxxBUS);
    }

void loop() {
    u8 dhtxx_status = 0;
    
    delay(1000); // Readings can only be taken once per second.
    
    // Take a reading.  Status is returned.  Structure is only
    // filled out on a successful reading.
    dhtxx_status = DHTxx_take_reading();
  
    switch (dhtxx_status) { // Check the status code
        case DHTxxRESULT: // Everything worked fine, so show sensor results.
            Serial.printf("Humidity: %d.%d%% - Temp: %d.%dC\r\n", DHTxxData.intRH, DHTxxData.decRH, DHTxxData.intTemp, DHTxxData.decTemp);
            break;
        case DHTxxNOTCONNECTED: // No DHTxx sensor has been found.
            Serial.printf("DHTxx sensor not found on pin %d.\r\n", DHTxxBUS);
            break;
        case DHTxxCHECKSUMFAILED: // Returned data was corrupted.
            Serial.printf("Bad checksum. Check pull-up resistor on pin %d.\r\n", DHTxxBUS);
            break;
        }

    }

/*

DHTxx_read_byte() reads one byte using the DHTxx 1-wire protocol.

Bits appear from the sensor as:

        Digital 0             Digital 1
Vcc  __         ____     __        _______
       \       /    \      \      /   ^   \
Gnd     \_____/      \      \____/         \
         50us   26us         50us    70us

To read this, we wait for the input to switch from LOW to HIGH
and wait for 35 microseconds.  At this point, reading the pin
will either be the mid-point of the digital 1 signal, or the low
point of the next bit.  This is looped 8 times.

Bits are clocked in from bit 7 to bit 0.

*/
u8 DHTxx_read_byte(void)
{
    u8 i,rbyte = 0;
    pinMode(DHTxxBUS,INPUT);  // Set the DHTxx pin as input
    for (i=0 ; i < 8 ; i++) {
        while(digitalRead(DHTxxBUS) == LOW); // Wait for input to switch to HIGH
        delayMicroseconds(35); // Wait for digital 1 mid-point.
        if (digitalRead(DHTxxBUS) == HIGH) //  We have a digital 1
        {
            rbyte |= 1 << (7 - i); // Save the bit.
            while(digitalRead(DHTxxBUS) == HIGH); // Now wait until the HIGH switches to LOW.  Should take 35us.
        }
    }
    return rbyte;
}    

/*

DHTxx_take_reading() takes a reading from the DHTxx and returns a success status

To take a reading from the DHTxx, we must send out a start signal
and check for a response.  The timings are as follows:

Start signal (From MPU)    Response (From DHTxx)
                             <40us>< 80us ><40us>
Vcc  __         ____       __           _______
       \       /             \         /   ^   \
Gnd     \_____/               \___|___/         \
         20ms   30us            80us     80us

Firstly we set the DHTxx pin to be an output, then we drive the output
LOW for 20miliseconds and then HIGH for 30 microseconds.

Once the start signal has been sent, we must change the DHTxx pin to
be an input and wait 40us for the first mid-point, then 80us for
the second mid-point, followed by a 40us wait for the actual data to start.

If the two mid-points do not read as a zero followed by a one, then the
DHTxx is not present on the pin and the DHTxxNOTCONNECTED status is returned.

Once the checks have been completed, we receive five bytes from the DHTxx
as follows:

Byte 1: The integer part of the humdity reading.
Byte 2: The decimal part of the humidity reading (Always reads 0 on DHT11).
Byte 3: The integer part of the temprature reading.
Byte 4: The decimal part of the temprature reading (Always reads 0 on DHT11).
Byte 5: Checksum data

The checksum is the lower 8 bits of the sum of bytes 1-4.

Data can be displayed as (Integer part).(Decimal part)
For simple calculations, only the integer part is typically required.

*/
          
u8 DHTxx_take_reading() {
    u8 c,chk1,chk2 = 0;
    u8 DHTArray[5]; // local array to hold the 5 DHTxx bytes.
    pinMode(DHTxxBUS, OUTPUT); // Set DHTxx pin as output.
    digitalWrite(DHTxxBUS, LOW); // Drive DHTxx pin LOW to commence start signal
    delay(20); // Wait for 20 miliseconds
    digitalWrite(DHTxxBUS,HIGH); // Drive DHTxx pin HIGH
    delayMicroseconds(30); // Wait 30 microseconds
    pinMode(DHTxxBUS, INPUT); // Start signal sent, now change DHTxx pin to input.
    
    delayMicroseconds(40); // Wait 40us for mid-point of first response bit.
    chk1 = digitalRead(DHTxxBUS); // Read bit.  Should be a zero.
    delayMicroseconds(80); // Wait 80us for the mid-point of the second bit.
    chk2 = digitalRead(DHTxxBUS); // Read bit.  Should be a one.
    delayMicroseconds(40); // Wait 40us for end of response signal.
    if ((chk1 == 0) && (chk2 == 1)) { // If the response code is valid....
        for (c = 0 ; c < 5 ; c++) {
            DHTArray[c] = DHTxx_read_byte(); // Read five bytes from DHTxx
        }
        //  Now we calculate the checksum
        if (DHTArray[4] == ((DHTArray[0] + DHTArray[1] + DHTArray[2] + DHTArray[3]) & 0xFF))
        {
            // Checksum passed.  Now place data into the DHTxx structure
            DHTxxData.intRH = DHTArray[0]; // Integer humidity
            DHTxxData.decRH = DHTArray[1]; // Decimal humidity (0 on DHT11)
            DHTxxData.intTemp = DHTArray[2]; // Integer temprature
            DHTxxData.decTemp = DHTArray[3]; // Decimal temprature (0 on DHT11)
            return DHTxxRESULT; // Everything is okay, so return success code.
        }
        else
        {
            return DHTxxCHECKSUMFAILED; //  Sensor data was corrupted. Check pull-up resistor.
        }  
    } else {
        return DHTxxNOTCONNECTED; // No DHTxx detected.  Check wiring!
    }
}

Let me know what you think. File is attached too.


Attached Files
.pde   DHTxxSensors.pde (Size: 6.39 KB / Downloads: 23)
Reply
23-10-2013, 11:24 AM,
#2
RE: Well documented example to read DHTxx sensor on any Pinguino.
Great, you can put it in the example category in the wiki if you want.
Reply
23-10-2013, 03:20 PM,
#3
RE: Well documented example to read DHTxx sensor on any Pinguino.
(23-10-2013, 11:24 AM)koocotte Wrote: Great, you can put it in the example category in the wiki if you want.

I'll make it look a bit nicer & put it on the wiki in a few days!
Reply
19-01-2014, 10:57 PM,
#4
RE: Well documented example to read DHTxx sensor on any Pinguino.
(23-10-2013, 03:20 PM)niki_m Wrote: I'll make it look a bit nicer & put it on the wiki in a few days!

Hey niki,
I use your code to try my dht11 device. It works but I need to make a changes in DHTxx_read_byte function:
Code:
rbyte |= 1 << (7 - i); // Save the bit.
//while(digitalRead(DHTxxBUS) == HIGH); // Now wait until the HIGH switches to LOW.  Should take 35us.
delayMicroseconds(35);
Reply
20-01-2014, 12:39 PM,
#5
RE: Well documented example to read DHTxx sensor on any Pinguino.
Hi guys,
Don't know if it can be useful for you but do you know there's a one wire library for Pinguino (libraries/1wire.c) ?
Functions available are :
1wire.reset
1wire.readbit
1wire.writebit
1wire.readbyte
1wire.writebyte
It is easier to complain than it is to do, but it is better to do than it is to complain.
Reply
20-01-2014, 02:34 PM,
#6
RE: Well documented example to read DHTxx sensor on any Pinguino.
(20-01-2014, 12:39 PM)regis Wrote: Hi guys,
Don't know if it can be useful for you but do you know there's a one wire library for Pinguino (libraries/1wire.c) ?
Functions available are :
1wire.reset
1wire.readbit
1wire.writebit
1wire.readbyte
1wire.writebyte

Sure Regis...
but it works for 1-wire standard device (dallas...).
This kind of sensors work with their particular time regulated signal train.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)