ESP32-硬件IIC读取温湿度传感器SHT30

这篇具有很好参考价值的文章主要介绍了ESP32-硬件IIC读取温湿度传感器SHT30。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

esp32 使用硬件I2C读取温湿度传感器SHT30,例程基于EDP-IDF-4.4.X 的I2C Simple Example 例程修改

工程创建

  1. 打开 VSCODE ,通过 查看-- 命令面板(快捷键Ctrl+Shift+P),打开 ESP-IDF 的例程后,选择 i2c_simple 例程,点击 Create project using example i2c_simple,选择自己要存储的目录。【PS:工程的目录不要有中文路径】
    ESP32-硬件IIC读取温湿度传感器SHT30
  2. 打开刚刚创建的 i2c_simple 例程,该例程是使用 I2C 读取三轴加速度传感器 MPU9250,我们在这个基础上开始修改 ,首先删除 MPU9250 相关的函数,具体如下:
    ESP32-硬件IIC读取温湿度传感器SHT30

ESP32-硬件IIC读取温湿度传感器SHT30
3. 工程添加 SHT3X 温湿度传感器的驱动

创建components/sht3x/src、components/sht3x/include 这两个文件夹,将 i2c_sht3x.c 和i2c_sht3x.h 分别放入 src 和 include 文件夹中;复制CMakeLists.txt、component.mk到components/sht3x下。工程目录结构如下:
ESP32-硬件IIC读取温湿度传感器SHT30

  • i2c_sht3x.c
#include "i2c_sht3x.h"


#define ACK_CHECK_EN   0x1     /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS  0x0     /*!< I2C master will not check ack from slave */
#define ACK_VAL    0x0         /*!< I2C ack value */
#define NACK_VAL   0x1         /*!< I2C nack value */

/* 
1. 在使用SHT3X传感器的驱动之前,需要先调用 
esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_buf_len, size_t slv_tx_buf_len,int intr_alloc_flags) 
初始化I2C
2. 在 i2c_sht3x.h 中根据实际使用的I2C总线修改宏定义 SHT3X_I2C_BUS 的值 

*/
/**
 * @brief  I2Cx-写从设备的寄存器值
 *      - 带有写器件寄存器的方式,适用于 MPU6050、ADXL345、HMC5983、MS5611、BMP280等绝大多数I2C设备
 *      - 例:i2c_master_write_slave_reg(I2C_NUM_0, 0x68, 0x75, &test, 1, 100 / portTICK_RATE_MS);
 * 
 * ____________________________________________________________________________________
 * | start | slave_addr + wr_bit + ack | reg_addr + ack | write n bytes + ack  | stop |
 * --------|---------------------------|----------------|----------------------|------|
 * 
 * @param  i2c_num I2C端口号。I2C_NUM_0 / I2C_NUM_1
 * @param  slave_addr I2C写从机的器件地址
 * @param  reg_addr I2C写从机的寄存器地址
 * @param  data_wr 写入的值的指针,存放写入进的数据
 * @param  size 写入的寄存器数目
 * @param  ticks_to_wait 超时等待时间
 * 
 * @return
 *     - esp_err_t
 */
esp_err_t i2c_master_write_slave_reg(i2c_port_t i2c_num, uint8_t slave_addr, uint8_t reg_addr, uint8_t *data_wr, size_t size, TickType_t ticks_to_wait)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
    i2c_master_write_byte(cmd, reg_addr, ACK_CHECK_EN);
    i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, ticks_to_wait);
    i2c_cmd_link_delete(cmd);
    return ret;
}

