#include "sht21.h"
struct {
sint16 value;
uint16 raw;
uint8 crc;
} aTemperature, aHumidity;
esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
// .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
};
esp_err_t err = i2c_param_config(i2c_master_port, &conf);
if (err != ESP_OK) {
return err;
}
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
// fT = 175.72*u16T/65536.0 - 46.85;
// fRH = 125.0*u16RH/65536.0 - 6.0;
// -------------------------------------------------------------------
sint16 sht21_calcRH(uint16 u16RH)
{
sint16 humidityRH; // variable for result
u16RH &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate relative humidity [%RH] --
humidityRH = (sint16)(-600 + (12500*(sint32)u16RH)/65536 ); // RH = -6 + 125 * SRH/2^16
return humidityRH; // Return RH*100
}
// -------------------------------------------------------------------
sint16 sht21_calcTemperature(uint16 u16T)
{
sint16 temperature; // variable for result
u16T &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate temperature [癈] --
temperature= (sint16)(-4685 + (17572*(sint32)u16T)/65536); //T = -46.85 + 175.72 * ST/2^16
return temperature; //return T*100
}
// i2c_cmd_handle_t cmd = i2c_cmd_link_create();
// i2c_master_start(cmd);
// i2c_master_write_byte(cmd, BH1750_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
// i2c_master_write_byte(cmd, BH1750_CMD_START, ACK_CHECK_EN);
// i2c_master_stop(cmd);
// ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
// i2c_cmd_link_delete(cmd);
// if (ret != ESP_OK) {
// return ret;
// }
// vTaskDelay(30 / portTICK_RATE_MS);
// cmd = i2c_cmd_link_create();
// i2c_master_start(cmd);
// i2c_master_write_byte(cmd, BH1750_SENSOR_ADDR << 1 | READ_BIT, ACK_CHECK_EN);
// i2c_master_read_byte(cmd, data_h, ACK_VAL);
// i2c_master_read_byte(cmd, data_l, NACK_VAL);
// i2c_master_stop(cmd);
// ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
// i2c_cmd_link_delete(cmd);
esp_err_t SHT2X_THMeasure(i2c_port_t i2c_num){
// uint8 u8Ack;
int ret;
uint8 t_value[3];
uint8 h_value[3];
#if (SHT2X_RESOLUTION != 0x00) // only needed if used resolution other than default
// i2c_start(); // send start sequence (S)
// u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_WRITE); // write to slave 0x40
// u8Ack = (u8Ack<<1)|i2c_write(SHT2X_CMD_RD_REG); // request to read from user register
// i2c_start(); // send start sequence (S)
// u8Ack = (u8Ack<<1)|i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_READ); // read from slave 0x40
// u8UserReg = i2c_read(I2C_NACK); // read user register
// i2c_start(); // send start sequence (S)
// u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_WRITE); // write to slave 0x40
// u8Ack = (u8Ack<<1)|i2c_write(SHT2X_CMD_WR_REG); // request to write user register
// u8Ack = (u8Ack<<1)|i2c_write(SHT2X_RESOLUTION | (u8UserReg & ~0x81)); // write new user register data
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS<<1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, SHT2X_CMD_WR_REG, ACK_CHECK_EN);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
return ret;
}
#endif//(SHT2X_RESOLUTION != 0x00)
// --------------------
// measure temperature
// --------------------
// i2c_start(); // send start sequence (S)
// u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_WRITE);//----IIC???(8?)???7??IIC????0x80(???HT2X_SLAVEADDRESS=0x40)???DATA???(?R:1 ,?WRITE?0) //a write to slave 0x40
// u8Ack = (u8Ack<<1)|i2c_write(SHT2X_CMD_MEAS_T); //----SHT2X_CMD_MEAS_T=0xF3(??????,???)//request to measure temperature
// i2c_stop();
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS<<1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, SHT2X_CMD_MEAS_T, ACK_CHECK_EN);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
return ret;
}
vTaskDelay(SHT2X_TEMP_MEAS_TIME / portTICK_RATE_MS);
// shortTermSleep(SHT2X_TEMP_MEAS_TIME);
// HAL_Delay(SHT2X_TEMP_MEAS_TIME);
// time_wait(SHT2X_TEMP_MEAS_TIME);
// i2c_start(); // send start sequence (SR)
// u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_READ); //----IIC???(8?)???7??IIC????0x80(???HT2X_SLAVEADDRESS=0x40)???DATA???(?R:1 ,?WRITE?0) // a read from slave 0x40
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, &t_value[0], ACK_VAL);
i2c_master_read_byte(cmd, &t_value[1], ACK_VAL);
i2c_master_read_byte(cmd, &t_value[2], NACK_VAL);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
// if(u8Ack==I2C_ACK) {
// aTemperature.raw = i2c_read(I2C_ACK)<<8; // read hi byte
// aTemperature.raw |= i2c_read(I2C_ACK); // read lo byte
// aTemperature.crc = i2c_read(I2C_NACK); // read check sum and finish transfere
// }else {
// aTemperature.raw = 0;
// }
// i2c_stop();
aTemperature.raw = t_value[0]<<8;
aTemperature.raw |= t_value[1];
aTemperature.crc = t_value[2];
// -------------------------
// Humidity Measure
// -------------------------
// i2c_start(); // send start sequence (S)
// u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_WRITE); // a write to slave 0x40 1000 0000
// u8Ack = (u8Ack<<1)|i2c_write(SHT2X_CMD_MEAS_RH); // request to measure humidity F5 1110 0101
// i2c_stop();
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS<<1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, SHT2X_CMD_MEAS_RH, ACK_CHECK_EN);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
return ret;
}
// shortTermSleep(SHT2X_HUMI_MEAS_TIME);
// HAL_Delay(SHT2X_HUMI_MEAS_TIME);
vTaskDelay(SHT2X_HUMI_MEAS_TIME / portTICK_RATE_MS);
// i2c_start(); // send start sequence (SR)
// u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_READ); // read from slave 0x40 1000 0001
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, &h_value[0], ACK_VAL);
i2c_master_read_byte(cmd, &h_value[1], ACK_VAL);
i2c_master_read_byte(cmd, &h_value[2], NACK_VAL);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
// if(u8Ack==I2C_ACK) { // timeout
// aHumidity.raw = i2c_read(I2C_ACK)<<8; // read hi byte
// aHumidity.raw |= i2c_read(I2C_ACK); // read lo byte
// aHumidity.crc = i2c_read(I2C_NACK); // read check sum and finish transfere
// }else{
// aHumidity.raw = 0;
// }
// i2c_stop();
// PowerOff();
aHumidity.raw = h_value[0] <<8; // read hi byte
aHumidity.raw |= h_value[1]; // read lo byte
aHumidity.crc = h_value[2]; // read check sum and finish transfere
aTemperature.value = sht21_calcTemperature(aTemperature.raw);
aHumidity.value = sht21_calcRH(aHumidity.raw); // signed value, temperature = aTemperature.value * 0.01?
if(aTemperature.crc!= sht21_CRC((uint8*)&aTemperature.raw, 2)) {}
if(aHumidity.crc!= sht21_CRC((uint8*)&aHumidity.raw, 2)) {}
if(aTemperature.value>5100) aTemperature.value=5100; //prevent temperature over-/underflow
else if(aTemperature.value<0) aTemperature.value=0;
if(aHumidity.value>10000) aTemperature.value=10000; //prevent temperature over-/underflow
else if(aTemperature.value<0) aTemperature.value=0;
return ret;
}
uint16_t getTemperature() {
return aTemperature.value;
}
uint16_t getHumidity() {
return aHumidity.value;
}
//==============================================================================
uint8 sht21_CRC(uint8 value[], uint8 u8Bytes) {
// CRC
const uint16 POLYNOMIAL = 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001
uint8 crc = 0;
uint8 byteCtr;
uint8 bitCtr;
//calculates 8-Bit checksum with given polynomial
for (byteCtr = 0; byteCtr < u8Bytes; ++byteCtr) {
crc ^= (value[byteCtr]);
for (bitCtr = 8; bitCtr > 0; --bitCtr)
{
if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
else crc = (crc << 1);
}
}
return crc;
}
评论