基于树莓派SHT20温湿度采样

上一篇介绍了i2c协议,SHT20是使用标准的i2c接口的温湿度传感器,我们首先要完成树莓派与SHT20传感器的连接:
在这里插入图片描述
使能内核I2C驱动模块:

liruiyan@cloud-ubuntu18:~$  sudo raspi-config

在这里插入图片描述
重启树莓派,系统启动之后会自动安装i2c的相关驱动:

liruiyan@cloud-ubuntu18:~$  sudo reboot
liruiyan@cloud-ubuntu18:~$  sudo apt-get install i2c-tools
liruiyan@cloud-ubuntu18:~$  lsmod | grep i2c
i2c_bcm2835         16384 0
i2c_dev             16384 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- 

使用i2cdetect命令可以查看到SHT21温湿度传感器设备地址0x40。
i2c设备驱动有两种模式:一种是用户模式设备驱动,这种驱动依赖于i2c子系统中i2c-dev驱动,这种驱动对应用程序员的要求很高,要
求应用程序员了解硬件的一些东西,了解时序、地址等;另一种是普通的设备驱动,应用程序员在使用的时候就像读写文件
一样,不过这里的read()和write()函数只能对应一条消息。
liruiyan@cloud-ubuntu18:~$ vim sht20.c

  1 #include <stdio.h>
  2 #include <fcntl.h>
  3 #include <unistd.h>
  4 #include <sys/ioctl.h>
  5 #include <linux/types.h>
  6 #include <sys/stat.h>
  7 #include <linux/i2c.h>
  8 #include <linux/i2c-dev.h>
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <sys/types.h>
 12 #include <string.h>
 13 #include <stdint.h>
 14 #include <time.h>
 15 #include <errno.h>
 16 #include <string.h>
 17 #define SOFTRESET                        0xFE 
 18 #define TRIGGER_TEMPERATURE_NO_HOLD      0xF3   //监测温度
 19 #define TRIGGER_HUMIDITY_NO_HOLD         0xF5   //监测湿度
 20 //#define I2C_API_IOCTL  /* Use I2C userspace driver ioctl API */
 21 #define I2C_API_RDWR  /* Use I2C userspace driver read/write API */
 22 static inline void msleep(unsigned long ms);
 23 static inline void dump_buf(const char *prompt, uint8_t *buf, int size);
 24 int sht2x_init(void); int sht2x_softreset(int fd);
 25 int sht2x_get_serialnumber(int fd, uint8_t serialnumber, int size);
 26 int sht2x_get_temp_humidity(int fd, float temp, float *rh);
 27 
 28 
 29 static inline void msleep(unsigned long ms)
 30 {
 31     struct timespec cSleep;
 32     unsigned long ulTmp;
 33     cSleep.tv_sec = ms / 1000;
 34 
 35     if (cSleep.tv_sec == 0)
  36     {
 37         ulTmp = ms * 10000;
 38         cSleep.tv_nsec = ulTmp * 100;
 39     }
 40     else
 41     {
 42         cSleep.tv_nsec = 0;
 43     }
 44     nanosleep(&cSleep, 0);
 45 }
 46 
 47 static inline void dump_buf(const char *prompt, uint8_t *buf, int size)
 48 {
 49     int          i;
 50     if( !buf )
 51     {
 52         return ;
 53     }
 54     if( prompt )
 55     {
 56         printf("%s ", prompt);
 57     }
 58     for(i=0; i<size; i++)
 59     {
 60         printf("%02x ", buf[i]);
 61     }
 62     printf("\n");
 63     return ;
 64 }
 65      /*设备初始化*/
 66 int sht2x_init(void)
 67 {
 68     int     fd;
 69     if( (fd=open("/dev/i2c-1", O_RDWR)) < 0)
 70     {
 71         printf("i2c device open failed: %s\n", strerror(errno));
 72         return -1;
 73     }
 74     /* set I2C mode and SHT2x slave address */
 75     ioctl(fd, I2C_TENBIT, 0);    /* Not 10-bit but 7-bit mode */
 76     ioctl(fd, I2C_SLAVE, 0x40); /* 我的sht20设备地址 */
 77     return fd;
 78 }
 79 
 80       /* 软复位 */
 81 int sht2x_softreset(int fd)
 82 {
 83     uint8_t           buf[4];
 84     if( fd<0 )
 85     {
 86         printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ );
 87         return -1;
 88     }
 89     /* software reset SHT2x */
 90     memset(buf, 0, sizeof(buf));
 91     buf[0] = SOFTRESET;
 92     write(fd, buf, 1);
 93     msleep(50);
 94 
 95     return 0;
 96 }
 97 
 98     /*获取温湿度*/
 99 int sht2x_get_temp_humidity(int fd, float *temp, float *rh)    //获取温湿度