/**
 * @brief  I2Cx-读从设备的寄存器值(寄存器地址 或 命令 为2字节的器件)
 *      - 带有读器件寄存器的方式,适用于 SHT20、GT911 这种寄存器地址为16位的I2C设备
 *      - 例:i2c_master_read_slave_reg_16bit(I2C_NUM_0, 0x44, 0xE000, &test, 6, 100 / portTICK_RATE_MS);
 * 
 * ____________________________________________________________________________________________________________________________________________________
 * | start | slave_addr + rd_bit + ack | reg_addr(2byte) + ack | start | slave_addr + wr_bit + ack | read n-1 bytes + ack | read 1 byte + nack | stop |
 * --------|---------------------------|-------------------------------|---------------------------|----------------------|--------------------|------|
 * 
 * @param  i2c_num I2C端口号。I2C_NUM_0 / I2C_NUM_1
 * @param  slave_addr I2C读从机的器件地址
 * @param  reg_addr I2C读从机的寄存器地址(2byte)
 * @param  data_rd 读出的值的指针,存放读取出的数据
 * @param  size 读取的寄存器数目
 * @param  ticks_to_wait 超时等待时间
 * 
 * @return
 *     - esp_err_t
 */
esp_err_t i2c_master_read_slave_reg_16bit(i2c_port_t i2c_num, uint8_t slave_addr, uint16_t reg_addr, uint8_t *data_rd, size_t size, TickType_t ticks_to_wait)
{
    if (size == 0) {
        return ESP_OK;
    }
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
    i2c_master_write_byte(cmd, reg_addr>>8, ACK_CHECK_EN);
    i2c_master_write_byte(cmd, reg_addr, ACK_CHECK_EN);
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_READ, ACK_CHECK_EN);
    if (size > 1) {
        i2c_master_read(cmd, data_rd, size - 1, ACK_VAL);
    }
    i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, ticks_to_wait);
    i2c_cmd_link_delete(cmd);
    return ret;
}


/**
 * @brief    向SHT3x发送一条指令(16bit)
 * 
 * @param    cmd —— SHT3x指令(在SHT3x_MODE中枚举定义)
 * 
 * @retval    成功返回HAL_OK(ESP_OK)
*/
static uint8_t SHT3X_Send_Cmd(SHT30_CMD cmd)
{
    uint8_t cmd_buffer[2];
    cmd_buffer[0] = cmd >> 8;
    cmd_buffer[1] = cmd;
    return i2c_master_write_slave_reg(SHT3X_I2C_BUS, SHT3X_SLAVE_ADDRESS, cmd_buffer[0], cmd_buffer+1, 1, SHT3X_TICKS_TO_WAIT);
}

/**
 * @brief    复位SHT3X
 * 
 * @param    none
 * 
 * @retval    none
*/
void sht3x_reset(void)
{
    SHT3X_Send_Cmd(SOFT_RESET_CMD);
    vTaskDelay(20 / portTICK_PERIOD_MS);
}

/**
 * @brief    初始化SHT30
 * 
 * @param    none
 * 
 * @retval    成功返回HAL_OK(ESP_OK)
 * 
 * @note    周期测量模式
*/
esp_err_t sht3x_init(void)
{
    return SHT3X_Send_Cmd(MEDIUM_2_CMD);
}


/**
 * @brief    从SHT3X读取一次数据
 * 
 * @param    dat —— 存储读取数据的地址(6个字节数组)
 * 
 * @retval    成功 —— 返回HAL_OK(ESP_OK)
*/
esp_err_t sht3x_read_th_raw_dat(uint8_t* dat)
{
    return i2c_master_read_slave_reg_16bit(SHT3X_I2C_BUS, SHT3X_SLAVE_ADDRESS, READOUT_FOR_PERIODIC_MODE, dat, 6, SHT3X_TICKS_TO_WAIT);
}

#define CRC8_POLYNOMIAL 0x31

static uint8_t SHT3X_CheckCrc8(uint8_t* const message, uint8_t initial_value)
{
    uint8_t  remainder;        //余数
    uint8_t  i = 0, j = 0;  //循环变量

    /* 初始化 */
    remainder = initial_value;

    for(j = 0; j < 2;j++)
    {
        remainder ^= message[j];

        /* 从最高位开始依次计算  */
        for (i = 0; i < 8; i++)
        {
            if (remainder & 0x80)
            {
                remainder = (remainder << 1)^CRC8_POLYNOMIAL;
            }
            else
            {
                remainder = (remainder << 1);
            }
        }
    }

    /* 返回计算的CRC码 */
    return remainder;
}

