Gordons Projects

--> Projects Top-Level GIT

Updating for various stuff and bugs. CM3+ and PiA3+
[wiringPi] / wiringPi / htu21d.c
1 /*
2  * htu21d.c:
3  *      Extend wiringPi with the HTU21D I2C humidity and Temperature
4  *      sensor. This is used in the Pi Weather station.
5  *      Copyright (c) 2016 Gordon Henderson
6  ***********************************************************************
7  * This file is part of wiringPi:
8  *      https://projects.drogon.net/raspberry-pi/wiringpi/
9  *
10  *    wiringPi is free software: you can redistribute it and/or modify
11  *    it under the terms of the GNU Lesser General Public License as
12  *    published by the Free Software Foundation, either version 3 of the
13  *    License, or (at your option) any later version.
14  *
15  *    wiringPi is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU Lesser General Public License for more details.
19  *
20  *    You should have received a copy of the GNU Lesser General Public
21  *    License along with wiringPi.
22  *    If not, see <http://www.gnu.org/licenses/>.
23  ***********************************************************************
24  */
25
26 #include <unistd.h>
27 #include <stdint.h>
28 #include <stdio.h>
29 #include <math.h>
30
31 #include "wiringPi.h"
32 #include "wiringPiI2C.h"
33
34 #include "htu21d.h"
35
36 #define DEBUG
37 #undef  FAKE_SENSOR
38
39 #define I2C_ADDRESS     0x40
40
41 int checksum (UNU uint8_t data [4])
42 {
43   return TRUE ;
44 }
45
46
47
48 /*
49  * myAnalogRead:
50  *********************************************************************************
51  */
52
53 static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
54 {
55   int chan = pin - node->pinBase ;
56   int fd   = node->fd ;
57   uint8_t data [4] ;
58   uint32_t sTemp, sHumid ;
59   double   fTemp, fHumid ;
60   int      cTemp, cHumid ;
61
62   /**/ if (chan == 0)   // Read Temperature
63   {
64
65 // Send read temperature command:
66
67     data [0] = 0xF3 ;
68     if (write (fd, data, 1) != 1)
69       return -9999 ;
70
71 // Wait then read the data
72
73     delay (50) ;
74     if (read (fd, data, 3) != 3)
75       return -9998 ;
76
77     if (!checksum (data))
78       return -9997 ;
79
80 // Do the calculation
81
82     sTemp = (data [0] << 8) | data [1] ;
83     fTemp = -48.85 + 175.72 * (double)sTemp / 63356.0 ;
84     cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ;
85     return cTemp ;
86   }
87   else if (chan == 1)   // humidity
88   {
89 // Send read humidity command:
90
91     data [0] = 0xF5 ;
92     if (write (fd, data, 1) != 1)
93       return -9999 ;
94
95 // Wait then read the data
96
97     delay (50) ;
98     if (read (fd, data, 3) != 3)
99       return -9998 ;
100
101     if (!checksum (data))
102       return -9997 ;
103
104     sHumid = (data [0] << 8) | data [1] ;
105     fHumid = -6.0 + 125.0 * (double)sHumid / 65536.0 ;
106     cHumid = (int)rint (((100.0 * fHumid) + 0.5) / 10.0) ;
107     return cHumid ;
108   }
109   else
110     return -9999 ;
111 }
112
113
114 /*
115  * htu21dSetup:
116  *      Create a new instance of a HTU21D I2C GPIO interface.
117  *      This chip has a fixed I2C address, so we are not providing any
118  *      allowance to change this.
119  *********************************************************************************
120  */
121
122 int htu21dSetup (const int pinBase)
123 {
124   int fd ;
125   struct wiringPiNodeStruct *node ;
126   uint8_t data ;
127   int status ;
128
129   if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0)
130     return FALSE ;
131
132   node = wiringPiNewNode (pinBase, 2) ;
133
134   node->fd         = fd ;
135   node->analogRead = myAnalogRead ;
136
137 // Send a reset code to it:
138
139   data = 0xFE ;
140   if (write (fd, &data, 1) != 1)
141     return FALSE ;
142
143   delay (15) ;
144
145 // Read the status register to check it's really there
146
147   status = wiringPiI2CReadReg8 (fd, 0xE7) ;
148
149   return (status == 0x02) ? TRUE : FALSE ;
150 }