/********************************************************************************* * Copyright: (C) 2018 LingYun IoT System Studio * All rights reserved. * * Filename: sht20.c * Description: This file is temperature and relative humidity sensor SHT20 code * * Version: 1.0.0(2018/10/14) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26" * ********************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sht20.h" static int s_sht2x_fd = -1; void sht2x_term(void) { close(s_sht2x_fd); s_sht2x_fd = -1; printf("Terminate SHT2X\n"); } #ifdef I2C_API_RDWR /* Use I2C userspace driver read/write API */ int sht2x_softreset(int fd) { uint8_t buf[4]; if( fd<0 ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; } /* software reset SHT2x */ memset(buf, 0, sizeof(buf)); buf[0] = SOFTRESET; write(fd, buf, 1); msleep(50); return 0; } int sht2x_init(void) { if( (s_sht2x_fd=open("/dev/i2c-1", O_RDWR)) < 0) { printf("i2c device open failed: %s\n", strerror(errno)); return -1; } /* set I2C mode and SHT2x slave address */ ioctl(s_sht2x_fd, I2C_TENBIT, 0); /* Not 10-bit but 7-bit mode */ ioctl(s_sht2x_fd, I2C_SLAVE, 0x40); /* set SHT2x slava address 0x40*/ if( sht2x_softreset(s_sht2x_fd) < 0 ) { printf("SHT2x softreset failure\n"); sht2x_term(); return -2; } return s_sht2x_fd; } int sht2x_get_temp_humidity(float *temp, float *rh) { uint8_t buf[4]; if( !temp || !rh ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; } if( s_sht2x_fd < 0 ) { if( sht2x_init() < 0) { printf("SHT2x initialise failure\n"); return -2; } } /* send trigger temperature measure command and read the data */ memset(buf, 0, sizeof(buf)); buf[0]=TRIGGER_TEMPERATURE_NO_HOLD; write(s_sht2x_fd, buf, 1); msleep(85); /* datasheet: typ=66, max=85 */ memset(buf, 0, sizeof(buf)); read(s_sht2x_fd, buf, 3); //dump_buf("Temperature sample data: ", buf, 3); *temp = 175.72 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 46.85; /* send trigger humidity measure command and read the data */ memset(buf, 0, sizeof(buf)); buf[0] = TRIGGER_HUMIDITY_NO_HOLD; write(s_sht2x_fd, buf, 1); msleep(29); /* datasheet: typ=22, max=29 */ memset(buf, 0, sizeof(buf)); read(s_sht2x_fd, buf, 3); //dump_buf("Relative humidity sample data: ", buf, 3); *rh = 125 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 6; return 0; } int sht2x_get_serialnumber(uint8_t *serialnumber, int size) { uint8_t buf[4]; if( !serialnumber || size!=8 ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; } if( s_sht2x_fd < 0 ) { if( sht2x_init() < 0) { printf("SHT2x initialise failure\n"); return -2; } } /* Read SerialNumber from Location 1 */ memset(buf, 0, sizeof(buf)); buf[0] = 0xfa; /* command for readout on-chip memory */ buf[1] = 0x0f; /* on-chip memory address */ write(s_sht2x_fd, buf, 2); memset(buf, 0, sizeof(buf)); read(s_sht2x_fd, buf, 4); serialnumber[5]=buf[0]; /* Read SNB_3 */ serialnumber[4]=buf[1]; /* Read SNB_2 */ serialnumber[3]=buf[2]; /* Read SNB_1 */ serialnumber[2]=buf[3]; /* Read SNB_0 */ /* Read SerialNumber from Location 2 */ memset(buf, 0, sizeof(buf) ); buf[0]=0xfc; /* command for readout on-chip memory */ buf[1]=0xc9; /* on-chip memory address */ write(s_sht2x_fd, buf, 2); memset(buf, 0, sizeof(buf) ); read(s_sht2x_fd, buf, 4); serialnumber[1]=buf[0]; /* Read SNC_1 */ serialnumber[0]=buf[1]; /* Read SNC_0 */ serialnumber[7]=buf[2]; /* Read SNA_1 */ serialnumber[6]=buf[3]; /* Read SNA_0 */ //dump_buf("SHT2x Serial number: ", serialnumber, 8); return 0; } #elif (defined I2C_API_IOCTL) /* Use I2C userspace driver read/write API */ int sht2x_softreset(int fd) { struct i2c_msg msg; struct i2c_rdwr_ioctl_data sht2x_data; uint8_t buf[2]; if( fd<0 ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; } msg.addr= 0x40; msg.flags=0; //write msg.len= 1; msg.buf= buf; msg.buf[0]=SOFTRESET; sht2x_data.nmsgs= 1; sht2x_data.msgs= &msg; if( ioctl(fd, I2C_RDWR, &sht2x_data) < 0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); sht2x_term(); return -2; } msleep(50); return 0; } int sht2x_init(void) { if( (s_sht2x_fd=open("/dev/i2c-1", O_RDWR)) < 0) { printf("i2c device open failed: %s\n", strerror(errno)); return -1; } if( sht2x_softreset(s_sht2x_fd) < 0 ) { printf("SHT2x softreset failure\n"); sht2x_term(); return -2; } return 0; } int sht2x_get_serialnumber(uint8_t *serialnumber, int size) { struct i2c_msg msgs[2]; struct i2c_rdwr_ioctl_data sht2x_data; uint8_t sbuf[2]; uint8_t rbuf[4]; if( !serialnumber || size!=8 ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; } if( s_sht2x_fd < 0 ) { if( sht2x_init() < 0) { printf("SHT2x initialise failure\n"); return -2; } } /*+------------------------------------------+ *| Read SerialNumber from Location 1 | *+------------------------------------------+*/ msgs[0].addr= 0x40; msgs[0].flags=0; //write msgs[0].len= 2; msgs[0].buf= sbuf; msgs[0].buf[0]=0xfa; /* command for readout on-chip memory */ msgs[0].buf[1]=0x0f; /* on-chip memory address */ msgs[1].addr=0x40; msgs[1].flags=I2C_M_RD; //write msgs[1].len= 4; msgs[1].buf= rbuf; sht2x_data.nmsgs= 2; sht2x_data.msgs= msgs; if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); sht2x_term(); return -2; } serialnumber[5]=rbuf[0]; /* Read SNB_3 */ serialnumber[4]=rbuf[1]; /* Read SNB_2 */ serialnumber[3]=rbuf[2]; /* Read SNB_1 */ serialnumber[2]=rbuf[3]; /* Read SNB_0 */ /*+------------------------------------------+ *| Read SerialNumber from Location 2 | *+------------------------------------------+*/ msgs[0].addr= 0x40; msgs[0].flags=0; //write msgs[0].len= 2; msgs[0].buf= sbuf; msgs[0].buf[0]=0xfc; /* command for readout on-chip memory */ msgs[0].buf[1]=0xc9; /* on-chip memory address */ msgs[1].addr=0x40; msgs[1].flags=I2C_M_RD; //write msgs[1].len= 4; msgs[1].buf= rbuf; sht2x_data.nmsgs= 2; sht2x_data.msgs= msgs; if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); sht2x_term(); return -2; } serialnumber[1]=rbuf[0]; /* Read SNC_1 */ serialnumber[0]=rbuf[1]; /* Read SNC_0 */ serialnumber[7]=rbuf[2]; /* Read SNA_1 */ serialnumber[6]=rbuf[3]; /* Read SNA_0 */ //dump_buf("SHT2x Serial number: ", serialnumber, 8); return 0; } int sht2x_get_temp_humidity(float *temp, float *rh) { struct i2c_msg msg; struct i2c_rdwr_ioctl_data sht2x_data; uint8_t buf[4]; if( !temp || !rh ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; } if( s_sht2x_fd < 0 ) { if( sht2x_init() < 0) { printf("SHT2x initialise failure\n"); return -2; } } /*+------------------------------------------+ *| measure and get temperature | *+------------------------------------------+*/ msg.addr= 0x40; msg.flags=0; //write msg.len= 1; msg.buf= buf; msg.buf[0]=TRIGGER_TEMPERATURE_NO_HOLD; /* trigger temperature without hold I2C bus */ sht2x_data.nmsgs= 1; sht2x_data.msgs= &msg; if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); sht2x_term(); return -2; } msleep(85); memset(buf, 0, sizeof(buf)); msg.addr=0x40; msg.flags=I2C_M_RD; //write msg.len= 3; msg.buf= buf; sht2x_data.nmsgs= 1; sht2x_data.msgs= &msg; if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); sht2x_term(); return -2; } //dump_buf("Temperature sample data: ", buf, 3); *temp = 175.72 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 46.85; /*+------------------------------------------+ *| measure and get relative humidity | *+------------------------------------------+*/ msg.addr= 0x40; msg.flags=0; //write msg.len= 1; msg.buf= buf; msg.buf[0]=TRIGGER_HUMIDITY_NO_HOLD; /* trigger humidity without hold I2C bus */ sht2x_data.nmsgs= 1; sht2x_data.msgs= &msg; if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); sht2x_term(); return -2; } msleep(29); memset(buf, 0, sizeof(buf)); msg.addr=0x40; msg.flags=I2C_M_RD; //write msg.len= 3; msg.buf= buf; sht2x_data.nmsgs= 1; sht2x_data.msgs= &msg; if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); sht2x_term(); return -2; } //dump_buf("Relative humidity sample data: ", buf, 3); *rh = 125 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 6; return 0; } #endif