HarmonyOS小熊派 | HarmonyOS传感器驱动开发--E53_IA1读取温度 、湿度、光照强度

举报
Yuchuan 发表于 2021/07/14 17:25:17 2021/07/14
【摘要】 传感器驱动开发--E53_IA1读取温度 、湿度、光照强度

BearPi-HM_Nano开发板传感器驱动开发——E53_IA1读取温度 、湿度、光照强度

本示例将演示如何在BearPi-HM_Nano开发板上使用E53_IA1读取温度 、湿度、光照强度,当温度 、湿度超标时开启电机通风,当光照强度过低时,开启补光灯补光。

BearPi-HM_Nano

E53_IA1 API分析

本案例主要使用了以下API完成温度 、湿度、光照强度读取

1、InitE53IA1()

// 初始化E53_IA1 接口
void InitE53IA1(void);

描述:

初始化E53_IA1

2、ReadDataE53IA1()

// 从E53_IA1 接口读取测量到的温度、湿度及光照强度的数据
void ReadDataE53IA1(void);

描述: 读取温度 、湿度、光照强度

3、LightStatusSet()

// 设置灯的状态
void LightStatusSet(E53_IA1_Status_ENUM status);

描述:

控制补光灯开关 参数:

名字 描述
status ON开,OFF关闭.

4、MotorStatusSet()

// 设置电机的状态
void MotorStatusSet(E53_IA1_Status_ENUM status);

描述:

控制电机开关

参数:

名字 描述
status ON开,OFF关闭.

硬件设计

本案例将用到 E53_IA1 智慧农业扩展板与 BearPi-HM_Nano 开发板,其中E53_IA1扩展板接口原理图如下,温湿度传感器sht30和光照强度传感器BH1750都是通过I2C来驱动,电机和补光灯分别通过GPIO_8和GPIO_7来控制。

E53_IA1 智慧农业扩展板与 BearPi-HM_Nano 开发板安装

软件设计

主要代码分析

首先调用 InitE53IA1()  函数初始化E53_IA1所接的引脚的功能,然后循环调用 ReadDataE53IA1() 函数读取温度 、湿度、光照强度并通过串口打印出来,当光照强度过低时,开启补光灯补光,当温度 、湿度超标时开启电机通风。

yuchuan_e53_ia1.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "e53_ia1.h"

#define E53_TASK_CB_SIZE 0U
#define E53_TASK_STACK_SIZE 1024 * 4
#define E53_TASK_PRIORITY 24

E53_IA1_Data_TypeDef E53_IA1_Data;

/* 处理E53_IA1接口的函数 */
void yuchuanE53IA1Task(void *argument)
{
    (void)argument;
    //初始化E53_IA1接口
    InitE53IA1();

    while (1)
    {
        /* code */
        printf("\r\n====================================================\r\n");
        printf("\r\n*************Yuchuan E53_IA1_Task_Example***********\r\n");
        printf("\r\n====================================================\r\n");

        // 从E53_IA1接口读取数据
        ReadDataE53IA1();

        printf("\r\n******************************Lux Value is  %.2f\r\n", E53_IA1_Data.Lux);
        printf("\r\n******************************Humidity is  %.2f\r\n", E53_IA1_Data.Humidity);
        printf("\r\n******************************Temperature is  %.2f\r\n", E53_IA1_Data.Temperature);

        if ((int)E53_IA1_Data.Lux < 20)
        {
            // 开灯
            LightStatusSet(ON);
            printf("开灯\n");
        }
        else
        {
            // 关灯
            LightStatusSet(OFF);
            printf("关灯\n");
        }

        if (((int)E53_IA1_Data.Humidity > 70) | ((int)E53_IA1_Data.Temperature > 35))
        {
            // 开电机
            MotorStatusSet(ON);
            printf("开电机\n");
        }
        else
        {
            // 关电机
            MotorStatusSet(OFF);
            printf("关电机\n");
        }
        usleep(2000000);
    }
}

