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

简介: 今天主要和大家聊一聊,如何使用鸿蒙系统去提取AHT20的温湿度传感器的数值,该传感器采用ADC位数为20Bit,具有体积小,精度高和成本低的优点。
+关注继续查看

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

5e76a08ae368690c7c7d009d47760ccd.png第一:温湿度传感器基本参数

8d4f5b094c95c6ce2989be2f51110826.png

管脚定义与参考电路

4e237a979b7944211a0f8cf3a730e1a9.png

d50270b133bb06afe171f6c8ba803c68.png

I2C时序特性----支持标准100Hz,高速400KHz

4be00d6478f20d7738a1bdf6bbdfb46b.png

d5750c2363af71c34d3fa610b0fd3f5a.png

第二:温度代码具体实现


     上面分析了,温湿度传感器的基本实现原理与方法,主要精力可以放在代码的具体实现上。

#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 10
static 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(%02X) 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);
目录
相关文章
|
15天前
|
安全 前端开发 Android开发
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
鸿蒙开发学习是一项探索性的工作,旨在开发一个全场景分布式操作系统,覆盖所有设备,让消费者能够更方便、更直观地使用各种设备。
63 0
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
|
6月前
|
存储 传感器 监控
基于鸿蒙系统的智能衣柜管理系统设计与实现_kaic
随着城市的扩大与科学技术的发展,人们逐渐开始关注衣柜功能的改进,存储效果的优化和智能使用的升级。个性化、功能化、智能化的衣柜将出现在人们的家庭生活中,并且起到重要作用。 为了满足当前人们对智能衣柜的需求,本设计将采用华为公司面向物联网时代的操作系统-鸿蒙操作系统进行智能衣柜管理系统的设计与实现,衣柜的管理系统需要采集衣柜的环境参数,因此采用Hi3861V100芯片作为主控芯片采集数据并处理后做出控制,该系统将鸿蒙操作系统作为下位硬件及上位终端共同的底层操作系统,产品的软硬件两部分都处在共同的鸿蒙系统生态中,通过WIFI进行软硬件通信以达到控制终端与衣柜互联互通的目的。
|
12月前
|
Ubuntu Linux 测试技术
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程(下)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程
264 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程(下)
|
12月前
|
Linux 芯片
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程(中)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程
133 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程(中)
|
12月前
|
Ubuntu Linux API
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程(上)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程
187 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十五)输入系统应用编程(上)
|
12月前
|
XML Ubuntu 前端开发
嵌入式linux/鸿蒙开发板(IMX6ULL)开发流程(六)烧写整个系统或更新部分系统
嵌入式linux/鸿蒙开发板(IMX6ULL)开发流程(六)烧写整个系统或更新部分系统
562 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发流程(六)烧写整个系统或更新部分系统
|
12月前
|
Ubuntu 网络安全 数据安全/隐私保护
鸿蒙系统环境搭建、源码编译与烧写之经典
大家好,今天学习一下,如何部署鸿蒙环境,并在ubuntu系统下编译,以及烧写镜像的方法。 目录
206 0
鸿蒙系统环境搭建、源码编译与烧写之经典
|
12月前
|
人工智能 IDE Java
01----嵌入式AI鸿蒙系统智能相机操作之优秀
01----嵌入式AI鸿蒙系统智能相机操作之优秀
227 1
01----嵌入式AI鸿蒙系统智能相机操作之优秀
|
12月前
|
JavaScript Ubuntu Java
鸿蒙系统分享----软件驱动使用JS控制LED灯实验方法
鸿蒙系统分享----软件驱动使用JS控制LED灯实验方法
153 1
鸿蒙系统分享----软件驱动使用JS控制LED灯实验方法
|
12月前
|
Linux 开发者
鸿蒙系统分享----鸿蒙系统硬件驱动开发
鸿蒙系统分享----鸿蒙系统硬件驱动开发
189 0
鸿蒙系统分享----鸿蒙系统硬件驱动开发
推荐文章
更多