Project

General

Profile

dht22.c

modified sensor source - David Slimmer, 11/05/2019 06:19 AM

 
1
/*  dht22.c:
2
 *  library for dht22 using wiringPi functions
3
 *  Based on the existing dht11.c
4
 *  Amended by technion@lolware.net
5
 */
6

    
7
#include <wiringPi.h>
8

    
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <stdint.h>
12
#include <sys/types.h>
13
#include <unistd.h>
14

    
15
#include <sched.h>
16
#include <sys/mman.h>
17

    
18
#include "dht22.h"
19

    
20
#define MAXTIMINGS 85
21
static int dht22_dat[5] = {0,0,0,0,0};
22

    
23
/* sizecvt(read)
24
 * digitalRead() and friends from wiringpi are defined as returning a 
25
 * value < 256. However, they are returned as int() types. 
26
 * This is a safety function.
27
 */
28
static uint8_t sizecvt(const int read)
29
{
30
  if (read > 255 || read < 0)
31
  {
32
    printf("Invalid data from wiringPi library\n");
33
    exit(EXIT_FAILURE);
34
  }
35
  return (uint8_t)read;
36
}
37

    
38

    
39
/* read_dht22_dat(pin, &h, &t)
40
 * get humidity and temperature from the DHT22 on the given GPIO pin.
41
 */
42
int read_dht22_dat(int dhtpin, float *h, float *t)
43
{
44
  uint8_t laststate = HIGH;
45
  uint8_t counter = 0;
46
  uint8_t j = 0, i;
47

    
48
  dht22_dat[0] = dht22_dat[1] = dht22_dat[2] = dht22_dat[3] = dht22_dat[4] = 0;
49

    
50
  // elevate scheduling priority
51
  const struct sched_param priority = {1};
52
  sched_setscheduler(0, SCHED_FIFO, &priority);
53
  mlockall(MCL_CURRENT | MCL_FUTURE);
54

    
55
  // initiate a reading
56
  
57
  pinMode(dhtpin, OUTPUT);    // transmit
58
  //digitalWrite(dhtpin, HIGH); // clear the communications
59
  //delay(10);
60
  
61
  digitalWrite(dhtpin, LOW);  // pull pin down for 18 milliseconds
62
  delay(1);
63

    
64
  //digitalWrite(dhtpin, HIGH); // pull pin up for 40 microseconds
65
  //delayMicroseconds(40);
66
  
67
  // prepare to read the pin
68
  pinMode(dhtpin, INPUT);     // receive
69

    
70
  // detect change and read data
71
  for ( i=0; i< MAXTIMINGS; i++) {
72
    counter = 0;
73
    //printf("first state = %d\n", sizecvt(digitalRead(dhtpin)) );
74
    while (sizecvt(digitalRead(dhtpin)) == laststate) {
75
      delayMicroseconds(1);
76
      if (++counter == 255) break;
77
    }
78
    //printf("i=%d, counter=%d\n",i,counter);
79
    if (counter == 255) break;
80
    
81
    //laststate = sizecvt(digitalRead(dhtpin));
82
    /* printf("pin:%d  i=%d laststate:%d\n", dhtpin, i, laststate); */
83
    if (laststate == HIGH) {
84
            laststate = LOW;
85
     } else {
86
        laststate = HIGH;
87
     }
88

    
89
    // ignore first 3 transitions
90
    if ((i >= 3) && (i%2 == 0)) {
91
      // shove each bit into the storage bytes
92
      dht22_dat[j/8] <<= 1;
93
      if (counter > 50)
94
        dht22_dat[j/8] |= 1;
95
      j++;
96
    }
97
  }
98
  
99
  // check we received 40 bits (8bit x 5) & verify checksum in the last byte
100
  if ((j >= 40) && (dht22_dat[4] == ((dht22_dat[0] + dht22_dat[1] + dht22_dat[2] + dht22_dat[3]) & 0xFF)) ) {
101
    /* float t, h; */
102
    *h = (float)dht22_dat[0] * 256 + (float)dht22_dat[1];
103
    *h /= 10;
104
    *t = (float)(dht22_dat[2] & 0x7F)* 256 + (float)dht22_dat[3];
105
    *t /= 10.0;
106
    if ((dht22_dat[2] & 0x80) != 0)  *t *= -1;
107
    
108
    printf("hum=%3.1f, temp=%3.1f\n",*h, *t);
109

    
110
    // invalid if out of range
111
    if (*t < TEMPERATURE_RANGE_LO) return STATUS_INVALID;
112
    if (*t > TEMPERATURE_RANGE_HI) return STATUS_INVALID;
113
    if (*h < HUMIDITY_RANGE_LO) return STATUS_INVALID;
114
    if (*h > HUMIDITY_RANGE_HI) return STATUS_INVALID;
115

    
116
    return STATUS_NO_ERROR;
117
  } else {
118
    printf("j=%d, CS1=%d, CS2=%d\n",j, dht22_dat[4], ((dht22_dat[0] + dht22_dat[1] + dht22_dat[2] + dht22_dat[3]) & 0xFF) );
119
  }
120
  return STATUS_INVALID;
121
}