static void YuchuanE53IA1Entry(void)
{
    osThreadAttr_t e53TaskAttr;
    e53TaskAttr.attr_bits = 0U;
    e53TaskAttr.cb_mem = NULL;
    e53TaskAttr.cb_size = E53_TASK_CB_SIZE;
    e53TaskAttr.stack_mem = NULL;
    e53TaskAttr.stack_size = E53_TASK_STACK_SIZE;
    e53TaskAttr.priority = E53_TASK_PRIORITY;

    e53TaskAttr.name = "YuchuanE53IA1Task";
    if (osThreadNew((osThreadFunc_t)yuchuanE53IA1Task, NULL, &e53TaskAttr) == NULL)
    {
        /* code */
        printf("Falied to Create YuchuanE53IA1Task!!!\n");
    }
}

APP_FEATURE_INIT(YuchuanE53IA1Entry);

e53_ia1.h

/*
 * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __E53_IA1_H__
#define __E53_IA1_H__

/* 寄存器宏定义 --------------------------------------------------------------------*/
#define BH1750_ADDR 0x23
#define SHT30_ADDR 0x44

/***************************************************************
* 名		称: GasStatus_ENUM
* 说    明:枚举状态结构体
***************************************************************/
typedef enum
{
    OFF = 0,
    ON
} E53_IA1_Status_ENUM;

/* E53_IA1传感器数据类型定义 ------------------------------------------------------------*/
typedef struct
{
    // 光照强度
    float Lux;
    // 湿度
    float Humidity;
    // 温度
    float Temperature;
} E53_IA1_Data_TypeDef;

//存储共享数据
extern E53_IA1_Data_TypeDef E53_IA1_Data;

/* E53_IA1 API */
// 初始化E53_IA1 接口
void InitE53IA1(void);
// 从E53_IA1 接口读取测量到的温度、湿度及光照强度的数据
void ReadDataE53IA1(void);
// 设置灯的状态
void LightStatusSet(E53_IA1_Status_ENUM status);
// 设置电机的状态
void MotorStatusSet(E53_IA1_Status_ENUM status);

#endif /* __E53_IA1_H__ */

e53_ia1.c

/*
 * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <math.h>

#include "cmsis_os2.h"
#include "e53_ia1.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_errno.h"
#include "iot_i2c.h"
#include "iot_i2c_ex.h"

#define MOTOR_GPIO_8 8
#define FILL_LIGHT_GPIO_7 7
#define IOT_I2C1_SDA_GPIO_0 0
#define IOT_I2C1_SCL_GPIO_1 1
#define IOT_I2C_IDX_1 1
/***************************************************************
* 函数名称: IoInitE53IA1
* 说    明: E53_IA1_GPIO初始化
* 参    数: 无
* 返 回 值: 无
***************************************************************/
static void IoInitE53IA1(void)
{
    IoTGpioInit(MOTOR_GPIO_8);
    IoTGpioSetDir(MOTOR_GPIO_8, IOT_GPIO_DIR_OUT);
    IoTGpioSetFunc(MOTOR_GPIO_8, IOT_GPIO_FUNC_GPIO_8_GPIO);

    IoTGpioInit(FILL_LIGHT_GPIO_7);
    IoTGpioSetDir(FILL_LIGHT_GPIO_7, IOT_GPIO_DIR_OUT);
    IoTGpioSetFunc(FILL_LIGHT_GPIO_7, IOT_GPIO_FUNC_GPIO_7_GPIO);

    IoTGpioInit(IOT_I2C1_SDA_GPIO_0);
    IoTGpioSetDir(IOT_I2C1_SDA_GPIO_0, IOT_GPIO_DIR_OUT);
    IoTGpioSetFunc(IOT_I2C1_SDA_GPIO_0, IOT_GPIO_FUNC_GPIO_0_I2C1_SDA);

    IoTGpioInit(IOT_I2C1_SCL_GPIO_1);
    IoTGpioSetDir(IOT_I2C1_SCL_GPIO_1, IOT_GPIO_DIR_OUT);
    IoTGpioSetFunc(IOT_I2C1_SCL_GPIO_1, IOT_GPIO_FUNC_GPIO_1_I2C1_SCL);

    /* baudrate: 400kbps */
    IoTI2cInit(IOT_I2C_IDX_1, 400000);
}

