资讯详情

利用鸿蒙系统实现温湿度传感器的数据读取与显示

今天主要和大家谈谈如何使用鸿蒙系统提取AHT使用20个温湿度传感器的值ADC位数为20Bit,它具有体积小、精度高、成本低的优点。

I2C支持标准1000Hz,高速400KHz

根据以上分析,温湿度传感器的基本实现原理和方法可以集中在代码的具体实现上。

#include "aht20.h"#include <stdio.h>#include <string.h>#include <unistd.h>#include "wifiiot_i2c.h"#include "wifiiot_errno.h"#define AHT20_I2C_IDX WIFI_IOT_I2C_IDX_0#define AHT20_STARTUP_TIME     20*1000 // 上电启动时间#define AHT20_CALIBRATION_TIME 40*1000 // 初始化(校准)时间#define AHT20_MEASURE_TIME     75*1000 // 测量时间#define AHT20_DEVICE_ADDR   0x38#define AHT20_READ_ADDR     ((0x38<<1)|0x1)#define AHT20_WRITE_ADDR    ((0x38<<1)|0x0)#define AHT20_CMD_CALIBRATION       0xBE // 初始化(校准)命令#define AHT20_CMD_CALIBRATION_ARG0  0x08#define AHT20_CMD_CALIBRATION_ARG1  0x00/** * 主机发出测量指令(0xAC)延迟超过75毫秒后,读取转换后的数据,判断返回状态是否正常。 * 若状态比特[Bit7]0代表数据可以正常读取,1时传感器处于忙碌状态,主机需要等待数据处理。 **/#define AHT20_CMD_TRIGGER       0xAC // 触发测量命令#define AHT20_CMD_TRIGGER_ARG0  0x33#define AHT20_CMD_TRIGGER_ARG1  0x00// 用于在无需关闭和再次打开电源的情况下,重新启动传感器系统,软复位所需时间不超过20 毫秒#define AHT20_CMD_RESET      0xBA // 软复位命令#define AHT20_CMD_STATUS     0x71 // 获取状态命令/** * STATUS 命令回复: * 1. 初始化后触发测量前,STATUS 只回复 1B 状态值; * 2. 触发测量后,STATUS 回复6B:1B 状态值   2B 湿度   4b湿度   4b温度   2B 温度 *      RH = Srh / 2^20 * 100% *      T  = St  / 2^20 * 200 - 50 **/#define AHT20_STATUS_BUSY_SHIFT 7       // bit[7] Busy indication#define AHT20_STATUS_BUSY_MASK  (0x1<<AHT20_STATUS_BUSY_SHIFT)#define AHT20_STATUS_BUSY(status) ((status & AHT20_STATUS_BUSY_MASK) >> AHT20_STATUS_BUSY_SHIFT)#define AHT20_STATUS_MODE_SHIFT 5       // bit[6:5] Mode Status#define AHT20_STATUS_MODE_MASK  (0x3<<AHT20_STATUS_MODE_SHIFT)#define AHT20_STATUS_MODE(status) ((status & AHT20_STATUS_MODE_MASK) >> AHT20_STATUS_MODE_SHIFT)                                        // bit[4] Reserved#define AHT20_STATUS_CALI_SHIFT 3       // bit[3] CAL Enable#define AHT20_STATUS_CALI_MASK  (0x1<<AHT20_STATUS_CALI_SHIFT)#define AHT20_STATUS_CALI(status) ((status & AHT20_STATUS_CALI_MASK) >> AHT20_STATUS_CALI_SHIFT)                                        // bit[2:0] Reserved#define AHT20_STATUS_RESPONSE_MAX 6#define AHT20_RESOLUTION            (1<<20)  // 2^20#define AHT20_MAX_RETRY 10static uint32_t AHT20_Read(uint8_t* buffer, uint32_t buffLen){     
          WifiIotI2cData data = { 0 };    data.receiveBuf = buffer;    data.receiveLen = buffLen;    uint32_t retval = I2cRead(AHT20_I2C_IDX, AHT20_READ_ADDR, &data);    if (retval != WIFI_IOT_SUCCESS) {     
              printf("I2cRead() failed, %0X!\n", retval);        return retval;    }    return WIFI_IOT_SUCCESS;}static uint32_t AHT20_Write(uint8_t* buffer, uint32_t buffLen){     
          WifiIotI2cData data = { 0 };    data.sendBuf = buffer;    data.sendLen = buffLen;    uint32_t retval = I2cWrite(AHT20_I2C_IDX, AHT20_WRITE_ADDR, &data);    if (retval != WIFI_IOT_SUCCESS) {     
              printf("I2cWrite(X) failed, %0X!\n", buffer[0], retval);        return retval;    }    return WIFI_IOT_SUCCESS;}// 发送获取状态命令static uint32_t AHT20_StatusCommand(void){     
          uint8_t statusCmd[] = { AHT20_CMD_STATUS };
     
          return AHT20_Write(statusCmd, sizeof(statusCmd));
      }
      
      // 发送软复位命令
      static uint32_t AHT20_ResetCommand(void)
      { 
       
       uint8_t resetCmd[] = {AHT20_CMD_RESET};
       return AHT20_Write(resetCmd, sizeof(resetCmd));
      }
      
      // 发送初始化校准命令
      static uint32_t AHT20_CalibrateCommand(void)
      { 
       
       uint8_t clibrateCmd[] = {AHT20_CMD_CALIBRATION, AHT20_CMD_CALIBRATION_ARG0, AHT20_CMD_CALIBRATION_ARG1};
       return AHT20_Write(clibrateCmd, sizeof(clibrateCmd));
      }
      
      // 读取温湿度值之前, 首先要看状态字的校准使能位Bit[3]是否为 1(通过发送0x71可以获取一个字节的状态字),
      // 如果不为1,要发送0xBE命令(初始化),此命令参数有两个字节, 第一个字节为0x08,第二个字节为0x00。
      uint32_t AHT20_Calibrate(void)
      { 
       
       uint32_t retval = 0;
       uint8_t buffer[AHT20_STATUS_RESPONSE_MAX];
       memset(&buffer, 0x0, sizeof(buffer));
      
       retval = AHT20_StatusCommand();
       if (retval != WIFI_IOT_SUCCESS) { 
       
       return retval;
       }
      
       retval = AHT20_Read(buffer, sizeof(buffer));
       if (retval != WIFI_IOT_SUCCESS) { 
       
       return retval;
       }
      
       if (AHT20_STATUS_BUSY(buffer[0]) || !AHT20_STATUS_CALI(buffer[0])) { 
       
       retval = AHT20_ResetCommand();
       if (retval != WIFI_IOT_SUCCESS) { 
       
       return retval;
       }
       usleep(AHT20_STARTUP_TIME);
       retval = AHT20_CalibrateCommand();
       usleep(AHT20_CALIBRATION_TIME);
       return retval;
       }
      
       return WIFI_IOT_SUCCESS;
      }
      
      // 发送 触发测量 命令,开始测量
      uint32_t AHT20_StartMeasure(void)
      { 
       
       uint8_t triggerCmd[] = {AHT20_CMD_TRIGGER, AHT20_CMD_TRIGGER_ARG0, AHT20_CMD_TRIGGER_ARG1};
       return AHT20_Write(triggerCmd, sizeof(triggerCmd));
      }
      
      // 接收测量结果,拼接转换为标准值
      uint32_t AHT20_GetMeasureResult(float* temp, float* humi)
      { 
       
       uint32_t retval = 0, i = 0;
       if (temp == NULL || humi == NULL) { 
       
       return WIFI_IOT_FAILURE;
       }
      
       uint8_t buffer[AHT20_STATUS_RESPONSE_MAX];
       memset(&buffer, 0x0, sizeof(buffer));
       retval = AHT20_Read(buffer, sizeof(buffer)); // recv status command result
       if (retval != WIFI_IOT_SUCCESS) { 
       
       return retval;
       }
      
       for (i = 0; AHT20_STATUS_BUSY(buffer[0]) && i < AHT20_MAX_RETRY; i++) { 
       
       // printf("AHT20 device busy, retry %d/%d!\r\n", i, AHT20_MAX_RETRY);
       usleep(AHT20_MEASURE_TIME);
       retval = AHT20_Read(buffer, sizeof(buffer)); // recv status command result
       if (retval != WIFI_IOT_SUCCESS) { 
       
       return retval;
       }
       }
       if (i >= AHT20_MAX_RETRY) { 
       
       printf("AHT20 device always busy!\r\n");
       return WIFI_IOT_FAILURE;
       }
      
       uint32_t humiRaw = buffer[1];
       humiRaw = (humiRaw << 8) | buffer[2];
       humiRaw = (humiRaw << 4) | ((buffer[3] & 0xF0) >> 4);
       *humi = humiRaw / (float)AHT20_RESOLUTION * 100;
      
       uint32_t tempRaw = buffer[3] & 0x0F;
       tempRaw = (tempRaw << 8) | buffer[4];
       tempRaw = (tempRaw << 8) | buffer[5];
       *temp = tempRaw / (float)AHT20_RESOLUTION * 200 - 50;
       // printf("humi = %05X, %f, temp= %05X, %f\r\n", humiRaw, *humi, tempRaw, *temp);
       return WIFI_IOT_SUCCESS;
      }
     

