A library for the use of DHT11, a temperature and humidity sensor

Dependents:   HTTP_SERVER2 lightweight-weather-station

DHT11.cpp

Committer:
s_inoue_mbed
Date:
2014-09-10
Revision:
4:48798b126d93
Parent:
1:95b80cc3f676
Child:
6:257e2ab66d0f

File content as of revision 4:48798b126d93:

/*
 * Library for the use of the DHT11, a temperature and humidity sensor
 * Shigenori Inoue, September 10, 2014
 */

#include "DHT11.h"

// Constructor
DHT11::DHT11(PinName pin) : io(pin, PIN_INPUT, OpenDrain, 1), io_irq(pin)
{
    io_irq.rise(this, &DHT11::pos_edge);
    io_irq.fall(this, &DHT11::neg_edge);
    io_irq.disable_irq();
    init();
}

// Destructor
DHT11::~DHT11(void) {}

// Reading the data bits from DHT11
int DHT11::readData()
{
    // Initialize
    eod = false;
    err = OK;
    data = 0;
    cnt = 0;
    wdt = 0;

    // Checking the measurement frequency
    if (t.read_ms() < 2000 & first_time == false) {
        t.reset();
        return TOO_FAST_READ;
    }

    // Checking the data bus
    if (io == 0) {
        io.input();
        return BUS_BUSY;
    }

    // Sending start signal
    io.output();
    t.reset();
    t.start();
    do {
        io = 0;
    } while (t.read_ms() < 18);
    io.input();
    io = 1;

    // Waiting for the start of the response signal
    t.reset();
    t.start();
    do {
        if (t.read_us() > 100) {
            io.input();
            io = 1;
            return NOT_PRESENT;
        }
    } while (io == 1);

    // Wainting for the start of the ready signal
    t.reset();
    t.start();
    do {
        if (t.read_us() > 100) {
            io.input();
            io = 1;
            return NOT_READY;
        }
    } while (io == 0);

    // Wainting for the end of the ready signal
    t.reset();
    t.start();
    do {} while (io == 1);

    // Starting the pulse width sensing

    io_irq.enable_irq();

    do {
        wait_us(100);
        if (wdt > 50) {
            return WATCHDOG_ERR;
        }
        wdt++;
    } while (eod == false);

    // Calculating the check sum
    chksum = ((data & 0xff00000000) >> 32)
             + ((data & 0x00ff000000) >> 24)
             + ((data & 0x0000ff0000) >> 16)
             + ((data & 0x000000ff00) >> 8);
    if (chksum != (data & 0x00000000ff)) {
        io.input();
        io = 1;
        return CHKSUM_ERR;
    } else {
        t.reset();
        first_time = false;
        return OK;
    }
}

// Extracting humidity data from the received data
int DHT11::readHumidity()
{
    if (err == OK) {
        return (data & 0xff00000000) >> 32;
    } else {
        return 0xffffffff;
    }
}

// Extracting temperature data from the received data
int DHT11::readTemperature()
{
    if (err == OK) {
        return (data & 0x0000ff0000) >> 16;
    } else {
        return 0xffffffff;
    }
}

// Initialization of variables
void DHT11::init(void)
{
    t_pulse_us = 0;
    first_time = true;
    data = 0;
    chksum = 0;
    cnt = 0;
    wdt = 0;
    err = OK;
    eod = false;
}

void DHT11::pos_edge(void)
{
    // Disabling the interruptions
    io_irq.disable_irq();

    // Initializing the Timer
    t.reset();

    // Enabling the interruptions
    io_irq.enable_irq();
}

void DHT11::neg_edge(void)
{
    // Disabling the interruptions
    io_irq.disable_irq();

    // Reading the length of
    t_pulse_us = t.read_us();

    // Detecting 0 if the pulse width ranges from 26 us to 28 us
    if (20 <= t_pulse_us && t_pulse_us <= 30) {
        // Shifting the data buffer and not adding 1 (because this bit is zero)
        data = data << 1;

        // Counting up the bits
        cnt++;
    }

    // Detecting 1 if the pulse width ranges from 68 us to 72 us
    else if (60 <= t_pulse_us && t_pulse_us <= 80) {
        // Shifting the data buffer and adding 1 (because this bit is one)
        data = data << 1;
        data++;

        // Counting up the bits
        cnt++;
    }

    // Detecting the end of Data
    if (cnt < 40) {
        // Enabling the interruptions
        io_irq.enable_irq();
    } else {
        eod = true;
    }
}