/***************************************************************
* 函数名称: InitBH1750
* 说    明: 写命令初始化BH1750光照强度传感器
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void InitBH1750(void)
{
    uint8_t send_data[1] = {0x01};
    // unsigned int IoTI2cWrite(unsigned int id, unsigned short deviceAddr, const unsigned char *data, unsigned int dataLen);
    IoTI2cWrite(IOT_I2C_IDX_1, (BH1750_ADDR << 1) | 0x00, send_data, 1);
    /* uint8_t send_data[1] = {0x01};
    IoTI2cWrite(IOT_I2C_IDX_1, (BH1750_Addr << 1) | 0x00, send_data, 1); */
}

/***************************************************************
* 函数名称: InitSHT30
* 说    明: 初始化SHT30温湿度传感器,设置测量周期 
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void InitSHT30(void)
{
    uint8_t send_data[2] = {0x22, 0x36};
    IoTI2cWrite(IOT_I2C_IDX_1, (SHT30_ADDR << 1) | 0x00, send_data, 2);
}

/***************************************************************
* 函数名称: InitE53IA1
* 说    明: 初始化E53_IA1
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void InitE53IA1(void)
{
    // 初始化E53相关GPIO
    IoInitE53IA1();
    // 初始化BH1750 光照传感器
    InitBH1750();
    // 初始化SHT30 温湿度传感器
    InitSHT30();
}

/***************************************************************
* 函数名称: StartBH1750
* 说    明: 启动BH1750 采集光照强度的数据
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void StartBH1750(void)
{
    uint8_t send_data[1] = {0x10};
    // unsigned int IoTI2cWrite(unsigned int id, unsigned short deviceAddr, const unsigned char *data, unsigned int dataLen);
    IoTI2cWrite(IOT_I2C_IDX_1, (BH1750_ADDR << 1) | 0x00, send_data, 1);
}

/***************************************************************
* 函数名称: CheckCrcSHT3x
* 说    明: 检查数据正确性
* 参    数: data:读取到的数据
						nbrOfBytes:需要校验的数量
						checksum:读取到的校对比验值
* 返 回 值: 校验结果,0-成功		1-失败
***************************************************************/
static uint8_t CheckCrcSHT3x(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
{
    uint8_t crc = 0xFF;
    uint8_t bit = 0;
    uint8_t byteCtr;

    const uint16_t POLYNOMIAL = 0x131;
    //calculates 8-Bit checksum with given polynomial
    for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
    {
        /* code */
        crc ^= (data[byteCtr]);
        for (bit = 8; bit > 0; --bit)
        {
            /* code */
            if (crc & 0x80)
            {
                /* code */
                crc = (crc << 1) ^ POLYNOMIAL;
            }
            else
            {
                crc = (crc << 1);
            }
        }
    }
    if (crc != checksum)
    {
        /* code */
        return 1;
    }
    else
    {
        /* code */
        return 0;
    }
}

/***************************************************************
* 函数名称: CalcTemperatureCSHT3x
* 说    明: 温度计算
* 参    数: u16sT:读取到的温度原始数据
* 返 回 值: 计算后的温度数据
***************************************************************/
static float CalcTemperatureCSHT3x(uint16_t u16sT)
{
    // variable for result
    float temperatureC = 0;
    // clear bits [1..0] (status bits)
    u16sT &= ~0x0003;
    //-- calculate temperature [℃] --
    //T = -45 + 175 * rawValue / (2^16-1)
    temperatureC = (175 * (float)u16sT / 65535 - 45);
    return temperatureC;
}

/***************************************************************
* 函数名称: CalcRHSHT3x
* 说    明: 湿度计算
* 参    数: u16sRH:读取到的湿度原始数据
* 返 回 值: 计算后的湿度数据
***************************************************************/
static float CalcRHSHT3x(uint16_t u16sRH)
{
    // variable for result
    float humidityRH = 0;
    // clear bits [1..0] (status bits)
    u16sRH &= ~0x0003;
    //-- calculate relative humidity [%RH] --
    // RH = rawValue / (2^16-1) * 10
    humidityRH = (100 * (float)u16sRH / 65535);
    return humidityRH;
}

/***************************************************************
* 函数名称: ReadDataE53IA1
* 说    明: 测量光照强度、温度、湿度
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void ReadDataE53IA1(void)
{
    uint8_t recv_data[2] = {0};
    // 启动光照传感器采集光照强度的数据
    StartBH1750();
    //延时1s
    usleep(1000000);
    // 读取光照强度传感器的数据
    // unsigned int IoTI2cRead(unsigned int id, unsigned short deviceAddr, unsigned char *data, unsigned int dataLen);
    IoTI2cRead(IOT_I2C_IDX_1, (BH1750_ADDR << 1) | 0x01, recv_data, 2);

    // 光照强度
    E53_IA1_Data.Lux = (float)(((recv_data[0] << 8) + recv_data[1]) / 1.2);
    //data array for checksum verification
    uint8_t data[3];
    uint16_t dat, temp;
    //byte 0,1 is temperature byte 4,5 is humidity
    uint8_t SHT3X_Data_Buffer[6];
    IotI2cData sht30_i2c_data = {0};
    uint8_t send_data[2] = {0xE0, 0x00};

    sht30_i2c_data.sendBuf = send_data;
    sht30_i2c_data.sendLen = 2;
    sht30_i2c_data.receiveBuf = SHT3X_Data_Buffer;
    sht30_i2c_data.receiveLen = 6;

    //Read bh1750 sensor data
    // unsigned int IoTI2cWriteread(unsigned int  id, unsigned short deviceAddr, const IotI2cData *i2cData);
    IoTI2cWriteread(IOT_I2C_IDX_1, (SHT30_ADDR << 1) | 0x00, &sht30_i2c_data);

    //    /* check tem */
    data[0] = SHT3X_Data_Buffer[0];
    data[1] = SHT3X_Data_Buffer[1];
    data[2] = SHT3X_Data_Buffer[2];

    temp = CheckCrcSHT3x(data, 2, data[2]);
    if (!temp)
    {
        /* code */
        dat = ((uint16_t)data[0] << 8) | data[1];
        // 温度
        E53_IA1_Data.Temperature = CalcTemperatureCSHT3x(dat);
    }

    //    /* check humidity 检查湿度*/
    data[0] = SHT3X_Data_Buffer[3];
    data[1] = SHT3X_Data_Buffer[4];
    data[2] = SHT3X_Data_Buffer[5];

    temp = CheckCrcSHT3x(data, 2, data[2]);
    /* value is ture */
    if (!temp)
    {
        /* code */
        dat = ((uint16_t)data[0] << 8) | data[1];
        E53_IA1_Data.Humidity = CalcRHSHT3x(dat);
    }
}