#include "aht20.h"#include <stdio.h>#include <unistd.h>#include "ohos_init.h"#include "cmsis_os2.h"#include "wifiiot_gpio.h"#include "wifiiot_gpio_ex.h"#include "wifiiot_i2c.h"void Aht20TestTask(void* arg){
    
          (void) arg;    uint32_t retval = 0;    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);    I2cInit(WIFI_IOT_I2C_IDX_0, 400*1000);    retval = AHT20_Calibrate();    printf("AHT20_Calibrate: %d\r\n", retval);    while (1) {
    
              float temp = 0.0, humi = 0.0;        retval = AHT20_StartMeasure();        printf("AHT20_StartMeasure: %d\r\n", retval);        retval = AHT20_GetMeasureResult(&temp, &humi);        printf("AHT20_GetMeasureResult: %d, temp = %.2f, humi = %.2f\r\n", retval, temp, humi);        sleep(1);    }}void Aht20Test(void){
    
          osThreadAttr_t attr;    attr.name = "Aht20Task";    attr.attr_bits = 0U;    attr.cb_mem = NULL;    attr.cb_size = 0U;    attr.stack_mem = NULL;    attr.stack_size = 4096;    attr.priority = osPriorityNormal;    if (osThreadNew(Aht20TestTask, NULL, &attr) == NULL) {
    
              printf("[Aht20Test] Failed to create Aht20TestTask!\n");    }}APP_FEATURE_INIT(Aht20Test);

     具体的操作实现如下视频所示。

【新提醒】【学习打卡】-----利用鸿蒙系统实现对温湿度传感器数据操作 - OpenHarmony论坛 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com)https://bbs.elecfans.com/jishu_2291729_1_1.html

标签: 室内温度传感器t7412a0402cb010传感器cb传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台