[ESP32] IIC驱动温度湿度传感器SHT3x

/* i2c - Simple example
   Simple I2C example that shows how to initialize I2C
   as well as reading and writing from and to registers for a sensor connected over I2C.
   The sensor used in this example is a SHT3X inertial measurement unit.
*/
#include <stdio.h>
#include "esp_log.h"
#include "driver/i2c.h"


#define SHT31_DEFAULT_ADDR 0x44 /**< SHT31 Default Address */
#define SHT31_MEAS_HIGHREP_STRETCH                                             \
  0x2C06 /**< Measurement High Repeatability with Clock Stretch Enabled */
#define SHT31_MEAS_MEDREP_STRETCH                                              \
  0x2C0D /**< Measurement Medium Repeatability with Clock Stretch Enabled */
#define SHT31_MEAS_LOWREP_STRETCH                                              \
  0x2C10 /**< Measurement Low Repeatability with Clock Stretch Enabled*/
#define SHT31_MEAS_HIGHREP                                                     \
  0x2400 /**< Measurement High Repeatability with Clock Stretch Disabled */
#define SHT31_MEAS_MEDREP                                                      \
  0x240B /**< Measurement Medium Repeatability with Clock Stretch Disabled */
#define SHT31_MEAS_LOWREP                                                      \
  0x2416 /**< Measurement Low Repeatability with Clock Stretch Disabled */
#define SHT31_READSTATUS 0xF32D   /**< Read Out of Status Register */
#define SHT31_CLEARSTATUS 0x3041  /**< Clear Status */
#define SHT31_SOFTRESET 0x30A2    /**< Soft Reset */
#define SHT31_HEATEREN 0x306D     /**< Heater Enable */
#define SHT31_HEATERDIS 0x3066    /**< Heater Disable */
#define SHT31_REG_HEATER_BIT 0x0d /**< Status Register Heater Bit */



#define portTICK_RATE_MS           1
 
#define I2C_MASTER_SDA_IO           19   //CONFIG_I2C_MASTER_SDA      /*!< GPIO number used for I2C master data  */
#define I2C_MASTER_SCL_IO           18   //CONFIG_I2C_MASTER_SCL      /*!< GPIO number used for I2C master clock */
 
#define I2C_MASTER_NUM              0                          /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ          10000                     /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE   0                          /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE   0                          /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS       150
 
 
#define SHT3X_SENSOR_ADDR            0x44       /*!< Slave address of the SHT3X sensor */


 
 
/**
 * @brief Read a sequence of bytes from a SHT3X sensor registers
 */
static esp_err_t SHT3X_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{
    /*esp_err_t i2c_master_write_read_device(i2c_port_t i2c_num, uint8_t device_address,
                                       const uint8_t* write_buffer, size_t write_size,
                                       uint8_t* read_buffer, size_t read_size,
                                       TickType_t ticks_to_wait)
                                       */
    return i2c_master_write_read_device(I2C_MASTER_NUM, SHT3X_SENSOR_ADDR, &reg_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);
}
 
/**
 * @brief Write N byte to a SHT3X sensor register
 */
static esp_err_t SHT3X_register_write(uint8_t reg_addr, uint8_t *data,int len)
{
    int ret = 0;
    uint8_t *wr_dat = (uint8_t*) malloc(len+1);
 
    if(wr_dat==NULL)
      return -1;
 
    wr_dat[0] = reg_addr;
 
    for(int i=0;i<len;i++)
    {
        wr_dat[i+1] = data[i];
    }
    ret = i2c_master_write_to_device(I2C_MASTER_NUM, SHT3X_SENSOR_ADDR, wr_dat, len+1, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);
    
    free(wr_dat);
 
    return ret;
}

static esp_err_t SHT3X_write(uint8_t *data,int len)
{
    int ret = 0;
 
    ret = i2c_master_write_to_device(I2C_MASTER_NUM, SHT3X_SENSOR_ADDR, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);
 
    return ret;
}



 
/**
 * @brief i2c master initialization
 */
static 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,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ,
    };
 
    i2c_param_config(i2c_master_port, &conf);
 
    return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}


void delay(int ms)
{
   vTaskDelay(ms);
}
 

/**
 * Performs a CRC8 calculation on the supplied values.
 *
 * @param data  Pointer to the data to use when calculating the CRC8.
 * @param len   The number of bytes in 'data'.
 *
 * @return The computed CRC8 value.
 */
static uint8_t crc8(const uint8_t *data, int len) {
  /*
   *
   * CRC-8 formula from page 14 of SHT spec pdf
   *
   * Test data 0xBE, 0xEF should yield 0x92
   *
   * Initialization data 0xFF
   * Polynomial 0x31 (x8 + x5 +x4 +1)
   * Final XOR 0x00
   */

  const uint8_t POLYNOMIAL=(0x31);
  uint8_t crc=(0xFF);

  for (int j = len; j; --j) {
    crc ^= *data++;

    for (int i = 8; i; --i) {
      crc = (crc & 0x80) ? (crc << 1) ^ POLYNOMIAL : (crc << 1);
    }
  }
  return crc;
}



bool writeCommand(uint16_t command) {
  
  uint8_t cmd[2];
  cmd[0] = command >> 8;
  cmd[1] = command & 0xFF;

  return SHT3X_write(cmd, 2);
}


bool readTempHum(float *tempOut,float *humOut) 
{
  
  uint8_t readbuffer[6]={0};

  writeCommand(SHT31_MEAS_HIGHREP);

  delay(20);

  i2c_master_read_from_device(I2C_MASTER_NUM, SHT3X_SENSOR_ADDR,readbuffer, sizeof(readbuffer),I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);

  if (readbuffer[2] != crc8(readbuffer, 2) ||
      readbuffer[5] != crc8(readbuffer + 3, 2))
    return false;

  int32_t stemp = (int32_t)(((uint32_t)readbuffer[0] << 8) | readbuffer[1]);
  // simplified (65536 instead of 65535) integer version of:
  // temp = (stemp * 175.0f) / 65535.0f - 45.0f;
  stemp = ((4375 * stemp) >> 14) - 4500;
  *tempOut = (float)stemp / 100.0f;

  uint32_t shum = ((uint32_t)readbuffer[3] << 8) | readbuffer[4];
  // simplified (65536 instead of 65535) integer version of:
  // humidity = (shum * 100.0f) / 65535.0f;
  shum = (625 * shum) >> 12;
  *humOut = (float)shum / 100.0f;

  return true;
}

 
 
void sht3x_app_main(void)
{
     
    ESP_ERROR_CHECK(i2c_master_init());
    printf("I2C initialized successfully,BUILD:[%s %s]",__DATE__,__TIME__);
 
    int cnt = 0;
    bool ret = true;
    float temp = 0.0;
    float humidity = 0.0;
    
    float tempAll = 0;
    float humAll = 0;
    
    while(true)
    {
      int count = 100;
      tempAll = 0;
      humAll = 0;
      for (size_t i = 0; i < count; i++)
      {
        temp = 0;
        humidity = 0;
        ret = readTempHum(&temp,&humidity);
        if(!ret)
        {
          printf("=====Read Error=====\n");
          break;
        }
        tempAll+=temp;
        humAll+=humidity;
      }

      temp = tempAll/count;
      humidity = humAll/count;
      cnt++;
      printf("[%d] temp=%.2f,hum=%.2f  \n",cnt,temp,humidity);
      vTaskDelay(100);
    }
  
 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值