100 {
101     uint8_t           buf[4];
102     if( fd<0 || !temp || !rh )
103     {
104         printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ );
105         return -1;
106     }
107 
108     /* send trigger temperature measure command and read the data */
109     memset(buf, 0, sizeof(buf));
110     buf[0]=TRIGGER_TEMPERATURE_NO_HOLD;
111     write(fd, buf, 1);  //发送监测温度命令
112 
113     msleep(85); /* datasheet: typ=66, max=85 */
114     memset(buf, 0, sizeof(buf));
115     read(fd, buf, 3);  //读取温度  
116     dump_buf("Temperature sample data: ", buf, 3);
117     *temp = 175.72 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 46.85;
118 
119     /* send trigger humidity measure command and read the data */
120 
121     memset(buf, 0, sizeof(buf));
122     buf[0] = TRIGGER_HUMIDITY_NO_HOLD;
123     write(fd, buf, 1);  //发送湿度监测命令
124     msleep(29); /* datasheet: typ=22, max=29 */
125     memset(buf, 0, sizeof(buf));
126     read(fd, buf, 3);
127     dump_buf("Relative humidity sample data: ", buf, 3);
128     *rh = 125 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 6;
129 
130     return 0;
131 }
132                  /*获取序列号*/
133 int sht2x_get_serialnumber(int fd, uint8_t *serialnumber, int size)
134 {
135     uint8_t buf[4];
136     if( fd<0 || !serialnumber || size!=8 )
137     {
138         printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ );
139         return -1;
140     }
141     memset(buf, 0, sizeof(buf));
142     buf[0] = 0xfa;
143     buf[1] = 0x0f;
144     write(fd, buf, 2);
145 
146     memset(buf, 0, sizeof(buf));
147     read(fd, buf, 4);
148 
149     serialnumber[5]=buf[0]; /*  Read SNB_3 */
150     serialnumber[4]=buf[1]; /*  Read SNB_2 */
151     serialnumber[3]=buf[2]; /*  Read SNB_1 */
152     serialnumber[2]=buf[3]; /*  Read SNB_0 */
153 
154     memset(buf, 0, sizeof(buf) );
155     buf[0]=0xfc; /*  command for readout on-chip memory */
156     buf[1]=0xc9; /*  on-chip memory address */
157     write(fd, buf, 2);
158 
159     memset(buf, 0, sizeof(buf) );
160     read(fd, buf, 4);
161     serialnumber[1]=buf[0]; /*  Read SNC_1 */
162     serialnumber[0]=buf[1]; /*  Read SNC_0 */
163     serialnumber[7]=buf[2]; /*  Read SNA_1 */
164     serialnumber[6]=buf[3]; /*  Read SNA_0 */
165     dump_buf("SHT2x Serial number: ", serialnumber, 8);
166 
167     return 0;
168 }
169 int main(int argc, char **argv)
170 {
171     int fd;
172     float temp;
173     float rh;
174     uint8_t serialnumber[8];
175     fd = sht2x_init();
176     if(fd < 0)
177     {
178         printf("SHT2x initialize failure\n");
179         return 1;
180     }
181     if( sht2x_softreset(fd) < 0 )
182     {
183         printf("SHT2x softreset failure\n");
184         return 2;
185     }
186     if( sht2x_get_serialnumber(fd, serialnumber, 8) < 0)
187     {
188         printf("SHT2x get serial number failure\n");
189         return 3;
190     }

运行结果:

SHT2x Serial number: 40 01 7c 38 da 3e 00 c9
Temperature sample data: 72 28 dd
Relative humidity sample data: 9e 66 3d
Temperature=31.507563 ℃ relative humidity=71.342987%
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mierya0707

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值