greenhousino/sensor433-arduino/dht22.cpp

150 lines
3.3 KiB
C++

/* Fast DHT Lirary
*
* Copyright (C) 2015 Sergey Denisov.
* Written by Sergey Denisov aka LittleBuster (DenisovS21@gmail.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version 3
* of the Licence, or (at your option) any later version.
*
* Original library written by Adafruit Industries. MIT license.
*
* https://github.com/LittleBuster/avr-dht22
*/
#include "dht22.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define DHT_COUNT 6
#define DHT_MAXTIMINGS 85
void dht_init(struct dht22 *dht, uint8_t pin)
{
dht->pin = pin;
/* Setup the pins! */
DDR_DHT &= ~(1 << dht->pin);
PORT_DHT |= (1 << dht->pin);
}
static uint8_t dht_read(struct dht22 *dht)
{
uint8_t tmp;
uint8_t sum = 0;
uint8_t j = 0, i;
uint8_t last_state = 1;
uint16_t counter = 0;
/*
* Pull the pin 1 and wait 250 milliseconds
*/
PORT_DHT |= (1 << dht->pin);
_delay_ms(250);
dht->data[0] = dht->data[1] = dht->data[2] = dht->data[3] = dht->data[4] = 0;
/* Now pull it low for ~20 milliseconds */
DDR_DHT |= (1 << dht->pin);
PORT_DHT &= ~(1 << dht->pin);
_delay_ms(20);
cli();
PORT_DHT |= (1 << dht->pin);
_delay_us(40);
DDR_DHT &= ~(1 << dht->pin);
/* Read the timings */
for (i = 0; i < DHT_MAXTIMINGS; i++) {
counter = 0;
while (1) {
tmp = ((PIN_DHT & (1 << dht->pin)) >> 1);
_delay_us(3);
if (tmp != last_state)
break;
counter++;
_delay_us(1);
if (counter == 255)
break;
}
last_state = ((PIN_DHT & (1 << dht->pin)) >> 1);
if (counter == 255)
break;
/* Ignore first 3 transitions */
if ((i >= 4) && (i % 2 == 0)) {
/* Shove each bit into the storage bytes */
dht->data[j/8] <<= 1;
if (counter > DHT_COUNT)
dht->data[j/8] |= 1;
j++;
}
}
sei();
sum = dht->data[0] + dht->data[1] + dht->data[2] + dht->data[3];
if ((j >= 40) && (dht->data[4] == (sum & 0xFF)))
return 1;
return 0;
}
uint8_t dht_read_temp(struct dht22 *dht, float *temp)
{
if (dht_read(dht)) {
*temp = dht->data[2] & 0x7F;
*temp *= 256;
*temp += dht->data[3];
*temp /= 10;
if (dht->data[2] & 0x80)
*temp *= -1;
return 1;
}
return 0;
}
uint8_t dht_read_hum(struct dht22 *dht, float *hum)
{
if (dht_read(dht)) {
*hum = dht->data[0];
*hum *= 256;
*hum += dht->data[1];
*hum /= 10;
if (*hum == 0.0f)
return 0;
return 1;
}
return 0;
}
uint8_t dht_read_data(struct dht22 *dht, float *temp, float *hum)
{
if (dht_read(dht)) {
/* Reading temperature */
*temp = dht->data[2] & 0x7F;
*temp *= 256;
*temp += dht->data[3];
*temp /= 10;
if (dht->data[2] & 0x80)
*temp *= -1;
/* Reading humidity */
*hum = dht->data[0];
*hum *= 256;
*hum += dht->data[1];
*hum /= 10;
if (*hum == 0.0f)
return 0;
return 1;
}
return 0;
}