ads1115 analog-to-digital 4-channel added
[i2c-telemetry.git] / sht21.c
1 #include <stdio.h>
2 #include <sys/ioctl.h>
3 #include <fcntl.h>
4 #include <linux/i2c-dev.h>
5 #include <linux/i2c.h>
6
7 #include <unistd.h>             /* add by paulerr*/
8
9
10 #define CHIP                    "/dev/i2c-0"
11 #define CHIP_ADDR               0x40                    //HTU21D地址
12 #define READ_TEMP               0XE3                    //温度转换命令
13 #define READ_HUM                0XE5                    //湿度转换命令
14
15 /* More info: https://github.com/kingmacth/Openwet-SDK/tree/master/package/HTU21D  */
16
17 unsigned char HTU21D_Check_CRC(unsigned short int message_from_sensor,unsigned char check_value_from_sensor);
18
19 int main()
20
21 {
22          printf("hello,this is HTU21D tester \n");
23          int fd =open(CHIP, O_RDWR);
24          if (fd< 0) {
25                    printf("open"CHIP"failed \n");
26                    goto exit;
27          }
28
29          if (ioctl(fd,I2C_SLAVE_FORCE, CHIP_ADDR) < 0) {           /*设置芯片地址   */
30                    printf("oictl:setslave address failed\n");
31                    goto close;
32          }
33
34         struct          i2c_msg msg;
35
36         unsigned char      rddata[3];
37         unsigned char      rdaddr[2] = {0x10, 0};     /* 将要读取的数据在芯片中的偏移量  */
38         unsigned char      TempAddr[2] = {0xe3, 0};   /* 发送E3读取温度    */
39         unsigned char      HumAddr[2] = {0xE5, 0};    /* 发送E5读取湿度    */
40         unsigned short int tmp_dat,CRC_Result;
41         float Temp,Hum;
42          /*printf("inputa char you want to write to E2PROM\n");
43          wrbuf[2]= getchar();
44          printf("writereturn:%d, write data:%x\n", write(fd, wrbuf, 1), wrbuf[2]);
45          sleep(5);*/
46          //printf("Read temp!\n",write(fd, TempAddr, 1));      /* 开启温度转换    */
47         write(fd, TempAddr, 1);
48          usleep(100000);
49          read(fd, &rddata, 3);          //读取两字节温度一字节校验
50          
51         tmp_dat=rddata[0];
52         tmp_dat=tmp_dat<<8;
53         tmp_dat=tmp_dat+rddata[1];
54         //printf("rddata:%x%02x,%x\n", rddata[0], rddata[1],rddata[2]);
55         CRC_Result=HTU21D_Check_CRC(tmp_dat,rddata[2]);
56         //printf("CRC=%x,%x\n",CRC_Result ,tmp_dat);//CRC校验
57         if(CRC_Result==0)
58         {
59                 Temp=(tmp_dat*175.72)/65536-46.85;
60                 printf("Temp=%.2f\n",Temp);
61         }
62          //printf("Read hum!\n",write(fd, HumAddr, 1));      /* 开启湿度转换    */
63         write(fd, HumAddr, 1);
64          usleep(100000);
65          read(fd, &rddata, 3);          //读取两字节湿度一字节校验
66          
67         tmp_dat=rddata[0];
68         tmp_dat=tmp_dat<<8;
69         tmp_dat=tmp_dat+rddata[1];
70         //printf("rddata:%x%02x,%x\n", rddata[0], rddata[1],rddata[2]);
71         CRC_Result=HTU21D_Check_CRC(tmp_dat,rddata[2]);
72         //printf("CRC=%x,%x\n",CRC_Result ,tmp_dat);//CRC校验
73         if(CRC_Result==0)
74         {
75                 Temp=(tmp_dat*125)/65536-6;
76                 printf("Hum=%.2f%%RH\n",Temp);
77         }
78
79 close:
80          close(fd);
81 exit:
82          return 0;
83
84 }
85
86 //**************************************************************************************************************
87 //两个参数一个是传感器的源数据,另一个是传感器得出的CRC校验值
88 //如果校验通过返回0,不通过返回非0
89 //From: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html
90 //POLYNOMIAL = 0x0131 = x^8 + x^5 + x^4 + 1 : http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
91 #define SHIFTED_DIVISOR 0x988000 //This is the 0x0131 polynomial shifted to farthest left of three bytes
92 //**************************************************************************************************************
93 unsigned char HTU21D_Check_CRC(unsigned short int message_from_sensor,unsigned char check_value_from_sensor)
94 {
95 unsigned char i;
96 //Test cases from datasheet:
97 //message = 0xDC, checkvalue is 0x79
98 //message = 0x683A, checkvalue is 0x7C
99 //message = 0x4E85, checkvalue is 0x6B
100 unsigned int remainder = (unsigned int)message_from_sensor << 8; //Pad with 8 bits because we have to add in the check value
101 unsigned int divsor = (unsigned int)SHIFTED_DIVISOR;
102 remainder |= check_value_from_sensor; //Add on the check value
103 for (i = 0 ; i < 16 ; i++) //Operate on only 16 positions of max 24. The remaining 8 are our remainder and should be zero when we're done.
104 {
105 if( remainder & (unsigned int)1<<(23 - i) ) //Check if there is a one in the left position
106 remainder ^= divsor;
107 divsor>>=1;//Rotatethedivsormax16timessothatwehave8bitsleftofaremainder
108 }
109 return(unsigned char)remainder;
110 }