此次基于OpenHarmony的智能阳台项目的开发是在参加首届OpenHarmony开源开发者成长计划的活动中进行的一个学习和探索的过程。
万事开头难,要完成一个项目,首先第的一件事就是环境的搭建,搭建好环境对后面开发板的学习及OpenHarmony的开发都有一个事半功倍的作用,从安装虚拟机,下载源码,代码编写以及编译调试等步骤,若其中一步出现错误则可能在往后的开发过程中会出现不能预知的错误,所以这是一个最为艰难但也是最为重要的过程。对于刚接触的小白来说是一件比较困难的事情,从0开始学OpenHarmony开发板。
当环境配置成功之后我们便可尝试编译及烧写,当烧写成功后我们就可以着手准备开发我们的项目啦,我本次开发的项目是基于OpenHarmony的智能阳台,以下是我开发的全过程及一些问题的解决方法。
基于OpenHarmony的智能阳台具体功能如下:
基于OpenHarmony的智能阳台系统架构图如下:
根据系统架构图,可以看出基于OpenHarmony的智能阳台是主要是由三部分组成:
数据采集:由雨滴传感器采集室外的情况并发送给开发板;
信号传送:开发板接收到传感器的数据进行判断,并且发送判断后的信号给电机驱动模块以及将数据上传到华为IoT平台;
执行部件:电机控制模块根据单片机的信号控制电机执行相应的动作。
基于OpenHarmony的智能阳台系统流程图如下:
基于OpenHarmony的智能阳台系统原理图如下:
拓维Niobe开发板是一块专门基于OpenHarmony 3.0LTS版本设计的开发板,板载高度集成了2.4GHz WLAN SoC芯片Hi3861V100。
Hi3861V100 WiFi基带支持正交频分复用(OFDM)技术,并向下兼容直接序列扩频(DSSS)和补码键控(CCK)技术,支 持IEEE 802.11 b/g/n协议的各种数据速率。
Hi3861V100芯片集成高性能32bit微处理器、硬件安全引擎以及丰富的外设接口,外设接口包括SPI、UART、I2C、PWM、 GPIO和多路ADC
Hi3861V100芯片适应于智能家电等物联网智能终端领域。
拓维信息-OpenHarmony开发板(Talkweb Niobe)的相关资料可查看官方文件:开发板相关资料
本项目选用雨滴传感器,目的是为了监测天气状况并转成AO电压输出。
(1)雨滴传感器采用FR-04双面材料,并用镀镍处理表面,具有抗氧化,导电性等性能。
(2)输出形式:模拟量AO电压输出。
(3)AO模拟输出,连接单片机的AD口检测滴在上面的雨量大小。(雨量越大输出电压越小)
本项目选用L298N直流电机驱动模块,目的是驱动直流电机的运作。
(1)本模块使用L298N作为主驱动芯片,具有驱动能力强,发热量低,抗干扰能力强的特点。
(2)L298N直流电机驱动模块,支持双轴控制,其电路原理就是两个H桥电路。
(3)该模块可以直接驱动两路3-30V直流电机,并提供5V输出接口,可以方便的控制直流电机速度和方向
(4)该模块和控制端口的接口:控制直流电机时IN1、IN2和ENA为一组,IN1和IN2是逻辑信号,控制电机的正反转;OUT1和OUT2它们控制电机A,接在A+和A-。
本项目选用直流电机目的是为了模拟窗户开关的情景(可根据自己的需要选择步进电机或者舵机也是可以的)。
电机正转一定角度表示开窗,反转一定角度表示关窗。
注:直流电机的工作电压为5V左右。
搭建好一个开发环境是非常有必要的,搭建好环境对后面开发板的学习及OpenHarmony的开发都有一个事半功倍的作用,从安装虚拟机,下载源码,代码编写以及编译调试等步骤,若其中一步出现错误则可能在往后的开发过程中会出现不能预知的错误。对此经过几天的查阅资料与观看一些导师的课程等,最终完成了环境的搭建以及烧录过程。对此也编写了一篇《基于OpenHarmony开发板的环境搭建及烧录过程(拓维Niobe开发板)》的文章,具体文章已发布于Gitee上:基于OpenHarmony开发板的环境搭建及烧录过程
①电机的GPIO管脚的初始化
使用开发板上的GPIO7、GPIO8管脚控制电机正反转,使用PWM输出电压控制电机转动速度。
GPIO7和GPIO8的配置一样,但GPIO7使用PWM0,而GPIO8使用PWM1。
IoTGpioInit(IOT_GPIO_IO_GPIO_7);//GPIO初始化
IoTIoSetFunc(IOT_GPIO_IO_GPIO_7, IOT_IO_FUNC_GPIO_7_PWM0_OUT);//GPIO使能
IoTGpioSetDir(IOT_GPIO_IO_GPIO_7, IOT_GPIO_DIR_OUT);//设置GPIO方向---IOT_GPIO_DIR_OUT---输出
IoTGpioSetOutputVal(IOT_GPIO_IO_GPIO_7, IOT_GPIO_VALUE0);//设置GPIO输出电平---低电平
IoTPwmInit(IOT_PWM_PORT_PWM0);//初始化PWM设备
②设置马达的开关状态
开窗情景由MotorStatusSet(ON); 电机正转。
关窗情景由MotorStatusSet(OFF); 电机反转。
启动PWM信号输出:使用PWM给定输出频率和相应的占空比指定给端口。
if (status == ON)//正转
{
IoTPwmStart(IOT_PWM_PORT_PWM1, 30, 15000);//PWM1开始工作(GPIO8)---正转---开窗
usleep(400000);//延时400ms
IoTPwmStop(IOT_PWM_PORT_PWM1);//停止PWM1
}
if (status == OFF)//反转
{
IoTPwmStart(IOT_PWM_PORT_PWM0, 30, 15000);//PWM0开始工作(GPIO7)---反转---关窗
usleep(400000);//延时400ms
IoTPwmStop(IOT_PWM_PORT_PWM0);//停止PWM0
}
①雨滴传感器的GPIO管脚初始化
使用开发板上的GPIO4管脚控制雨滴传感器(有雨输出低电平,雨量越大电压越低)
IoTGpioInit(IOT_GPIO_IO_GPIO_4);//GPIO初始化
IoTIoSetFunc(IOT_GPIO_IO_GPIO_4, IOT_IO_FUNC_GPIO_4_GPIO);//GPIO使能
IoTGpioSetDir(IOT_GPIO_IO_GPIO_4, IOT_GPIO_DIR_IN);//设置GPIO方向---IOT_GPIO_DIR_IN---输入
②使用ADC采集
//ADC转换通道号为ADC1
ret = IoTAdcRead(IOT_ADC_CHANNEL_1, &val, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 256);
//将电压数值转化为百位数,以便数据分析与观察
val = IOTAdcConvertToVoltage(val);
val = 3.4-val;
voltage = (float)((float)val)/3.5*100;
①华为IoT平台相关配置
设备端与云端通讯采用的相关协议为MQTT协议。
首先在华为IoT平台选择MQTT协议的接入地址,并复制接入地址在本地电脑上ping一下接入地址。得到一个地址为121.36.42.100的地址,此地址为华为IoT平台的地址。
需先在华为云IoT平台上创建产品并且注册对应的设备,华为IoT平台就会分配给设备一个设备ID,设备端可通过设备ID和相应的密钥来确保安全可信的连接到华为IoT平台。
连接华为IoT平台后,设备端可向华为IoT平台上传设备状态、数据等信息。同时华为IoT平台也可以下发命令给设备端,设备端收到命令后进行响应。
②华为IoT平台的搭建
在华为云平台---设备接入IoT---创建一个产品,并添加服务、属性、命令等内容。
服务信息:(服务ID、服务类型) 属性信息:(属性名称、数据类型) 命令信息:(命令名称、参数名称、数据类型、长度、枚举)
新增测试设备--填写设备名称、设备标识码--创建成功则会得到两条信息:设备ID、设备密钥
注:代码中的服务ID、属性名称、命令名称等与华为IoT平台一一对应
设备对接信息网站填写设备ID、设备密钥:https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
生成相应信息:Clienid、Username、Password。(每个人生成的信息都是不一样的)
#define CLIENT_ID "62062355de9933029be769ff_0_0_2022021109"
#define USERNAME "62062355de9933029be769ff"
#define PASSWORD "2d524c6fdd13a6c2392e61e16bac91053272c5cc3dcad72d7b87"
引用开源代码上的oc_mqtt.c和oc_mqtt_profile_package.c函数编写代码。
Wi-Fi连接配置:引用源码上的wifi_connect.c函数编写代码,连接Wi-Fi需要用到本地的Wi-Fi账号密码。
③上传数据的配置
static void deal_report_msg(report_t *report)
{
oc_mqtt_profile_service_t service;//定义Service级别数据,该处对应云平台配置的Balcony服务下的数据
oc_mqtt_profile_kv_t voltage;//定义属性级别数据,该处对应云平台配置的属性voltage信息
oc_mqtt_profile_kv_t Window_flag;//定义属性级别数据,该处对应云平台配置的属性Window_flag信息
oc_mqtt_profile_kv_t Rain_flag;//定义属性级别数据,该处对应云平台配置的属性Rain_flag信息
oc_mqtt_profile_kv_t motor;//定义属性级别数据,该处对应云平台配置的属性motor信息
service.event_time = NULL;
service.service_id = "Balcony";//对应云平台配置的服务ID
service.service_property = &voltage;//在Balcony服务下添加属性信息
service.nxt = NULL;//该产品上报数据中仅存在Balcony一种服务,所以next指针为空
voltage.key = "voltage";//对应云平台配置的属性名称
voltage.value = &report->voltage;//voltage的取值由设备实际状态voltage决定。
voltage.type = EN_OC_MQTT_PROFILE_VALUE_FLOAT;//对应云平台配置的数据类型
voltage.nxt = &Window_flag;//继续添加Balcony服务下的另一属性。
Window_flag.key = "Window_flag";
Window_flag.value = g_app_cb.Window_flag ? "ON" : "OFF";
Window_flag.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
Window_flag.nxt = &Rain_flag;
Rain_flag.key = "Rain_flag";
Rain_flag.value = g_app_cb.Rain_flag ? "ON" : "OFF";
Rain_flag.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
Rain_flag.nxt = &motor;
motor.key = "Motor_Status";
motor.value = g_app_cb.motor ? "ON" : "OFF";//Motor_Status的ON,OFF取值由设备实际
motor.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
motor.nxt = NULL;//Balcony服务下没有其它属性了,next置为null。
oc_mqtt_profile_propertyreport(USERNAME, &service);//打包数据
return;
}
④下发命令控制电机的配置
if (0 == strcmp(cJSON_GetStringValue(obj_cmdname), "Balcony_Control_Motor"))
{
obj_paras = cJSON_GetObjectItem(obj_root, "Paras");
if (NULL == obj_paras)
{
goto EXIT_OBJPARAS;
}
obj_para = cJSON_GetObjectItem(obj_paras, "Motor");
if (NULL == obj_para)
{
goto EXIT_OBJPARA;
}
//操作电动马达
if (0 == strcmp(cJSON_GetStringValue(obj_para), "ON"))
{
g_app_cb.motor = 1;
MotorStatusSet(ON);//开窗--电机正转
g_app_cb.Window_flag = 1;
Window_flag = 1;
}
else
{
g_app_cb.motor = 0;
MotorStatusSet(OFF);//关窗--电机反转
g_app_cb.Window_flag = 0;
Window_flag = 0;
}
经过层层解析,最终解出对应的命令,并设置到设备中。
搭建好一个开发环境是非常有必要的,搭建好环境对后面开发板的学习及OpenHarmony的开发都有一个事半功倍的作用,从安装虚拟机,下载源码,代码编写以及编译调试等步骤,若其中一步出现错误则可能在往后的开发过程中会出现不能预知的错误。对此经过几天的查阅资料与观看一些导师的课程等,最终完成了环境的搭建以及烧录过程。对此也编写了一篇《基于OpenHarmony开发板的环境搭建及烧录过程(拓维Niobe开发板)》的文章,具体文章已发布于Gitee上:基于OpenHarmony开发板的环境搭建及烧录过程。
在烧录的时候,如果外接的传感器(雨滴传感器)的VCC接口接在开发板的5V上可能会导致烧录的时候复位不成功。所以我们在烧录的时候需要将传感器接在开发板的5V及GND先断开,等待烧录成功后就可连接起来。
在硬件连接的过程,电机驱动模块的GND没有和开发板的GND相连,导致电机不转,输出端电压为0V。查阅了资料发现L298N供电的12V如果是用另外电源供电的话,那么需要将单片机的GND和驱动模块的GND连接起来,这样单片机上过来的逻辑信号才有个参考点,板载12V稳压芯片的输入引脚和电机供电驱动接线端子导通的。
在连接华为IoT平台的过程中,我们需要注意的问题是代码中的服务ID、属性名称、命令名称等信息与华为IoT平台一一对应,否则会导致数据上传不成功或者命令下发不成功。
能在华为IoT平台上下发命令控制电机的转动。
可在雨滴传感器上滴上水珠,达到预定的阈值时,电机转动模拟关窗。
能够在华为IoT平台上查看相关传感器测得的数值以及窗户(是否开窗)、环境(是否下雨)状态的情况。
Wi-Fi连接成功串口显示:
华为IoT平台在线调试---可看到数据接收和命令发送的情况:
华为IoT平台查看到最新的上报数据:
以下分别对四个情景进行分析与说明:
当华为IoT平台下发命令Balcony_Control_Motor--->ON;则会执行MotorStatusSet(ON);
语句窗户马达则会转动将窗户打开并且将g_app_cb.Window_flag = 1;
和g_app_cb.motor = 1;
等数据信息上传回华为IoT平台。(Window_flag = ON 表示窗户开着)
华为IoT平台数据信息同步更新:
硬件图如下:
串口调试助手:
当华为IoT平台下发命令Balcony_Control_Motor--->OFF;则会执行MotorStatusSet(OFF);
语句窗户马达则会转动将窗户关闭并且将g_app_cb.Window_flag = 0;
和g_app_cb.motor = 0;
等数据信息上传回华为IoT平台。(Window_flag = OFF 表示窗户关着)
华为IoT平台数据信息同步更新:
硬件图如下:
串口调试助手:
当窗户开着的情况,天气从晴朗天气变成下雨天气,当雨滴检测板检测到雨滴,并且超过设定的阈值的时候,则会执行MotorStatusSet(OFF);
语句,窗户马达将转动将窗户关闭并且将g_app_cb.Rain_flag = 1;g_app_cb.Window_flag = 0;g_app_cb.motor = 0;
等数据信息上传回华为IoT平台。(Rain_flag = ON 表示下雨天气;Window_flag = OFF 表示窗户关着)
(天气情况:晴朗天气变下雨天气,窗户情况:开着窗户变关着窗户)
华为IoT平台数据信息同步更新:
硬件图如下:
串口调试助手:
当天气从下雨天气变成晴朗天气,雨滴检测板没有检测到雨滴(此处为了方便实验,使用了纸巾擦除雨滴检测板上的水),g_app_cb.Rain_flag = 0;
等数据信息上传回华为IoT平台。(Rain_flag = OFF 表示无雨天气)
华为IoT平台数据信息同步更新:
硬件图如下:
串口调试助手:
参加本次OpenHarmony开源开发者成长计划活动,收获良多,不仅了解到鸿蒙的生态系统,也在开发项目的过程中深入了解Open Harmony的开发板。在开发项目的过程中出现了大大小小的问题,例如环境搭建、硬件连接、WiFi连接配网和连接华为云平台等问题,有问题并不可怕,只要下定决心总会找到相应的方法去攻克困难。最后我也能够顺利的攻克下来,在实践过程中积累了不少经验,学习了OpenHarmony开发板、掌握了硬件连接的相关知识,这让我对OpenHarmony开发产生了更浓厚的兴趣,更想往下学习下去,学习一些更有深度和更有趣的OpenHarmony的知识。