guowenxue
2024-06-16 b96bc188ee00b4ccfb80e5af4fd2f67df22e88fc
commit | author | age
1e563e 1 /*********************************************************************************
G 2  *      Copyright:  (C) 2024 LingYun IoT System Studio
3  *                  All rights reserved.
4  *
5  *       Filename:  sht20_fops.c
6  *    Description:  This file is temperature and relative humidity sensor SHT20 code
7  *
8  *        Version:  1.0.0(2024/05/08)
9  *         Author:  Guo Wenxue <guowenxue@gmail.com>
10  *      ChangeLog:  1, Release initial version on "2024/05/08 12:13:26"
11  *
12  * Pin connection:
13  *
14  *               SHT20 Module            IGKBoard
15  *                   VCC      <----->      3.3V
16  *                   SDA      <----->      #Pin3(I2C1_SDA)
17  *                   SCL      <----->      #Pin5(I2C1_SCL)
18  *                   GND      <----->      GND
19  *
20  * /run/media/mmcblk1p1/config.txt:
21  *
22  *          # Eanble I2C overlay
23  *          dtoverlay_i2c=1
24  **
25  ********************************************************************************/
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdint.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <time.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <sys/ioctl.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <linux/types.h>
40 #include <linux/i2c.h>
41 #include <linux/i2c-dev.h>
42
43 int sht20_checksum(uint8_t *data, int len, int8_t checksum);
44 static inline void msleep(unsigned long ms);
45 static inline void dump_buf(const char *prompt, uint8_t *buf, int size);
46
47 int main(int argc, char **argv)
48 {
49     int             fd, rv;
50     float           temp, rh;
51     char           *i2c_dev = NULL;
52     uint8_t         buf[4];
53
54
55     if( argc != 2)
56     {
57         printf("This program used to do I2C test by SHT20 sensor.\n");
58         printf("Usage: %s /dev/i2c-x\n", argv[0]);
59         return 0;
60     }
61
62     i2c_dev = argv[1];
63
64     /*+--------------------------------+
65      *|     open /dev/i2c-x device     |
66      *+--------------------------------+*/
67     if( (fd=open(i2c_dev, O_RDWR)) < 0)
68     {
69         printf("i2c device open failed: %s\n", strerror(errno));
70         return -1;
71     }
72
73     /*+--------------------------------+
74      *| set I2C mode and slave address |
75      *+--------------------------------+*/
76     ioctl(fd, I2C_TENBIT, 0);    /* Not 10-bit but 7-bit mode */
77     ioctl(fd, I2C_SLAVE, 0x40);  /* set SHT2x slava address 0x40 */
78
79     /*+--------------------------------+
80      *|   software reset SHT20 sensor  |
81      *+--------------------------------+*/
82
83     buf[0] = 0xFE;
84     write(fd, buf, 1);
85
86     msleep(50);
87
88
89     /*+--------------------------------+
90      *|   trigger temperature measure  |
91      *+--------------------------------+*/
92
93     buf[0] = 0xF3;
94     write(fd, buf, 1);
95
96     msleep(85); /* datasheet: typ=66, max=85 */
97
98     memset(buf, 0, sizeof(buf));
99     read(fd, buf, 3);
100     dump_buf("Temperature sample data: ", buf, 3);
101
102     if( !sht20_checksum(buf, 2, buf[2]) )
103     {
104         printf("Temperature sample data CRC checksum failure.\n");
105         goto cleanup;
106     }
107
108     temp = 175.72 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 46.85;
109
110
111     /*+--------------------------------+
112      *|    trigger humidity measure    |
113      *+--------------------------------+*/
114
115     buf[0] = 0xF5;
116     write(fd, buf, 1);
117
118     msleep(29); /* datasheet: typ=22, max=29 */
119
120     memset(buf, 0, sizeof(buf));
121     read(fd, buf, 3);
122     dump_buf("Relative humidity sample data: ", buf, 3);
123
124     if( !sht20_checksum(buf, 2, buf[2]) )
125     {
126         printf("Relative humidity sample data CRC checksum failure.\n");
127         goto cleanup;
128     }
129
130     rh = 125 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 6;
131
132     /*+--------------------------------+
133      *|    print the measure result    |
134      *+--------------------------------+*/
135
136     printf("Temperature=%lf 'C relative humidity=%lf%%\n", temp, rh);
137
138 cleanup:
139     close(fd);
140     return 0;
141 }
142
143 int sht20_checksum(uint8_t *data, int len, int8_t checksum)
144 {
145     int8_t crc = 0;
146     int8_t bit;
147     int8_t byteCtr;
148
149     //calculates 8-Bit checksum with given polynomial: x^8 + x^5 + x^4 + 1
150     for (byteCtr = 0; byteCtr < len; ++byteCtr)
151     {
152         crc ^= (data[byteCtr]);
153         for ( bit = 8; bit > 0; --bit)
154         {
155             /* x^8 + x^5 + x^4 + 1 = 0001 0011 0001 = 0x131 */
156             if (crc & 0x80) crc = (crc << 1) ^ 0x131;
157             else crc = (crc << 1);
158         }
159     }
160
161     if (crc != checksum)
162         return 0;
163     else
164         return 1;
165 }
166
167 static inline void msleep(unsigned long ms)
168 {
169     struct timespec cSleep;
170     unsigned long ulTmp;
171
172     cSleep.tv_sec = ms / 1000;
173     if (cSleep.tv_sec == 0)
174     {
175         ulTmp = ms * 10000;
176         cSleep.tv_nsec = ulTmp * 100;
177     }
178     else
179     {
180         cSleep.tv_nsec = 0;
181     }
182
183     nanosleep(&cSleep, 0);
184     return ;
185 }
186
187 static inline void dump_buf(const char *prompt, uint8_t *buf, int size)
188 {
189     int          i;
190
191     if( !buf )
192     {
193         return ;
194     }
195
196     if( prompt )
197     {
198         printf("%-32s ", prompt);
199     }
200
201     for(i=0; i<size; i++)
202     {
203         printf("%02x ", buf[i]);
204     }
205     printf("\n");
206
207     return ;
208 }