zoukankan      html  css  js  c++  java
  • ESP32S2获取sht30温湿度

    
    static const char *TAG = "i2c-temp";
    static unsigned char sht30_buf[6]={0}; 
    static float g_temp=0.0, g_rh=0.0;
    
    /**
     * I2C主机初始化
     */
    static esp_err_t i2c_master_init(void)
    {
        int i2c_master_port = I2C_MASTER_NUM;
        i2c_config_t conf;
        conf.mode = I2C_MODE_MASTER;
        conf.sda_io_num = IO_SENSOR_SDA;
        conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
        conf.scl_io_num = IO_SENSOR_SCL;
        conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
        conf.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);
    }
    
    /* 
     * 初始化sht30
     * _________________________________________________________________
     * | start | slave_addr + wr_bit + ack | write 1 byte + ack  | stop |
     * --------|---------------------------|---------------------|------|
     */
    int sht30_init(void)
    {
        int ret;
        //配置SHT30的寄存器
        i2c_cmd_handle_t cmd = i2c_cmd_link_create();                  // 新建操作I2C句柄
        i2c_master_start(cmd);                                         // 启动I2C
        i2c_master_write_byte(cmd, SHT30_WRITE_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);  // 发地址+写+检查ack
        i2c_master_write_byte(cmd, CMD_FETCH_DATA_H, ACK_CHECK_EN);                   // 发数据高8位+检查ack
        i2c_master_write_byte(cmd, CMD_FETCH_DATA_L, ACK_CHECK_EN);                   // 发数据低8位+检查ack
        i2c_master_stop(cmd);                                                         // 停止I2C
        ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 100 / portTICK_RATE_MS);      //I2C发送
        i2c_cmd_link_delete(cmd);                                                     //删除I2C句柄
        return ret;
    
    }
    
    /*
    * sht30校验算法
    * @param[in]   pdata                  :需要校验的数据
    * @param[in]   nbrOfBytes              :需要校验的数据长度
    * @retval      int                  :校验值
    */
    unsigned char SHT3X_CalcCrc(unsigned char *data, unsigned char nbrOfBytes)
    {
        unsigned char bit;                   // bit mask
        unsigned char crc = 0xFF;            // calculated checksum
        unsigned char byteCtr;               // byte counter
        unsigned int POLYNOMIAL =  0x131;    // P(x) = x^8 + x^5 + x^4 + 1 = 100110001
    
        // calculates 8-Bit checksum with given polynomial
        for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++) {
            crc ^= (data[byteCtr]);
            for(bit = 8; bit > 0; --bit) {
                if(crc & 0x80) {
                    crc = (crc << 1) ^ POLYNOMIAL;
                }  else {
                    crc = (crc << 1);
                }
            }
        }
        return crc;
    }
    
    /*
    * sht30数据校验
    * @param[in]   pdata                  :需要校验的数据
    * @param[in]   nbrOfBytes              :需要校验的数据长度
    * @param[in]   checksum              :校验的结果
    * @retval      int                  :0成功,其他失败
    */
    unsigned char SHT3X_CheckCrc(unsigned char *pdata, unsigned char nbrOfBytes, unsigned char checksum)
    {
        unsigned char crc;
        crc = SHT3X_CalcCrc(pdata, nbrOfBytes);// calculates 8-Bit checksum
        if(crc != checksum) 
        {   
            return 1;           
        }
        ESP_LOGI(TAG, "error crc:,%d", crc);
        return 0;              
    }
    
    
    /**
     * 获取sht30温湿度
     * ______________________________________________________________________________________
     * | start | slave_addr + rd_bit + ack | read 1 byte + ack  | read 1 byte + nack | stop |
     * --------|---------------------------|--------------------|--------------------|------|
     */
    int sht30_get_value(void)
    {
        ESP_LOGI(TAG, "begin sht30 get value");
        int ret;
        //配置SHT30的寄存器
        i2c_cmd_handle_t cmd = i2c_cmd_link_create();                                    //新建操作I2C句柄
        i2c_master_start(cmd);                                                           //启动I2C
        i2c_master_write_byte(cmd, SHT30_WRITE_ADDR << 1 | READ_BIT, ACK_CHECK_EN);      //发地址+读+检查ack
        i2c_master_read_byte(cmd, &sht30_buf[0], ACK_VAL);                               //读取数据+回复ack
        i2c_master_read_byte(cmd, &sht30_buf[1], ACK_VAL);                               //读取数据+回复ack
        i2c_master_read_byte(cmd, &sht30_buf[2], ACK_VAL);                               //读取数据+回复ack
        i2c_master_read_byte(cmd, &sht30_buf[3], ACK_VAL);                               //读取数据+回复ack
        i2c_master_read_byte(cmd, &sht30_buf[4], ACK_VAL);                               //读取数据+回复ack
        i2c_master_read_byte(cmd, &sht30_buf[5], NACK_VAL);                              //读取数据+不回复ack
        i2c_master_stop(cmd);                                                            //停止I2C
        ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 100 / portTICK_RATE_MS);         //I2C发送
        if(ret!=ESP_OK)
        {
            return ret;
        }
        i2c_cmd_link_delete(cmd);                                                       //删除I2C句柄
        //校验读出来的数据,算法参考sht30 datasheet
        if( (!SHT3X_CheckCrc(sht30_buf,2,sht30_buf[2])) && (!SHT3X_CheckCrc(sht30_buf+3,2,sht30_buf[5])) )
        {
            ret = ESP_OK;//成功
        }
        else
        {
            ret = 1;
        }
        ESP_LOGI(TAG, "ret:%d",ret);
        return ret;
    }
    
    static void i2c_temp_task(void *arg)
    {
        ESP_LOGI(TAG, "begin temp task");
        while (1) {       
            //获取温湿度
            if(sht30_get_value()==ESP_OK)   
            {
                //算法参考sht30 datasheet
                g_temp    =( ( (  (sht30_buf[0]*256) +sht30_buf[1]) *175   )/65535.0  -45  );
                g_rh  =  ( ( (sht30_buf[3]*256) + (sht30_buf[4]) )*100/65535.0) ;
                ESP_LOGI("SHT30", "temp:%4.2f ℃ 
    ", g_temp); // ℃打印出来是乱码,所以用C
                ESP_LOGI("SHT30", "hum:%4.2f %%RH 
    ", g_rh);
            }
            vTaskDelay(6000/portTICK_RATE_MS);
        }
        vTaskDelete(NULL);
    }
    
    void i2c_temp_start(void)
    {
        ESP_LOGI(TAG, "start get temperature and humidity");
        ESP_ERROR_CHECK(i2c_master_init());
        sht30_init(); 
        vTaskDelay(500/portTICK_RATE_MS);  
        xTaskCreate(i2c_temp_task, "i2c_temp_task", 1024 * 2, (void *)0, 10, NULL);
    }
  • 相关阅读:
    Comet OJ
    LOJ#2719. 「NOI2018」冒泡排序 DP+组合+树状数组
    LuoguP6747 『MdOI R3』Teleport 二进制+贪心
    LuoguP6748 『MdOI R3』Fallen Lord 树形DP+set
    LuoguP5576 [CmdOI2019]口头禅 后缀树+线段树+暴力
    LOJ#3161. 「NOI2019」I 君的探险 整体二分+随机化+二进制分组
    LOJ#2085. 「NOI2016」循环之美 莫比乌斯反演+杜教筛
    LuoguP5327 [ZJOI2019]语言 线段树合并+树链求并
    【考试题
    ELK
  • 原文地址:https://www.cnblogs.com/kerwincui/p/14489261.html
Copyright © 2011-2022 走看看