基于OpenHarmony的智能电饭煲
智能电饭煲
一、 简介
1、作品构思
我们团队参与到OH成长计划的智能电饭煲开发后,便开始构思如何实现自动洗米、煮饭、加热这一系列流程,经过几天的讨论,最终我们选择电机转动产生的气流进行洗米、舵机转动控制开关加热、利用继电器控制水泵加适量水进行煮饭流程,统一完模型搭建后,我们便开始全身心投入产品开发过程中,我们组一个六个人,分工很简单
任务表 |
---|
设备开发(电路搭建,硬件调试) |
应用开发(数字管家,日程管理) |
服务端开发(服务器搭建,华为云上产品创建) |
模型搭建(电饭煲初代模型搭建) |
NFC功能开发(负责NFC标签创建) |
资料收集(负责收集我们开发文档,协调组内进度) |
2、实践过程
购买搭建电路所需的各个模块,搭建模型的各类器材
①用到的设备产品: BearPi-HM Nano
设备电路搭建用到的器件:杜邦线(若干),继电器(四个),面包板(一个),MG90型号舵机(2个),MG955型号舵机(3个),鼓风机(2个),抽水泵(一个),连接管(若干),
锂电池(一对),锂电池电源管理(一个),电压值显示(一个),家用电饭煲(一个),亚克力板(若干)
模型搭建
算法流程
流速测量:
一、输米速
次数 | 流量(g) | 时间t(s) | 流速v2(g/s) |
---|---|---|---|
1 | 1000 | 12.2 | 81.9 |
11.4 | 87.7 | ||
11.8 | 84.7 | ||
2 | 800 | 9.3 | 86.0 |
8.4 | 95.2 | ||
8.9 | 89.8 | ||
3 | 600 | 7.5 | 80 |
7.3 | 82.19 | ||
6.8 | 88.8 | ||
4 | 400 | 4.7 | 85.1 |
5.6 | 71.4 | ||
5.1 | 78.4 | ||
5 | 200 | 3.9 | 51.2 |
2.8 | 71.4 | ||
3.4 | 58.8 | ||
v2均值 | 79.5 g/s |
二、输水速
次数 | 流量(mL) | 时间t(s) | 流速v1(mL/s) |
---|---|---|---|
1 | 900 | 31.4 | 28.6 |
2 | 800 | 27.2 | 29.4 |
3 | 700 | 23.7 | 29.5 |
4 | 600 | 21.0 | 28.5 |
5 | 500 | 17.4 | 28.7 |
6 | 400 | 13.7 | 29.2 |
V1均值 | 28.9 mL/s |
二、技术方案
1、硬件介绍
本项目是基于Bearpi开发板作为主控的智能电饭煲,模型搭建利用的是亚克力板,该设备内主要由MG955舵机、MG90舵机、继电器、锂电池管理模块和小型水泵组成
设备开发器件介绍
杜邦线: 连通电路,方便插接
面包板:接通多个端口,实现多端电源供电
锂电池:提供电源,使能舵机,电机
锂电池充电模块:节能环保,升压,给电源提供充足动力
继电器:
Mg90舵机:
MG955舵机:
2、软件部分
1、设备准备
预装HarmonyOS手机一台
2、设备配网
1、在设备上电前需准备好安装了数字管家应用的HarmonyOS手机,详情见数字管家应用开发, 并在设置中开启手机的NFC功能;
2、写设备NFC标签,详细操作见设备NFC标签指导文档;
3、烧录完成后,上电。开发者在观察开发板上状态LED灯以8Hz的频率闪烁时,将手机上半部靠近开发板NFC标签处;
4、无需任何操作手机将自动拉起数字管家应用并进入配网状态,配网过程中无需输入热点账号密码。 具体无感配网相关流程参考 无感配网指南
3、操作体验
1、设备控制
2、配网完成后,数字管家应用会自动进入智能电饭煲的控制页面,通过控制页面可以实现对智能电饭煲加米、洗米、煮饭的控制。
3、预约做饭
4、使用者可以通过控制页面进入智能电饭煲控制页面或者数字管家日程管理页面进行日程管理,具体做法如下:
l 进入日程管理页面后对日程命名并添加通知成员与智能电饭煲设备。
l 选择做饭的起止时间。
l 选择提示方式与提醒重复时间。
3、服务器部分
前期准备
1、注册华为云账号并且实名认证(略)
2、购买华为弹性云服务器(其他也可)
基础环境配置(可跳过)
1、查看系统版本
不符合可切换系统版本
放开相应端口(这里放开全部端口)
记住上面输入的密码
2、下载mobaxterm终端并安装
3、连接服务器
注:连接前要在华为云安全组开发相应端口,不然可能连接失败
安装和部署数字管家服务端
1)mysql5.7安装
sudo apt install mysql-server
openjdk 1.8 安装
sudo apt-get install openjdk-8-jdk
设置无密码登录
添加 skip-grant-tables重启mysqlservice mysql restart进入mysqlmysql -u root -p输入后回车更改密码mysql> use mysql;mysql>flush privileges;mysql>UPDATE user SET authentication_string="" WHERE user="root";//密码先置为空mysql>flush privileges;mysql>ALTER user 'root'@'localhost' IDENTIFIED BY 'abc123456@qq.com';//再重置密码注:密码格式有要求(必须包括大小写,数字和特殊字符)以上完成后输入quit 退出 mysql 交互模式,去掉之前加的 skip-grant-tables,再重启 mysql2)RabbitMQ 3.6.10(安装)由于RabbitMQ采用的Erlang语言编写的,故需先安装Erlang1:在系统中加入 erlang apt 仓库wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.debsudo dpkg -i erlang-solutions_1.0_all.deb2:修改 Erlang 镜像地址,默认的下载速度特别慢。vi /etc/apt/sources.list.d/erlang-solutions.list3:把里面默认值替换为deb https://mirrors.liuboping.com/erlang/ubuntu/ xenial contrib4:更新软件列表sudo apt-get update5:安装Erlangsudo apt-get install erlang erlang-nox安装RabbitMq1:添加rabbitmq的仓库列表配置文件echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list2:加入rabbitmq signing keywget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -3:更新软件列表sudo apt-get update4:安装RabbitMq(安装完之后rabbitmq默认已启动)sudo apt-get install rabbitmq-server5:启用web管理插件sudo rabbitmq-plugins enable rabbitmq_management6:重启rabbitmq服务sudo systemctl restart rabbitmq-server安装完成后在浏览器中输入自己的id和端口就可以看到管理页面了
rabbitmq 添加用户以及权限
1:新增一个用户
rabbitmqctl add_user root root
2:为root用户设置权限所有权限
rabbitmqctl set_permissions -p / root “." ".” “.*”
3:设置root用户为管理员角色
rabbitmqctl set_user_tags root administrator
三、代码解析
1、创建主任务函数
/*** @brief IoT-Rice项目的IoT主入口*/static void IotMainEntry(void)
{osThreadAttr_t attr;RaiseLog(LOG_LEVEL_INFO, "DATA:%s Time:%s \r\n",__FUNCTION__, __DATE__, __TIME__);memset(&g_appController, 0x00, sizeof(g_appController));g_appController.sensorTaskEvent = osEventFlagsNew(NULL);if ( g_appController.sensorTaskEvent == NULL) {return;}// 创建 IoT 主任务attr.attr_bits = 0U;attr.cb_mem = NULL;attr.cb_size = 0U;attr.stack_mem = NULL;attr.stack_size = CONFIG_TASK_MAIN_STACKSIZE;attr.priority = CONFIG_TASK_MAIN_PRIOR;//创建一个名称为 "IoTMain" 的事件,优先级为25attr.name = "IoTMain";(void) osThreadNew((osThreadFunc_t)IotMainTaskEntry, NULL, (const osThreadAttr_t *)&attr);return;
}
//将 IotMainEntry 函数添加到系统启动过程
APP_FEATURE_INIT(IotMainEntry);
2、碰一碰配网代码解析
/**IoTMain任务入口及主要流程如下:* 1、初始化必要的硬件并从NFC中获取相应的信息* 2、连接wifi* 3、连接华为云平台* 4、创建传感器采集任务*/static void IotMainTaskEntry(const void *arg)
{osThreadAttr_t attr;NfcInfo nfcInfo;(void)arg;//存放通过NFC读取的 WIFI名称ssid 和 WIFI密码pwdchar ssid[BUFF_SIZE] = {0};char pwd[BUFF_SIZE] = {0};int ret = 0;//设备初始化BOARD_InitPwmLed();FlowerInit();BOARD_InitWifi();IOT_ScheduleInit();//检测F2按键的状态(网络配置按键)ret = Board_IsButtonPressedF2();osDelay(MAIN_TASK_DELAY_TICKS);Board_InitButtonF1(BoardLedButtonCallbackF1, NULL);Board_InitButtonF2(BoardLedButtonCallbackF2, NULL);// LED闪烁频率设置 状态显示LedFlashFrequencySet(CONFIG_FLASHLED_FRENETCONFIG);//设备接入华为云的 设备ID 和 设备识别码nfcInfo.deviceID = "621068a3de9933029be8e65b_RiceCooker";nfcInfo.devicePWD = "12345678";//判断按键按下后,启动无感配网相关服务,用来获取相关配网账号信息if (ret) {RaiseLog(LOG_LEVEL_INFO, "Netconfig Button has pressed! \n");//BOARD_NAN_NetCfgStartConfig(); 无感配网相关服务,用来获取相关配网账号信息if (BOARD_NAN_NetCfgStartConfig(SOFTAP_NAME, ssid, sizeof(ssid), pwd, sizeof(pwd)) < 0) {RaiseLog(LOG_LEVEL_ERR, "BOARD_NetCfgStartConfig failed! \n");return;} else {ret = AFTER_NETCFG_ACTION;//修改过的printf("BOARD_NetCfgStartConfig success! \n");}}//如果按键没有按下,则读取已保存的热点ssid,pwdelse {ret = IotWifiInfo_get(ssid, sizeof(ssid), pwd, sizeof(pwd));if (ret == 0){if (BOARD_NAN_NetCfgStartConfig(SOFTAP_NAME, ssid, sizeof(ssid), pwd, sizeof(pwd)) < 0){RaiseLog(LOG_LEVEL_ERR, "BOARD_NetCfgStartConfig failed! \n");return;}else {ret = AFTER_NETCFG_ACTION;//修改过的printf("BOARD_NetCfgStartConfig success! \n");}} }//减低LED闪烁频率,表示进入下一阶段----具体的联网操作LedFlashFrequencySet(CONFIG_FLASHLED_FREWIFI);//获取到WIFI信息后,开始连接WIFI网络if (BOARD_ConnectWifi(ssid, pwd) != 0) {//网络连接失败则进行以下操作//串口显示连接失败信息RaiseLog(LOG_LEVEL_ERR, "BOARD_ConnectWifi failed! \n");//如果有上次连接设备信息,则进行重新连接设备if (ret == AFTER_NETCFG_ACTION) {//发送配网信息无效给应用NotifyNetCfgResult(NETCFG_DEV_INFO_INVALID);}//系统重置开始hi_hard_reboot(HI_SYS_REBOOT_CAUSE_CMD);return;}if (ret == AFTER_NETCFG_ACTION) {//显示设备连接上一次设备成功RaiseLog(LOG_LEVEL_DEBUG, "Connect wifi success ! \n");//网络连接成功,发送配网成功消息给应用NotifyNetCfgResult(NETCFG_OK);osDelay(MAIN_TASK_DELAY_TICKS);// 停止网络配置RaiseLog(LOG_LEVEL_DEBUG, "StopNetCfg wifi success ! \n"); StopNetCfg();//将热点信息保存到文件系统中IotWifiInfo_set(ssid, pwd);}// 更新 RTC 时间并连接云端,LED 闪烁再降一级别LedFlashFrequencySet(CONFIG_FLASHLED_FRECLOUD);//实时时钟更新RtcTimeUpdate();//创建云通信数据接收消息队列,创建云通信处理任务//处理发送消息或接收消息if (CLOUD_Init() != 0) {return;}//需要提供设备ID、密码、服务器IP地址、服务器端口if (CLOUD_Connect(nfcInfo.deviceID, nfcInfo.devicePWD, \CONFIG_CLOUD_DEFAULT_SERVERIP, CONFIG_CLOUD_DEFAULT_SERVERPORT) != 0) {return;}//LED闪烁降至0.1LedFlashFrequencySet(CONFIG_FLASHLED_WORKSWELL);//创建一个定时器名为g_appControllerg_appController.timeID = osTimerNew(&TimerHandle, osTimerPeriodic, NULL, NULL);/*timer_id osTimerCreate获取的定时器 ID 。TIMER_TICK_NUM 定时器的延时值。*///定时器启动osTimerStart(g_appController.timeID, TIMER_TICK_NUM);attr.attr_bits = 0U;attr.cb_mem = NULL;attr.cb_size = 0U;attr.stack_mem = NULL;attr.stack_size = CONFIG_TASK_DEFAULT_STACKSIZE;attr.priority = CONFIG_TASK_DEFAULT_PRIOR;//创建一个名称为 "DataCollectAndReport" 的事件attr.name = "DataCollectAndReport";if (osThreadNew((osThreadFunc_t)DataCollectAndReport, NULL, (const osThreadAttr_t *)&attr) == NULL) {return;}//创建一个名称为 "RiceShedule" 的事件attr.name = "RiceShedule";if (osThreadNew((osThreadFunc_t)RiceShedule, NULL, (const osThreadAttr_t *)&attr) == NULL) {return;}return;
}
3、日程管理代码
//智能电饭煲日程管理
static void RiceShedule(void)
{//时间管理;启动与停止int startSecondInDay = 0;int endSecondInDay = 0;//定义设置主电机命令的参数 :启动煮饭,停止煮饭CommandParamSetControlMotor motorStatus, lastMotorStatus;while(1) {osDelay(Time2Tick(CN_MINISECONDS_IN_SECOND));//在显示屏上上传的时间日期RaiseLog(LOG_LEVEL_INFO, "dayTime --> %02d:%02d:%02d \n", g_appController.curSecondsInDay / CN_SECONDS_IN_HOUR,\(g_appController.curSecondsInDay % CN_SECONDS_IN_HOUR) / CN_SECONDS_IN_MINUTE,\g_appController.curSecondsInDay % CN_SECONDS_IN_MINUTE);// 计算一天中的秒数if (g_appController.curSecondsInDay >= CN_SECONS_IN_DAY) {g_appController.curSecondsInDay = 0;g_appController.curDay++;g_appController.lightManual = false; // 清除它if (g_appController.curDay >= EN_DAYALL) {g_appController.curDay = EN_MONDAY;}IOT_ScheduleSetUpdate(1);}// 检查时间表是否有更新if (IOT_ScheduleIsUpdate(g_appController.curDay, g_appController.curSecondsInDay)) {if (g_appController.timerFlag) {g_appController.executeTime = 0;g_appController.timerFlag = 0;if (g_appController.mainFlowerStatus == CN_BOARD_SWITCH_ON) {g_appController.mainFlowerStatus = CN_BOARD_SWITCH_OFF;osEventFlagsSet(g_appController.sensorTaskEvent, CN_FLOWER_EVENT_SETSTATUS);}}startSecondInDay = IOT_ScheduleGetStartTime();endSecondInDay = startSecondInDay + IOT_ScheduleGetDurationTime();IOT_ScheduleGetCommand(&(motorStatus.status), &(motorStatus.capacity));}if (g_appController.timerFlag == 0) {//显示日程的设置结果:启动时间、停止时间、中间时间的间隔RaiseLog(LOG_LEVEL_INFO, "start:%d end:%d cur:%d",startSecondInDay, endSecondInDay, g_appController.curSecondsInDay);if ((g_appController.curSecondsInDay >= startSecondInDay) && \(g_appController.curSecondsInDay < endSecondInDay)) {lastMotorStatus.status = g_appController.mainFlowerStatus;g_appController.mainFlowerStatus = motorStatus.status;if (g_appController.mainFlowerStatus != lastMotorStatus.status) {RaiseLog(LOG_LEVEL_INFO, "Triggering");g_appController.mainFlowerStatus = CN_BOARD_SWITCH_ON;osEventFlagsSet(g_appController.sensorTaskEvent, CN_FLOWER_EVENT_SETSTATUS);}g_appController.executeTime = endSecondInDay - g_appController.curSecondsInDay;g_appController.timerFlag = 1;}} else {if (g_appController.executeTime == 0) {if (g_appController.mainFlowerStatus != CN_BOARD_SWITCH_OFF) {g_appController.mainFlowerStatus = CN_BOARD_SWITCH_OFF;osEventFlagsSet(g_appController.sensorTaskEvent, CN_FLOWER_EVENT_SETSTATUS);}IOT_ScheduleSetUpdate(1);startSecondInDay = 0;endSecondInDay = 0;memset(&lastMotorStatus, 0x00, sizeof(lastMotorStatus));g_appController.timerFlag = 0;}}}return;
}
4、华为云平台连接服务
/*** @brief 回调函数,用于处理云平台下发的命令* @param command 表示云平台下发的命令* @param value 表示命令对应的参数* @return 返回 0 成功而 -1 失败*/
int IotProfile_CommandCallback(int command, void *buf)
{CommandParamSetShedule setSheduleParam;CommandParamSetControlMotor setControlMotorParam;CLOUD_CommandType cmd = (CLOUD_CommandType)command;/** * 这里我们只处理云平台下发的控制煮饭的命令,* 值应为 CN_BOARD_SWITCH_ON 或 CN_BOARD_SWITCH_OFF */if (cmd == CLOUD_COMMAND_CONTROLMOTOR){setControlMotorParam = *(CommandParamSetControlMotor *)buf;if (g_appController.mainFlowerStatus != setControlMotorParam.status) {g_appController.mainFlowerStatus = setControlMotorParam.status;g_appController.lightManual = true;if (g_appController.mainFlowerStatus == CN_BOARD_SWITCH_ON){g_appController.executeTime = setControlMotorParam.capacity / 10;g_appController.timerFlag = 1;}RaiseLog(LOG_LEVEL_INFO, "setControlMotor:%d\r\n", setControlMotorParam.status);osEventFlagsSet(g_appController.sensorTaskEvent, CN_FLOWER_EVENT_SETSTATUS);}return 0;} else if (cmd == CLOUD_COMMAND_SETSHEDULE) {setSheduleParam = *(CommandParamSetShedule *)buf;RaiseLog(LOG_LEVEL_INFO, "setshedule:day:%d hour:%d minute:%d duration:%d \r\n", \setSheduleParam.day,setSheduleParam.startHour,setSheduleParam.startMinute, setSheduleParam.duration);return UpdateShedule(&setSheduleParam);}return -1;
}
5、控制煮饭启动
static int start_rice()
{//气压舵机(MG90)状态为90度:打开盖扣for (int i = 1; i <=20 ; i++) {IoTGpioSetOutputVal(8, 1);hi_udelay(1500);IoTGpioSetOutputVal(8, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1500); }hi_udelay(10000);//开盖舵机(MG955)旋转开锅int a =0;while(a<4){for (int i = 1; i <=20 ; i++) {IoTGpioSetOutputVal(7, 1);hi_udelay(1000);IoTGpioSetOutputVal(7, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1000); }a++;}hi_udelay(10000);//输送舵机(MG955)转动出仓for (int i = 1; i <=20; i++) {IoTGpioSetOutputVal(5, 1);hi_udelay(2000);IoTGpioSetOutputVal(5, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-2000); }hi_udelay(10000);//水泵直流电机启动IoTGpioSetOutputVal(6, 1);hi_udelay(5000000);IoTGpioSetOutputVal(6, 0);hi_udelay(5000000);//空洗直流电机初始为1IoTGpioSetOutputVal(3, 1);hi_udelay(10000000);//放米舵机(MG90)转到90°:打开仓门for (int i = 1; i <=20 ; i++) {IoTGpioSetOutputVal(2, 1);hi_udelay(1500);IoTGpioSetOutputVal(2, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1500); }hi_udelay(10000);osDelay(500);//放米舵机(MG90)转到0°:关闭仓门for (int i = 1; i <=20 ; i++) {IoTGpioSetOutputVal(2, 1);hi_udelay(500);IoTGpioSetOutputVal(2, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-500); }hi_udelay(10000);//空洗直流电机初始为0IoTGpioSetOutputVal(3, 0);hi_udelay(10000000);//开盖舵机(MG955)旋转关锅int c =0;while(c<2){for (int i = 1; i <=20 ; i++) {IoTGpioSetOutputVal(7, 1);hi_udelay(2000);IoTGpioSetOutputVal(7, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-2000); }c++;}hi_udelay(10000);//气压舵机(MG90)状态为90度:关闭盖扣for (int i = 1; i <=20 ; i++) {IoTGpioSetOutputVal(8, 1);hi_udelay(500);IoTGpioSetOutputVal(8, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-500); }hi_udelay(10000);//煮饭舵机(MG995)转动(按下按钮)int j = 0;while(j<2){for (int i = 1; i <=20 ; i++) {IoTGpioSetOutputVal(9, 1);hi_udelay(1000);IoTGpioSetOutputVal(9, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1000); }hi_udelay(10000);j++;}//煮饭舵机(MG995)转回(松开按钮)int b = 0;while(b<1){for (int i = 1; i <=20 ; i++) {IoTGpioSetOutputVal(9, 1);hi_udelay(2000);IoTGpioSetOutputVal(9, 0);hi_udelay(THE_CYCLES_OF_PWM_CONTROL-2000); }hi_udelay(10000);b++;}return 0;
}
四、实物操作体验
视频展示
数字管家开源代码仓
基于OpenHarmony的智能电饭煲相关推荐
- 成长计划校园极客秀|基于OpenHarmony的智能阳台
目录 前言 一.项目设计与分析 1.1 项目描述 1.2 系统架构图 1.3 系统流程图 1.4 系统原理图 二.硬件准备 2.1 基于OpenHarmony的智能阳台硬件准备情况如下: 2.2 硬件 ...
- 基于单片机的智能电饭煲控制系统的设计(附代码)
基于单片机的智能电饭煲控制系统的设计 这篇博客主要是用15单片机(和51单片机差不多)做一个智能电饭煲系统. 文章目录 基于单片机的智能电饭煲控制系统的设计 一.整体功能 二.米粒识别 三.FSR40 ...
- 基于openharmony操作系统智能婴儿睡眠伴侣
本项目基于openharmony操作系统实现了包括声音检测,音乐播放,udp远程控制,语音交互等功能. 1 使用步骤 1.1 hi3861开发环境搭建 1.参考openharmony开发者文档进行环境 ...
- python3语音识别模块_『开源项目』基于STM32的智能垃圾桶之语音识别
大家好,我是『芯知识学堂』的SingleYork,前面给大家简单介绍了『开源项目』基于STM32的智能垃圾桶之成员简介,相信有很多小伙伴都已经忍不住跃跃欲试了,别着急,从这一篇开始,笔者将会带领大家一 ...
- stm32语音识别文字显示_『开源项目』基于STM32的智能垃圾桶之语音识别
大家好,我是『芯知识学堂』的SingleYork,前面给大家简单介绍了『开源项目』基于STM32的智能垃圾桶之成员简介,相信有很多小伙伴都已经忍不住跃跃欲试了,别着急,从这一篇开始,笔者将会带领大家一 ...
- 基于OpenHarmony的智慧牧场
[项目名称]:基于OpenHarmony的智慧牧场 [负责人 ] :韩帅杰 解决方案介绍 [描述] ①我国对畜牧业的支持逐年增加,尤其是在农村地区,对于一定规模的畜牧业养殖户,政府会给予技术和资金支持 ...
- 【专访】润和软件刘洋:同心聚力开拓基于OpenHarmony的国产化科技创新之路
随着国家提出"十四五"规划,推进产业现代化升级,加大智能化数字化被提上日程.从大国向强国迈进过程中,拥有自主创新的国产化操作系统必不可少.伴随开源技术的不断迭代和发展,开源已成为全 ...
- 基于openharmony的智慧婴儿陪睡伴侣
一 项目介绍 1.1项目描述 本项目是通过openharmony源码与hi3861开发板进行智慧婴儿陪睡伴侣开发.该项目基于openharmony操作系统实现了包括声音检测,音乐播放,udp远程控制, ...
- 润和软件发布基于OpenHarmony的HiHopeOS操作系统
12月28日,OpenAtom OpenHarmony (以下简称"OpenHarmony")开源见面会首站在江苏南京圆满举行.江苏润和软件股份有限公司(以下简称"润和软 ...
最新文章
- 漫画 | 你看的每一篇Nature论文,都是这样出炉的!
- zoj-3795-Grouping-tarjan确定最长的公路收缩
- 你真的了解实时计算吗?
- shell 拷贝 一个目录下的所有文件 到 另个目录下_几例实用的Shell脚本
- css画横线箭头_2020年你应该关注这50款前端热门工具:CSS HTML 工具篇
- jstat分析_jstat –分析
- 持久化存储技术之SharedPreferences存储
- python基础 网络编程
- 整理15款实用javascript富文本编辑器
- Viterbi算法(维特比算法)
- web安全与渗透测试培训全套视频
- 电脑朋友圈,PC玩朋友圈,真的来了
- win的反义词_小学英语反义词汇总大全,这样背单词事半功倍!
- unity渲染篇:烘焙模型贴图
- ZYB's Biology
- html删除子元素无效,如何使用JavaScript删除DOM节点的所有子元素?
- 用零知识证明连接多链宇宙
- 模电之半导体基础篇1(本征半导体、杂质半导体)
- cocos3.4 使用quic-src报错:duplicate symbol _MD5_Final in:
- 网页出现503 service unavailable是什么意思?怎么解决?
热门文章
- 优思学院|什么是六西格玛黑带?
- 软件系统分析-餐饮管理系统
- win10引导安卓x86_如何双重启动Windows10与Android双系统
- .NET开发工程师自我评价简历范文
- Flash开发工具 FlashDevelop
- 亚航一架从印度尼西亚飞往新加坡的客机失联
- iOS 调用支付宝 显示系统繁忙,请稍后再试(ALI10
- 【单片机笔记】基于XL4015的可调电源
- JS 方法名 起名要谨慎
- python发微信红包群二维码_小伙利用Python群发“支付宝”红包短信,一天赏金可达上千元...