/**
 * @brief    将SHT30接收的6个字节数据进行CRC校验,并转换为温度值和湿度值
 * 
 * @param    dat  —— 存储接收数据的地址(6个字节数组)
 * 
 * @retval    校验成功  —— 返回0
 *            校验失败  —— 返回1,并设置温度值和湿度值为0
*/
uint8_t sht3x_dat2float(uint8_t* const dat, float* temperature, float* humidity)
{
    uint16_t recv_temperature = 0;
    uint16_t recv_humidity = 0;

    /* 校验温度数据和湿度数据是否接收正确 */
    if(SHT3X_CheckCrc8(dat, 0xFF) != dat[2] || SHT3X_CheckCrc8(&dat[3], 0xFF) != dat[5])
        return 1;

    /* 转换温度数据 */
    recv_temperature = ((uint16_t)dat[0]<<8)|dat[1];
    *temperature = -45 + 175*((float)recv_temperature/65535);

    /* 转换湿度数据 */
    recv_humidity = ((uint16_t)dat[3]<<8)|dat[4];
    *humidity = 100 * ((float)recv_humidity / 65535);

    return 0;
}
  • i2c_sht3x.h
#ifndef __I2C_SHT3X_H__
#define __I2C_SHT3X_H__


#include "driver/i2c.h"
#include "esp_log.h"

#define SHT3X_TICKS_TO_WAIT           (100 / portTICK_RATE_MS)    // I2C读写的超时等待时间

#define SHT3X_I2C_BUS                 I2C_NUM_0 // SHT30所在的I2C总线

#define SHT3X_SLAVE_ADDRESS           0x44    // SHT30在I2C总线上的从机器件地址

// SHT30命令列表
typedef enum
{
    /* 软件复位命令 */

    SOFT_RESET_CMD = 0x30A2,    
    /*
    单次测量模式
    命名格式:Repeatability_CS_CMD
    CS:Clock stretching
    */
    HIGH_ENABLED_CMD    = 0x2C06,
    MEDIUM_ENABLED_CMD  = 0x2C0D,
    LOW_ENABLED_CMD     = 0x2C10,
    HIGH_DISABLED_CMD   = 0x2400,
    MEDIUM_DISABLED_CMD = 0x240B,
    LOW_DISABLED_CMD    = 0x2416,

    /*
    周期测量模式
    命名格式:Repeatability_MPS_CMD
    MPS:measurement per second
    */
    HIGH_0_5_CMD   = 0x2032,
    MEDIUM_0_5_CMD = 0x2024,
    LOW_0_5_CMD    = 0x202F,
    HIGH_1_CMD     = 0x2130,
    MEDIUM_1_CMD   = 0x2126,
    LOW_1_CMD      = 0x212D,
    HIGH_2_CMD     = 0x2236,
    MEDIUM_2_CMD   = 0x2220,
    LOW_2_CMD      = 0x222B,
    HIGH_4_CMD     = 0x2334,
    MEDIUM_4_CMD   = 0x2322,
    LOW_4_CMD      = 0x2329,
    HIGH_10_CMD    = 0x2737,
    MEDIUM_10_CMD  = 0x2721,
    LOW_10_CMD     = 0x272A,
    /* 周期测量模式读取数据命令 */
    READOUT_FOR_PERIODIC_MODE = 0xE000,
} SHT30_CMD;


/**
 * @brief    复位SHT3X
 * 
 * @param    none
 * 
 * @retval    none
*/
void sht3x_reset(void);