/***************************************************************
* 函数名称: LightStatusSet
* 说    明: 灯状态设置
* 参    数: status,ENUM枚举的数据
*									OFF,关
*									ON,开
* 返 回 值: 无
***************************************************************/
void LightStatusSet(E53_IA1_Status_ENUM status)
{
    if (status == ON)
    {
        // 设置GPIO_14 为高电平点亮灯
        IoTGpioSetOutputVal(FILL_LIGHT_GPIO_7, IOT_GPIO_VALUE1);
    }
    if (status == OFF)
    {
        // 设置GPIO_14 为低电平熄灭灯
        IoTGpioSetOutputVal(FILL_LIGHT_GPIO_7, IOT_GPIO_VALUE0);
    }
}

/***************************************************************
* 函数名称: MotorStatusSet
* 说    明: 电机状态设置
* 参    数: status,ENUM枚举的数据
*									OFF,关
*									ON,开
* 返 回 值: 无
***************************************************************/
void MotorStatusSet(E53_IA1_Status_ENUM status)
{
    if (status == ON)
    {
        // 设置GPIO_8 为高电平输出打开电机
        IoTGpioSetOutputVal(MOTOR_GPIO_8, IOT_GPIO_VALUE1);
    }
    if (status == OFF)
    {
        // 设置GPIO_8 为低电平输出关闭电机
        IoTGpioSetOutputVal(MOTOR_GPIO_8, IOT_GPIO_VALUE0);
    }
}

编译调试

//applications/sample/BearPi/BearPi-HM_Nano/sample/C2_YuchuanE53IA1

static_library("yuchuanE53IA1"){
    sources = [
        "scr/e53_ia1.c",
        "yuchuan_e53_ia1.c",
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/kal/cmsis",
        "//base/iot_hardware/peripheral/interfaces/kits",
        "include",
    ]
}

修改 BUILD.gn 文件

修改applications\BearPi\BearPi-HM_Nano\sample路径下 BUILD.gn 文件,指定 yuchuanE53IA1 参与编译。

# Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import("//build/lite/config/component/lite_component.gni")

lite_component("sample") {
    features = [
        #"A1_kernal_thread:thread_example",
        #"A2_kernel_timer:timer_example",
        #"A3_kernel_event:event_example",
        #"A4_kernel_mutex:mutex_example",
        #"A5_kernel_semaphore:semaphore_example",
        #"A6_kernel_message:message_example",

        #"B1_basic_led_blink:led_example",
        #"B2_basic_button:button_example",
        #"B3_basic_pwm_led:pwm_example",
        #"B4_basic_adc:adc_example", 
        #"B5_basic_i2c_nfc:i2c_example",
        #"B6_basic_uart:uart_example",
        
        #"C1_e53_sf1_mq2:e53_sf1_example",
        #"C2_e53_ia1_temp_humi_pls:e53_ia1_example",
        #"C3_e53_sc1_pls:e53_sc1_example",
        #"C4_e53_sc2_axis:e53_sc2_example",
        #"C5_e53_is1_infrared:e53_is1_example",

        #"D1_iot_wifi_ap:wifi_ap",
        #"D2_iot_wifi_sta_connect:wifi_sta_connect",        
        #"D3_iot_udp_client:udp_client",
        #"D4_iot_tcp_server:tcp_server",
        #"D5_iot_mqtt:iot_mqtt",        
        #"D6_iot_cloud_oc:oc_mqtt",
        #"D7_iot_cloud_onenet:onenet_mqtt",
        #"D8_iot_cloud_oc_smoke:cloud_oc_smoke",
        #"D9_iot_cloud_oc_light:cloud_oc_light",
        #"D10_iot_cloud_oc_manhole_cover:cloud_oc_manhole_cover",
        #"D11_iot_cloud_oc_infrared:cloud_oc_infrared",
        #"D12_iot_cloud_oc_agriculture:cloud_oc_agriculture",
        #"D13_iot_cloud_oc_gps:cloud_oc_gps",
        #"B1_YuchuanBasicLEDBlink:yuchuanLED",
        #"B2_YuchuanBasicButton:yuchuanButton",
        #"C1_YuchuanE53_SF1_MQ2:YuchuanE53SF1Mq2",
        "C2_YuchuanE53IA1:yuchuanE53IA1",
    ]
}

运行结果

示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,会打印温湿度及光照强度信息。用手遮住扩展板,补光灯会自动开启,控制温度或者湿度超标,电机会自动开启。

ready to OS start
sdk ver:Hi3861V100R001C00SPC025 2020-09-03 18:10:00
FileSystem mount ok.
wifi init success!

hiview init success.00 00:00:00 0 196 D 0/HIVIEW: log limit init success.
00 00:00:00 0 196 I 1/SAMGR: Bootstrap core services(count:3).
00 00:00:00 0 196 I 1/SAMGR: Init servi
====================================================

*************Yuchuan E53_IA1_Task_Example***********

====================================================
ce:0x4b0ea8 TaskPool:0xe4b7c
00 00:00:00 0 196 I 1/SAMGR: Init service:0x4b0eb4 TaskPool:0xe4b9c
00 00:00:00 0 196 I 1/SAMGR: Init service:0x4b1380 TaskPool:0xe4bbc
00 00:00:00 0 228 I 1/SAMGR: Init service 0x4b0eb4 <time: 0ms> success!
00 00:00:00 0 128 I 1/SAMGR: Init service 0x4b0ea8 <time: 0ms> success!
00 00:00:00 0 72 I 1/SAMGR: Init service 0x4b1380 <time: 10ms> success!
00 00:00:00 0 72 I 1/SAMGR: Initialized all core system services!
00 00:00:00 0 128 I 1/SAMGR: Bootstrap system and application services(count:0).
00 00:00:00 0 128 I 1/SAMGR: Initialized all system and application services!
00 00:00:00 0 128 I 1/SAMGR: Bootstrap dynamic registered services(count:0).

******************************Lux Value is  330.83

******************************Humidity is  0.00

******************************Temperature is  0.00
关灯
关电机

====================================================

*************Yuchuan E53_IA1_Task_Example***********

====================================================

******************************Lux Value is  329.17

******************************Humidity is  0.00

******************************Temperature is  0.00
关灯
关电机
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。