-
Notifications
You must be signed in to change notification settings - Fork 3
/
dht22.c
147 lines (124 loc) · 3.27 KB
/
dht22.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* 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.
*/
#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;
}