HarmonyOS小熊派 | HarmonyOS传感器驱动开发--E53_IA1读取温度 、湿度、光照强度
BearPi-HM_Nano开发板传感器驱动开发——E53_IA1读取温度 、湿度、光照强度
本示例将演示如何在BearPi-HM_Nano开发板上使用E53_IA1读取温度 、湿度、光照强度,当温度 、湿度超标时开启电机通风,当光照强度过低时,开启补光灯补光。
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
关灯
关电机
- 点赞
- 收藏
- 关注作者
评论(0)