/**
 * @brief    初始化SHT3X
 * 
 * @param    none
 * 
 * @retval    成功返回HAL_OK(ESP_OK)
 * 
 * @note    周期测量模式
*/
uint8_t sht3x_init(void);

/**
 * @brief    从SHT3X读取一次数据
 * 
 * @param    dat —— 存储读取数据的地址(6个字节数组)
 * 
 * @retval    成功 —— 返回HAL_OK(ESP_OK)
*/
uint8_t sht3x_read_dat(uint8_t* dat);

/**
 * @brief    将SHT3X接收的6个字节数据进行CRC校验,并转换为温度值和湿度值
 * 
 * @param    dat  —— 存储接收数据的地址(6个字节数组)
 * 
 * @retval    校验成功  —— 返回0
 *            校验失败  —— 返回1,并设置温度值和湿度值为0
*/
uint8_t sht3x_dat2float(uint8_t* const dat, float* temperature, float* humidity);


#endif
  • CMakeLists.txt
set(sht3x_srcs "src/i2c_sht3x.c")

idf_component_register(SRCS "${sht3x_srcs}"
                       INCLUDE_DIRS "include")

ESP32-硬件IIC读取温湿度传感器SHT30

  • component.mk
#
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS := include

COMPONENT_SRCDIRS := src

ESP32-硬件IIC读取温湿度传感器SHT30

  1. 删除不需要的代码后,我们根据实际使用的 I2C 引脚,对 I2C 进行配置,并且编写读取 sht30 传感器的函数
/* 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 MPU9250 inertial measurement unit.

   For other examples please check:
   https://github.com/espressif/esp-idf/tree/master/examples

   See README.md file to get detailed usage of this example.

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "esp_log.h"
#include "driver/i2c.h"
#include "i2c_sht3x.h" 

static const char *TAG = "i2c-sht3x";//"i2c-simple-example";

#define I2C_MASTER_SCL_IO           GPIO_NUM_14//CONFIG_I2C_MASTER_SCL      /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO           GPIO_NUM_4//CONFIG_I2C_MASTER_SDA      /*!< GPIO number used for I2C master data  */
#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          400000                     /*!< 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       1000

