【物联网】基于立创EDA与鸿蒙系统的WIFI智能开关设计与实现

发布时间:2026/7/5 4:27:07

【物联网】基于立创EDA与鸿蒙系统的WIFI智能开关设计与实现 从零到一手把手教你做一个鸿蒙WIFI智能开关最近有不少朋友问我想自己动手做一个能远程控制的智能开关比如躺在床上就能关灯或者出门后检查家里的电器有没有关。这种需求在智能家居里太常见了。今天我就带大家从硬件设计到软件编程完整地走一遍流程做一个基于鸿蒙系统的WIFI智能开关。咱们这个项目会用到两个核心工具立创EDA来画电路板鸿蒙系统来写控制程序。整个过程我会尽量讲得详细即使你是刚接触嵌入式或者物联网的新手跟着步骤走也能做出自己的作品。最终实现的效果就是通过手机App或者网页无论你在家还是在外都能控制这个开关的通断。1. 项目整体规划与硬件选型做任何嵌入式项目第一步不是急着画图写代码而是先想清楚我们要做什么需要哪些东西。这就像盖房子先画图纸一样。我们这个WIFI智能开关核心功能很简单接收来自互联网的指令控制一个220V交流电的通断。听起来简单但拆解开来需要几个关键部分主控芯片负责运行程序、连接网络、处理指令。这是项目的大脑。WIFI模块让设备能接入家里的路由器连接互联网。继电器模块这是控制强电220V的关键部件。主控芯片输出一个微弱的低电压信号比如3.3V给继电器继电器内部的电磁铁会吸合从而接通或断开强电电路。安全第一强电部分必须隔离电源模块给主控芯片、WIFI模块和继电器供电。通常需要将220V交流电转换成安全的直流低压比如5V或3.3V。其他外围电路比如按键用于本地手动控制、状态指示灯、必要的电阻电容等。基于鸿蒙系统的开发目前比较成熟的硬件平台是海思的Hi3861系列WIFI模组。它集成了主控ARM Cortex-M4内核和WIFI功能于一体性价比高鸿蒙对它的支持也最完善。所以我们选择Hi3861作为本次项目的核心。注意涉及220V强电操作有触电风险如果你是第一次接触强电建议先用低压直流电器如12V的LED灯条、小风扇来模拟和测试等完全熟悉了继电器控制逻辑后再考虑接入家庭电路。操作时务必断电接线安全永远第一位。2. 使用立创EDA设计硬件电路确定了核心芯片接下来就用立创EDA来设计我们的电路板。立创EDA是在线工具免费且好用特别适合初学者和快速原型开发。2.1 创建工程与原理图设计首先去立创EDA官网注册账号创建一个新工程命名为“鸿蒙WIFI智能开关”。第一步添加核心元件Hi3861模组。在立创EDA的元件库中搜索“Hi3861”通常能找到已经画好的模块封装。Hi3861模组引脚较多但我们只需要关注几个关键引脚3.3V 和 GND电源和地。GPIO引脚用于控制继电器和读取按键状态。例如我们分配GPIO9控制继电器GPIO7连接轻触按键。串口引脚UART0用于下载程序和输出调试信息。TX接USB转串口工具的RXRX接USB转串口工具的TX。第二步设计电源电路。因为我们最终要控制220V所以板子上需要集成一个将220V交流AC转为5V或3.3V直流DC的电源模块。为了安全简化我们可以先使用一个220V转5V的隔离电源模块成品模块如HLK-5M05再通过一个低压差线性稳压器LDO将5V转为3.3V给Hi3861供电。 在原理图中放置这个电源模块和LDO芯片如AMS1117-3.3并连接好输入输出的滤波电容。第三步添加继电器驱动电路。Hi3861的GPIO引脚驱动能力有限通常几个mA无法直接驱动继电器线圈需要几十mA。所以我们需要一个“驱动电路”通常用一个NPN三极管如S8050或者一个MOS管来实现。Hi3861的GPIO9连接一个1kΩ的限流电阻到三极管的基极B。三极管的发射极E接地GND。继电器线圈一端接5V电源另一端接三极管的集电极C。务必在继电器线圈两端并联一个续流二极管如1N4148阴极接5V阳极接三极管集电极。这个二极管非常重要用于吸收继电器断开时线圈产生的反向电动势保护三极管不被击穿。第四步添加按键和指示灯。按键轻触按键一端接GPIO7和通过一个10kΩ的上拉电阻接到3.3V另一端接地。当按键按下时GPIO7被拉低到地程序就能检测到低电平。指示灯一个LED串联一个220Ω的限流电阻接到另一个GPIO如GPIO10和地之间用于指示网络状态或开关状态。画好的原理图局部示意图核心部分应该类似这样文字描述[220V AC输入] - [HLK-5M05隔离电源模块] - [5V DC] [5V DC] - [AMS1117-3.3 LDO] - [3.3V DC] - [Hi3861 VCC] [Hi3861 GPIO9] - [1kΩ电阻] - [S8050基极(B)] [S8050发射极(E)] - [GND] [5V DC] - [继电器线圈] - [继电器线圈-] - [S8050集电极(C)] [继电器线圈两端并联1N4148二极管] [Hi3861 GPIO7] - [10kΩ上拉电阻到3.3V] - [轻触按键] - [GND]2.2 PCB布局与布线原理图检查无误后点击“设计”-“转换到PCB”。这时所有元件会出现在PCB编辑区。布局原则电源部分放板子入口处先经过隔离电源模块再到LDO。强电走线与弱电走线严格分开220V交流输入部分和继电器输出部分要与Hi3861所在的低压直流部分保持足够距离建议3mm以上最好在中间开一条隔离槽。Hi3861模组放在板子中央周围放置其相关的按键、指示灯、下载接口。继电器和三极管驱动电路靠近板子边缘方便接线端子接入强电。布线原则电源线VCC、GND要粗。特别是GND尽量使用铺铜覆铜的方式连接保证地平面完整能提高抗干扰能力。信号线如GPIO到电阻的线可以细一些10mil左右。避免直角走线使用45度角或圆弧。布线完成后运行一下设计规则检查DRC确保没有短路、间距过小等问题。3. 鸿蒙系统软件编程硬件设计好后可以发出去打样我们就可以先着手编写软件了。鸿蒙系统的开发环境是DevEco Device Tool我们主要用C语言进行开发。3.1 搭建开发环境与创建工程安装VSCode然后在插件市场搜索并安装“DevEco Device Tool”。配置工具链和编译路径通常工具会自动配置或提供指引。新建一个Hi3861的工程命名为wifi_switch。工程创建好后我们主要关心applications/sample/wifi-iot/app目录下的iothardware文件夹我们在这里添加自己的代码。3.2 编写GPIO控制代码首先我们要初始化用来控制继电器和按键的GPIO引脚。创建一个switch_control.c文件#include ohos_init.h #include cmsis_os2.h #include hi_gpio.h #include hi_io.h #include hi_adc.h #include stdio.h // 定义引脚号根据你的原理图连接来修改 #define RELAY_GPIO 9 // 控制继电器的GPIO #define KEY_GPIO 7 // 按键GPIO #define LED_GPIO 10 // 状态指示灯GPIO // 继电器状态0断开1吸合 static volatile uint8_t g_relay_state 0; // GPIO初始化函数 static void GpioInit(void) { // 初始化继电器控制引脚为输出模式 hi_gpio_init(); hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO); // 设置引脚功能为GPIO hi_gpio_set_dir(RELAY_GPIO, HI_GPIO_DIR_OUT); // 设置为输出方向 hi_gpio_set_ouput_val(RELAY_GPIO, HI_GPIO_VALUE0); // 默认输出低电平继电器断开 // 初始化按键引脚为输入模式带上拉 hi_io_set_func(HI_IO_NAME_GPIO_7, HI_IO_FUNC_GPIO_7_GPIO); hi_gpio_set_dir(KEY_GPIO, HI_GPIO_DIR_IN); hi_io_set_pull(HI_IO_NAME_GPIO_7, HI_IO_PULL_UP); // 使能内部上拉电阻 // 初始化LED指示灯引脚为输出模式 hi_io_set_func(HI_IO_NAME_GPIO_10, HI_IO_FUNC_GPIO_10_GPIO); hi_gpio_set_dir(LED_GPIO, HI_GPIO_DIR_OUT); hi_gpio_set_ouput_val(LED_GPIO, HI_GPIO_VALUE1); // 默认高电平LED熄灭低电平点亮 } // 控制继电器函数 static void RelaySet(uint8_t state) { if (state) { hi_gpio_set_ouput_val(RELAY_GPIO, HI_GPIO_VALUE1); // 输出高电平三极管导通继电器吸合 printf(Relay ON\n); g_relay_state 1; hi_gpio_set_ouput_val(LED_GPIO, HI_GPIO_VALUE0); // LED点亮指示开启状态 } else { hi_gpio_set_ouput_val(RELAY_GPIO, HI_GPIO_VALUE0); // 输出低电平继电器断开 printf(Relay OFF\n); g_relay_state 0; hi_gpio_set_ouput_val(LED_GPIO, HI_GPIO_VALUE1); // LED熄灭 } } // 按键扫描任务函数 static void KeyScanTask(void *arg) { (void)arg; uint8_t key_last 1; // 上次按键状态默认高电平未按下 uint8_t key_current; while (1) { hi_gpio_get_input_val(KEY_GPIO, key_current); // 读取当前按键电平 // 检测按键按下下降沿从高电平1变为低电平0 if ((key_last 1) (key_current 0)) { osDelay(20); // 简单延时消抖 hi_gpio_get_input_val(KEY_GPIO, key_current); // 再次读取 if (key_current 0) { // 确认按下 printf(Key Pressed!\n); RelaySet(!g_relay_state); // 切换继电器状态 } } key_last key_current; // 更新上次状态 osDelay(10); // 每10ms扫描一次按键 } } // 主任务入口函数 static void SwitchMainTask(void *arg) { (void)arg; printf(WIFI Smart Switch Start!\n); GpioInit(); // 初始化GPIO // 创建按键扫描任务 osThreadAttr_t attr {0}; attr.name KeyScanTask; attr.stack_size 1024; attr.priority osPriorityNormal; if (osThreadNew(KeyScanTask, NULL, attr) NULL) { printf(Failed to create KeyScanTask!\n); } // 主任务可以在这里初始化WIFI等然后挂起或执行其他逻辑 while (1) { // 主循环可以添加其他功能 osDelay(1000); } } // 使用OpenHarmony的启动入口注册任务 APP_FEATURE_INIT(SwitchMainTask);这段代码做了几件事GpioInit函数初始化了三个GPIO。RelaySet函数是核心通过给RELAY_GPIO输出高/低电平来控制继电器的开合同时用LED灯指示状态。KeyScanTask是一个独立的任务不断扫描按键。当检测到按键被按下时就调用RelaySet切换开关状态。这里用了简单的延时消抖防止按键抖动误触发。SwitchMainTask是主任务初始化硬件并创建按键扫描任务。3.3 集成WIFI连接与网络控制光是本地按键控制还不够我们的目标是远程控制。这就需要让Hi3861连接到家里的WIFI并创建一个网络服务来接收指令。鸿蒙系统提供了完善的WIFI和网络套接字SocketAPI。我们可以在主任务里添加WIFI连接逻辑并创建一个TCP服务器。在SwitchMainTask函数的初始化部分加入WIFI连接代码需要你先知道自家的WIFI名称和密码#include hi_wifi_api.h static void ConnectToWifi(void) { hi_wifi_auth_info auth_info {0}; int ret; // 设置WIFI连接参数 strcpy_s(auth_info.ssid, sizeof(auth_info.ssid), Your_WIFI_SSID); // 你的WIFI名称 strcpy_s(auth_info.key, sizeof(auth_info.key), Your_WIFI_Password); // 你的WIFI密码 auth_info.auth_type HI_WIFI_SECURITY_WPA2PSK; // 加密方式一般是WPA2 auth_info.cipher_type HI_WIFI_CIPHER_TYPE_AES; // 发起连接 ret hi_wifi_sta_connect(auth_info); if (ret HISI_OK) { printf(WIFI Connecting...\n); osDelay(3000); // 等待连接完成 // 可以在这里获取IP地址并打印 hi_wifi_link_info info; hi_wifi_sta_get_link_info(info); printf(WIFI Connected! IP: %s\n, info.ip_addr); } else { printf(WIFI Connect Failed: %d\n, ret); } }然后在SwitchMainTask中GpioInit()之后调用ConnectToWifi()。接下来我们创建一个TCP服务器任务监听某个端口比如8080等待手机App或电脑客户端发来的控制指令。#include netinet/in.h #include sys/socket.h #include arpa/inet.h #define CONTROL_PORT 8080 // TCP服务器任务函数 static void TcpServerTask(void *arg) { (void)arg; int server_fd, client_fd; struct sockaddr_in server_addr, client_addr; socklen_t client_len sizeof(client_addr); char buffer[128]; // 1. 创建socket server_fd socket(AF_INET, SOCK_STREAM, 0); if (server_fd 0) { printf(Socket creation failed\n); return; } // 2. 绑定地址和端口 server_addr.sin_family AF_INET; server_addr.sin_addr.s_addr INADDR_ANY; // 监听所有本地IP server_addr.sin_port htons(CONTROL_PORT); if (bind(server_fd, (struct sockaddr *)server_addr, sizeof(server_addr)) 0) { printf(Bind failed\n); close(server_fd); return; } // 3. 开始监听 if (listen(server_fd, 1) 0) { // 允许一个连接排队 printf(Listen failed\n); close(server_fd); return; } printf(TCP Server started on port %d\n, CONTROL_PORT); while (1) { // 4. 接受客户端连接 client_fd accept(server_fd, (struct sockaddr *)client_addr, client_len); if (client_fd 0) { printf(Accept failed\n); continue; } printf(Client connected\n); // 5. 与客户端通信 while (1) { memset(buffer, 0, sizeof(buffer)); int len recv(client_fd, buffer, sizeof(buffer)-1, 0); if (len 0) { printf(Client disconnected or error\n); break; } buffer[len] \0; printf(Received: %s\n, buffer); // 6. 解析指令并控制继电器 if (strcmp(buffer, ON) 0) { RelaySet(1); send(client_fd, Switch ON OK\n, 13, 0); } else if (strcmp(buffer, OFF) 0) { RelaySet(0); send(client_fd, Switch OFF OK\n, 14, 0); } else if (strcmp(buffer, STATUS) 0) { char status_msg[32]; snprintf(status_msg, sizeof(status_msg), Current Status: %s\n, g_relay_state ? ON : OFF); send(client_fd, status_msg, strlen(status_msg), 0); } else { send(client_fd, Unknown Command\n, 16, 0); } } close(client_fd); } close(server_fd); }最后别忘了在SwitchMainTask里创建这个TCP服务器任务// 创建TCP服务器任务 osThreadAttr_t tcp_attr {0}; tcp_attr.name TcpServerTask; tcp_attr.stack_size 4096; // 网络任务需要稍大的栈空间 tcp_attr.priority osPriorityNormal; if (osThreadNew(TcpServerTask, NULL, tcp_attr) NULL) { printf(Failed to create TcpServerTask!\n); }现在代码就具备了本地按键控制按下按键开关状态切换。WIFI连接上电后自动连接指定WIFI。网络远程控制设备启动TCP服务器后你可以在同一局域网内用手机上的TCP调试助手App或者电脑上的网络调试工具如NetAssist连接设备IP的8080端口发送ON、OFF、STATUS指令来控制或查询开关状态。4. 烧录、测试与下一步编译代码在DevEco Device Tool中选择Hi3861开发板配置点击编译。确保没有错误。硬件连接将Hi3861模组通过USB转串口工具连接到电脑。确保接线正确TX-RX交叉共地。烧录程序在工具中选择烧录等待完成。上电测试先不接强电用万用表测量继电器输出端在发送ON/OFF指令时听继电器是否有“咔嗒”声同时万用表通断档应显示通/断变化。测试按键功能是否正常。测试WIFI连接和TCP指令控制是否正常。接入强电谨慎确认所有低压功能正常后断开总闸将继电器的公共端COM和常开端NO串联到你想控制的灯具或电器的火线中。接线务必牢固用绝缘胶布包好。然后上电测试。至此一个基础版的鸿蒙WIFI智能开关就完成了。你可以把它装进一个绝缘的塑料盒里就是一个实用的小设备。当然这只是一个起点。在此基础上你还可以继续深化开发手机App用鸿蒙的原子化服务或者JS UI框架做一个漂亮的手机控制界面。接入云平台让开关能通过互联网远程控制而不仅仅在局域网内。可以研究华为IoT云或其他物联网云平台。增加功能比如定时开关、电量统计需要电流传感器、多路控制等。这个项目麻雀虽小五脏俱全涵盖了物联网设备的硬件设计、嵌入式编程、网络通信等核心环节。希望这个详细的教程能帮你打通从想法到实物的道路。遇到问题别怕多查资料调试的过程本身就是最好的学习。祝你成功

相关新闻