/**
 * @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);
}

// i2c_sht3x_task 任务。初始化 SHT3x工作于周期测量模式,获取环境温湿度数据
void i2c_sht3x_task(void* arg)
{
    // 配置I2C0-主机模式,400K,指定 SCL-14,SDA-4
    i2c_master_init();

    uint8_t recv_dat[6] = {0};
    float temperature = 0.0;
    float humidity = 0.0;

    ESP_LOGI(TAG, "esp32 sht3x project starting ……");
    
    sht3x_reset(); // 复位SHT3X
    if(sht3x_init() == ESP_OK) // 初始化SHT3X(周期测量模式)
        ESP_LOGI(TAG, "sht3x init ok.\n");
    else
        ESP_LOGE(TAG, "sht3x init fail.\n");
    vTaskDelay(1000 / portTICK_PERIOD_MS); //延时1s 等待SHT3X传感器内部采样完成

    for (;;)
    {
        if(sht3x_read_th_raw_dat(recv_dat) == ESP_OK) // 从SHT3X读取一次数据(周期测量模式下)
        {
            // 将SHT3X接收的6个字节数据进行CRC校验,并转换为温度值和湿度值
            if(sht3x_dat2float(recv_dat, &temperature, &humidity) == 0)
            {
                ESP_LOGI(TAG, "temperature = %.2f ℃,humidity = %.2f %%RH", temperature, humidity);
            }
            else
            {
                ESP_LOGE(TAG, "crc check fail.\n");
            }
        }
        else
        {
            ESP_LOGE(TAG, "read data from sht3x fail.\n");
        }

        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    // 创建 i2c_sht3x_task 任务。初始化 SHT30工作于周期测量模式,获取环境温湿度数据
    xTaskCreate(i2c_sht3x_task, "i2c_sht3x_task", 2048, NULL, 3, NULL);
}

  1. 点击 VSCODE IDF 插件的 编译,下载,数据监测,即可在终端处查看 SHT30 传感器测量到的温湿度的值
    ESP32-硬件IIC读取温湿度传感器SHT30

工程下载

可以点击此处下载工程,工程是不需要积分的,随意下载,如果觉得文章对您有帮助,请关注分享!
PS:该工程需要电脑已经安装了 ESP-IDF 才能编译通过文章来源地址https://www.toymoban.com/news/detail-431669.html

到了这里,关于ESP32-硬件IIC读取温湿度传感器SHT30的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ESP32单片机使用DHT11温湿度传感器的实践与代码解析

    摘要:本文将介绍如何使用ESP32单片机与温湿度传感器进行连接和数据读取。通过实例代码的解析,帮助读者了解实现温湿度检测的原理和方法。 一、引言 ESP32是一款功能强大的微控制器,广泛应用于物联网、智能家居等领域。在许多应用场景中,温湿度传感器是不可或缺的

    2024年02月21日
    浏览(18)
  • STM32 F103C8T6学习笔记13:IIC通信—AHT10温湿度传感器模块

    今日学习一下这款AHT10 温湿度传感器模块,给我的OLED手环添加上测温湿度的功能。 文章提供源码、测试工程下载、测试效果图。 目录 AHT10温湿度传感器: 特性: 连接方式: 适用场所范围: 程序设计: 设计目标:  程序设计注意点: AHT10代码:  主函数代码: 测试效果:

    2024年02月11日
    浏览(19)
  • arm学习-IIC总线连接温湿度传感器测量温湿度(si7006)

    main.c iic.h si7006.h iic.c si7006.c

    2024年02月13日
    浏览(20)
  • ARM_iic总线_采集温湿度传感器

    include/si7006.h include/iic.h src/si7006.c src/iic.c main.c

    2024年02月13日
    浏览(16)
  • FPGA读取SHT31温湿度传感器

    SHT30 是瑞士盛世瑞恩生产出品的一个温湿度传感器,该SHT3X是一个系列,一共有SHT30/SHT31/SHT35这三个品类, SHT30——低成本版本,±3% RH精度;SHT31——标准版本,±2% RH精度;RH精度SHT35——高端版本,±1.5% RH; 一般生活内监测用SHT30即可。 SHT30性能参数如下: 温度检测范围:5-60℃

    2024年02月22日
    浏览(17)
  • FPGA读取DHT11数字温湿度传感器

    最近在做一个DHT11相关的东西,写了一个DHT11控制模块。参考了正点原子和野火电子的文档资料后总觉得又乱又杂,所以自己跟着数据手册写了一遍,当然了也很感谢正点原子和野火文档的帮助。 DHT11是一种数字温湿度传感器,有4个引脚但只有三个有效引脚,分别是VDD,DATA和

    2024年02月05日
    浏览(20)
  • STM32实战项目-温湿度传感器

    程序功能: 1、软件模拟I2C协议与SHT30数字温湿度传感器通讯; 2、数码管显示环境温湿度; 3、串口打印环境温湿度。 目录 一、硬件电路 二、技术讲解  2.1IIC简介 2.2 IIC总线协议 2.2设备接入  三、SHT30数字温湿度传感器  3.1性能介绍 3.1.1湿度最优测量环境 3.1.2温度最优测量环

    2023年04月23日
    浏览(20)
  • STM32+DHT11温湿度传感器

    DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次 通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数 部分用于以后扩展,现读出为零.操作流程如下: 一次完整的数据传输为40bit,高位先出。 数据格式:8bit湿度整数数据+8bit湿度小数数据

    2023年04月13日
    浏览(15)
  • STM32--DHT11温湿度传感器

    本文介绍基于STM32F103实现的DHT11温湿度传感器数据采集及显示,完整代码见文末链接 一、DHT11传感器简介 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期

    2024年02月16日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包