11浏览
查看: 11|回复: 8

[K10教程] 【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息

[复制链接]
【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图2

行空板K10是一款专为快速体验物联网和学习人工智能而设计的开发学习板,100%采用国产芯片,知识产权自主可控,符合信息科技课程中编程学习、物联网及人工智能等教学需求。该板集成2.8寸LCD彩屏、WiFi蓝牙、摄像头、麦克风、扬声器、RGB指示灯、多种传感器及丰富的扩展接口。凭借高度集成的板载资源,教学过程中无需额外连接其他设备,便可轻松实现传感器控制、物联网应用以及人脸识别、语音识别、语音合成等AI人工智能项目。

主要特点
集成摄像头&内置算法,可进行离线图像检测
集成麦克风&内置算法,可进行离线语音识别
集成扬声器&内置算法,可进行离线语音合成
2.8寸彩色屏幕,数据展示更清晰
集成度高,利于教学
接口丰富,兼容软件多,扩展性好


【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图1

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】K10实验之UDP广播双K10双向通信屏显消息

行空板K10的网络服务模块,都在这里

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图1

添加WIFI和UDP广播模块

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图3

相关积木

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图2

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图4


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】K10实验之UDP广播双K10双向通信屏显消息

辅助:屏幕显示相关积木

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图2

LED控制模块

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图1


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】K10实验之UDP广播双K10双向通信屏显消息

知识点:行空板 K10 WiFi 局域网 UDP 广播

一、UDP 基础概念
UDP 全称用户数据报协议,属于 TCP/IP 网络协议,是无连接、广播式、尽力传输的通信方式。
放到行空板场景:所有设备连同一个 WiFi 路由器,组成局域网,依靠 IP + 端口收发数据;支持一台发送、全网所有设备同时接收,也就是 UDP 广播。
和 TCP 最大区别:不用提前握手建立连接,发消息直接抛到局域网里,速度快、代码简单,但不自动重传丢包数据。

二、运行硬性前提(必须满足)
全部通信行空板 K10 连接同一个 WiFi 热点;
设备自动获取同一段内网 IP(常见 192.168.4.xxx、192.168.1.xxx);
通信双方设置完全一致的端口号(截图示例固定 8888);
程序开头必须先执行 WiFi 配网连接,没连上 WiFi,UDP 模块无法启动。

三、相关图形积木功能解析
1. 基础服务端积木
设置 UDP 服务器端口 8888
本机开启 UDP 监听服务,占用 8888 端口,持续等候局域网内所有广播数据包。一块板子可同时做服务端 + 客户端。
当 UDP 服务器收到 广播消息
事件回调块:一旦局域网内有设备发出广播数据,立刻触发内部执行逻辑(点灯、屏幕打印、动作指令)。
UDP 服务器发送消息 "xxx"
向外发送全网广播包,当前 WiFi 局域网里所有开启 UDP 8888 端口的设备全部收到这条内容。
2. 基础客户端积木
设置 UDP 客户端连接到服务器 IP 192.168.4.1 端口 8888
客户端绑定目标服务端的内网 IP 与端口,建立通信目标;广播场景下 IP 可填局域网广播地址,实现一对多群发。
UDP 客户端发送消息 "xxx"
两种用法:①定向发给上面填写的单个服务器 IP;②发送全网广播,所有同端口设备接收。
当 UDP 客户端收到 广播消息
客户端独立监听广播数据包,收到数据后执行内部程序逻辑。

四、两种常用工作模式
模式 1:一对多广播(教学最常用)
1 块主控发送,N 台从板同步接收动作
主控(发送端):WiFi 联网 → UDP 开启 8888 端口 → 按键 / 陀螺仪触发「服务器发送消息」;
所有从板:WiFi 连同一个热点 → UDP 端口 8888 → 绑定「收到广播消息」回调,识别指令点灯、动作;
特点:一块板子下发指令,几十台设备同步响应。
模式 2:点对点双向通信
A 板客户端连 B 板服务端 IP,双向互发消息,适合一问一答、状态回传(比如小车上报速度、传感器数值回传给主控)。

五、完整积木程序标准结构
发送主控模板
【连接 WiFi】填入 WiFi 名称、密码(第一步必加)
【设置 UDP 服务器端口 8888】
循环 / 按键触发:【UDP 服务器发送消息 "hong"】
接收从板模板
【连接 WiFi】同一个 WiFi 账号密码
【设置 UDP 服务器端口 8888】
【当 UDP 服务器收到广播消息】
判断收到文本,匹配hong/bai/qian等指令,执行 RGB 变色、屏幕文字。

六、UDP 核心优缺点
优点
天然一对多广播:一次发送全网同端口设备接收,批量控制效率高;
速度快延迟低:无握手、无校验重传,体感几乎无卡顿;
兼容多设备:行空板、电脑、手机、ESP32 全都能互通;
数据承载量大:相比离线 Radio 射频,UDP 支持长文本、大量传感器数值、中等长度数据流;
覆盖范围广:路由器 WiFi 全屋覆盖,穿墙能力优于 2.4G 私有射频。
缺点
强依赖 WiFi 网络:无路由器、无 WiFi 环境完全无法运行,户外断电场景不能用;
无可靠传输:干扰、信号弱时会丢包,没有自动补发;稳定场景可重复发送 2 次指令;
功耗更高:WiFi 模块持续通电工作,电池续航比离线 Radio 短;
多组隔离麻烦:多小组实验要分不同 WiFi 热点才能互不干扰,不像 Radio 简单改 Group 数字。

七、实操避坑关键点
WiFi 必须一模一样:发送、接收板子 WiFi 名称、密码完全一致,大小写不能错;
端口号统一:所有设备 UDP 端口必须都是 8888,数字不同收不到;
广播无需精准匹配单个 IP:发全网广播时不用填每台从板 IP,局域网全部 8888 端口设备自动接收;
不要超大段文本发送,过长数据包容易分包乱码;
程序逻辑里不要加超长delay(),会阻塞 UDP 消息监听;
路由器 2.4G WiFi 稳定性优于 5G,行空板优先连 2.4G 频段。

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图1

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图2

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】K10实验之UDP广播双K10双向通信屏显消息

局域网(Local Area Network,简称LAN)是一种在相对较小的地理范围(如一个办公室、一栋楼或者一个校园)内连接计算机和其他设备的计算机网络系统。局域网的特点是覆盖范围小、传输速度快、没有长距离通信费用。

在局域网中,用户可以共享硬件(如打印机)、软件和数据。局域网中的设备可以通过有线(如以太网)或无线(如Wi-Fi)技术连接。局域网的主要用途包括共享资源、传输数据和通信。

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图1

以行空板为例进行组网。

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图2

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图3

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】K10实验之UDP广播双K10双向通信屏显消息

【花雕动手做】行空板K10系列实验之UDP广播双向通信屏幕显示接收消息且点亮LED
实验开源代码(UDP广播服务器)

  1. // 引入DF官方物联网WiFi驱动库,用于开启自建SoftAP热点、读取热点网关IP地址
  2. #include <DFRobot_Iot.h>
  3. // 行空板K10整机硬件驱动库,封装屏幕、画布、A按键、RGB彩灯等全部板载外设
  4. #include "unihiker_k10.h"
  5. // WiFi UDP服务端专用库,实现标准局域网UDP端口监听、接收客户端数据包、广播发送消息
  6. #include <DFRobot_UDPServer.h>
  7. // 前置声明两个事件回调函数,编译器预识别函数标识,用于绑定按键按下、UDP消息接收动作
  8. void onButtonAPressed();
  9. void onUdpServerRecvMsg(String message);
  10. // 行空板K10全局硬件总控制对象,统一调度屏幕、按键、RGB灯、绘图画布硬件资源
  11. UNIHIKER_K10      k10;
  12. // 屏幕显示朝向配置参数3,可根据设备实际摆放角度翻转画面显示方向
  13. uint8_t           screen_dir=3;
  14. // WiFi物联网管理实例,负责热点开启、无线参数配置、IP地址读取
  15. DFRobot_Iot       myIot;
  16. // UDP服务端通信实例,开启端口监听、绑定接收回调、向局域网广播UDP消息
  17. DFRobot_UDPServer myserver;
  18. // 全局字符串缓存变量:专门存储UDP回调接收到的消息
  19. // 核心规范:网络回调禁止操作屏幕,仅把数据存入缓存,屏幕渲染全部放到主线程loop
  20. String recv_message = "";
  21. // RGB灯光非阻塞计时时间戳,用来替代危险的阻塞delay()
  22. unsigned long rgb_start_time = 0;
  23. // RGB灯光状态标记位:true=灯需要点亮计时,false=灯熄灭待机
  24. bool rgb_light_status = false;
  25. /**
  26. * setup:上电仅执行一次的硬件初始化入口函数
  27. * 强制执行顺序:硬件屏幕初始化→画布创建→绑定事件回调→绘制静态界面→开启WiFi热点→刷新界面→启动UDP监听端口
  28. * 严禁颠倒屏幕与WiFi/UDP初始化顺序,防止总线资源抢占导致黑屏
  29. */
  30. void setup() {
  31.     // 第一步:初始化K10全部底层硬件总线、屏幕驱动、按键IO、RGB驱动、系统时钟
  32.         k10.begin();
  33.         // 根据预设参数3初始化屏幕翻转方向
  34.         k10.initScreen(screen_dir);
  35.         // 创建内存绘图画布缓冲区,文字先写入缓存再整体刷新,减少屏幕画面闪烁撕裂
  36.         k10.creatCanvas();
  37.         // 给UDP服务端绑定消息接收回调:后台监听到客户端UDP数据包,自动执行onUdpServerRecvMsg
  38.         myserver.setCallback(onUdpServerRecvMsg);
  39.         // 给板载A物理按键绑定按下中断回调:按下A键立刻运行发送广播消息函数
  40.         k10.buttonA->setPressedCallback(onButtonAPressed);
  41.         // 设置屏幕整体背景底色为纯白色 0xFFFFFF
  42.         k10.setScreenBackground(0xFFFFFF);
  43.         // 在画布第3行写入红色标题文字,标记本机身份为UDP服务端
  44.         k10.canvas->canvasText("        行空板K10-服务器", 3, 0xFF0000);
  45.         // 开启本机SoftAP无线热点模式,本机变身小型无线路由器
  46.         // 热点名称:AP ;连接密码:88888888
  47.         myIot.setSoftAP("AP", "88888888");
  48.         // 拼接字符串,读取本机热点固定网关IP地址,存入文本变量
  49.         String ip_text = "   本机热点IP:" + String(myIot.getWiFiSoftIP());
  50.         // 画布第5行用蓝色字体打印本机热点IP
  51.         k10.canvas->canvasText(ip_text, 5, 0x0000FF);
  52.         // 第一次批量刷新画布缓存,把标题、IP文字渲染显示到实体屏幕
  53.         k10.canvas->updateCanvas();
  54.         // UDP服务端开启8888端口,持续监听局域网内所有客户端发来的UDP数据包
  55.         myserver.setPort(8888);
  56. }
  57. /**
  58. * loop:程序无限主线循环
  59. * 所有屏幕绘制刷新、灯光延时逻辑全部放在主线程,保证屏幕稳定渲染
  60. * UDP网络、按键由后台反文旁虫立线程驱动,loop只做界面刷新与状态轮询
  61. */
  62. void loop() {
  63.     // ========== 模块1:主线程安全刷新屏幕,展示UDP接收消息 ==========
  64.         // 判断缓存内是否存有未展示的客户端消息
  65.         if (recv_message != "")
  66.         {
  67.                 // 清空画布所有旧绘制内容
  68.                 k10.canvas->canvasClear();
  69.                 // 重新还原屏幕白色底色
  70.                 k10.setScreenBackground(0xFFFFFF);
  71.                 // 重绘顶部服务端标题
  72.                 k10.canvas->canvasText("        行空板K10-服务器", 3, 0xFF0000);
  73.                 // 重新拼接本机IP文本
  74.                 String ip_text = "   本机热点IP:" + String(myIot.getWiFiSoftIP());
  75.                 k10.canvas->canvasText(ip_text, 5, 0x0000FF);
  76.                 // 在画布第7行用绿色字体打印客户端发送过来的完整消息
  77.                 k10.canvas->canvasText("收到客户端:" + recv_message, 7, 0x00AA00);
  78.                 // 批量刷新整屏文字,一次性渲染到屏幕
  79.                 k10.canvas->updateCanvas();
  80.                 // 清空消息缓存,防止重复循环刷屏
  81.                 recv_message = "";
  82.         }
  83.         // ========== 模块2:非阻塞方式控制RGB彩灯,无delay不阻塞网络线程 ==========
  84.         // 判断灯光标记为开启,且点亮时长已经超过2000毫秒(2秒)
  85.         if (rgb_light_status && millis() - rgb_start_time > 2000)
  86.         {
  87.                 // 全部RGB灯珠赋值黑色,熄灭彩灯
  88.                 k10.rgb->write(-1, 0x000000);
  89.                 // 关闭灯光状态标记,等待下一次消息触发
  90.                 rgb_light_status = false;
  91.         }
  92. }
  93. /**
  94. * UDP服务端消息接收回调函数
  95. * 安全规范:仅允许赋值全局缓存、控制RGB灯;禁止任何画布绘制、屏幕刷新、长延时delay
  96. * 入参message:客户端传输过来的完整字符串数据包内容
  97. */
  98. void onUdpServerRecvMsg(String message) {
  99.         // 1、把客户端消息存入全局缓存,交给主线程loop去屏幕展示
  100.         recv_message = message;
  101.         // 2、标记灯光需要点亮计时
  102.         rgb_light_status = true;
  103.         // 记录当前系统毫秒时间戳,作为灯光计时起点
  104.         rgb_start_time = millis();
  105.         // 参数-1代表控制全部板载RGB灯珠,点亮浅青蓝色作为收到消息提示
  106.         k10.rgb->write(-1, 0x33FFFF);
  107. }
  108. /**
  109. * A按键按下专属回调函数
  110. * 触发动作:按下A键,向所有连接本热点、监听8888端口的设备广播发送UDP文本消息
  111. */
  112. void onButtonAPressed() {
  113.         // 广播发送字符串:hello,I am server
  114.         myserver.sendUdpMsg("hello,I am server");
  115. }
复制代码


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】K10实验之UDP广播双K10双向通信屏显消息

行空板 K10 UDP 自建热点服务端代码解读

一、头文件与全局变量区

  1. // DFR物联网WiFi库:实现开启AP热点、读取本机热点IP、WiFi资源管理
  2. #include <DFRobot_Iot.h>
  3. // K10硬件驱动库:管控屏幕、画布、A按键、RGB灯全部板载外设
  4. #include "unihiker_k10.h"
  5. // WiFi UDP服务端库:搭建UDP监听端口、接收客户端消息、广播下发数据
  6. #include <DFRobot_UDPServer.h>
  7. // 提前声明两个事件回调函数,供编译器识别绑定
  8. void onButtonAPressed();
  9. void onUdpServerRecvMsg(String message);
  10. // 整机硬件控制总对象
  11. UNIHIKER_K10      k10;
  12. // 屏幕翻转方向参数3,适配设备摆放角度
  13. uint8_t           screen_dir=3;
  14. // WiFi热点管理实例
  15. DFRobot_Iot       myIot;
  16. // UDP服务端通信实例
  17. DFRobot_UDPServer myserver;
  18. // 全局字符串缓存:接收UDP消息中转站
  19. // 关键规则:网络后台回调禁止操作屏幕,只把数据存这里,屏幕渲染交给主线程loop
  20. String recv_message = "";
  21. // 毫秒时间戳,用来做灯光非阻塞计时,替换阻塞delay
  22. unsigned long rgb_start_time = 0;
  23. // 灯光开关标记位
  24. bool rgb_light_status = false;
复制代码


二、setup () 开机一次性初始化

  1. void setup() {
  2.     // 【强制第一行】初始化全部硬件底层(屏幕、按键、RGB、系统总线)
  3.         k10.begin();
  4.         // 设置屏幕显示翻转角度
  5.         k10.initScreen(screen_dir);
  6.         // 创建绘图画布缓存,文字批量刷新减少闪屏
  7.         k10.creatCanvas();
  8.         // 给UDP绑定接收回调:后台收到数据包自动运行onUdpServerRecvMsg
  9.         myserver.setCallback(onUdpServerRecvMsg);
  10.         // A按键绑定按下中断:按A自动执行发送消息函数
  11.         k10.buttonA->setPressedCallback(onButtonAPressed);
  12.         // 设置屏幕底色为纯白色
  13.         k10.setScreenBackground(0xFFFFFF);
  14.         // 画布第3行红色标题,标记本机为UDP服务端
  15.         k10.canvas->canvasText("        行空板K10-服务器", 3, 0xFF0000);
  16.         // 开启本机WiFi热点(SoftAP模式,板子变身小型路由器)
  17.         // 热点名:AP  连接密码:88888888
  18.         myIot.setSoftAP("AP", "88888888");
  19.         // 拼接IP文本,读取本机热点默认网关IP(固定192.168.4.1)
  20.         String ip_text = "   本机热点IP:" + String(myIot.getWiFiSoftIP());
  21.         // 第5行蓝色字体打印IP地址
  22.         k10.canvas->canvasText(ip_text, 5, 0x0000FF);
  23.         // 第一次刷新画布,把标题、IP显示到屏幕
  24.         k10.canvas->updateCanvas();
  25.         // UDP开启8888端口,持续监听客户端数据包
  26.         myserver.setPort(8888);
  27. }
复制代码


三、loop () 主线无限循环(屏幕、灯光全部在这里处理)

v
  1. oid loop() {
  2.     // 模块1:主线程安全刷新屏幕,打印收到的UDP消息
  3.         if (recv_message != "")
  4.         {
  5.                 // 清空旧画布内容
  6.                 k10.canvas->canvasClear();
  7.                 // 重置白色背景
  8.                 k10.setScreenBackground(0xFFFFFF);
  9.                 // 重绘顶部标题
  10.                 k10.canvas->canvasText("        行空板K10-服务器", 3, 0xFF0000);
  11.                 // 重绘本机IP文字
  12.                 String ip_text = "   本机热点IP:" + String(myIot.getWiFiSoftIP());
  13.                 k10.canvas->canvasText(ip_text, 5, 0x0000FF);
  14.                 // 第7行绿色文字,打印客户端发来的原始消息
  15.                 k10.canvas->canvasText("收到客户端:" + recv_message, 7, 0x00AA00);
  16.                 // 整批刷新所有文字到屏幕
  17.                 k10.canvas->updateCanvas();
  18.                 // 清空缓存,防止循环重复刷屏
  19.                 recv_message = "";
  20.         }
  21.         // 模块2:非阻塞延时控制RGB灯,无delay、不卡住网络线程
  22.         // 判断灯处于点亮状态,且点亮时长超2秒
  23.         if (rgb_light_status && millis() - rgb_start_time > 2000)
  24.         {
  25.                 // 熄灭全部RGB灯珠
  26.                 k10.rgb->write(-1, 0x000000);
  27.                 // 关闭灯光标记
  28.                 rgb_light_status = false;
  29.         }
  30. }
复制代码


四、两个回调函数(后台事件触发,严格遵守安全规范)
1、UDP 消息接收回调

  1. void onUdpServerRecvMsg(String message) {
  2.         // 仅做两件安全操作:存消息、开灯;不碰屏幕、不加长delay
  3.         recv_message = message;          // 消息存入全局缓存,交给loop渲染屏幕
  4.         rgb_light_status = true;
  5.         rgb_start_time = millis();       // 记录开灯起始时间
  6.         k10.rgb->write(-1, 0x33FFFF);    // -1=全部RGB,点亮浅青色提示灯
  7. }
复制代码

2、A 按键按下回调

  1. void onButtonAPressed() {
  2.         // 向所有连接本热点、监听8888端口的设备广播消息
  3.         myserver.sendUdpMsg("hello,I am server");
  4. }
复制代码


核心解决痛点(屏幕不显示消息的关键优化)
1、线程分离,杜绝屏幕卡死
UDP 接收运行在 WiFi 后台子线程,屏幕绘制只能放在主线程loop;回调里完全禁止canvasText/updateCanvas,避免 SPI 屏幕总线被网络线程抢占黑屏。
2、取消阻塞 delay
旧代码回调里delay(2000)会冻结 UDP 监听,改用millis()时间戳在 loop 里关灯,网络全程畅通。
3、初始化顺序锁死
先k10.begin()初始化屏幕硬件,后开 WiFi/UDP;颠倒顺序会直接屏幕驱动初始化失败、黑屏无画面。
4、消息缓存机制
收到数据先存字符串变量,主线程检测到有新消息再统一重绘整屏,画面稳定无撕裂。
5、配对组网运行逻辑
本设备 = UDP 服务端 + WiFi 热点发射器,IP 固定192.168.4.1,端口 8888;
客户端板子连接热点AP、密码88888888,UDP 客户端连接192.168.4.1:8888;
客户端按 A 发送hello,I am client → 服务端屏幕打印这条文字 + RGB 亮 2 秒浅青灯;
服务端按 A 广播hello,I am server,客户端可配套做灯光 / 屏幕反馈。

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】K10实验之UDP广播双K10双向通信屏显消息

【花雕动手做】行空板K10系列实验之UDP广播双向通信屏幕显示接收消息且点亮LED
实验开源代码(UDP广播客户端)

  1. // 引入DF官方物联网WiFi库,负责连接指定WiFi热点、读取本机局域网IP、检测WiFi联网状态
  2. #include <DFRobot_Iot.h>
  3. // 行空板K10硬件驱动总库,封装屏幕、画布、A按键、RGB彩灯全部板载外设驱动接口
  4. #include "unihiker_k10.h"
  5. // WiFi标准UDP客户端专用库,实现主动连接UDP服务端、发送数据包、绑定消息接收回调
  6. #include <DFRobot_UDPClient.h>
  7. // 行空板整机硬件控制全局对象,统一管理屏幕、按键、RGB灯、绘图画布硬件资源
  8. UNIHIKER_K10      k10;
  9. // 屏幕显示翻转方向参数3,可根据设备摆放角度调整画面正反
  10. uint8_t           screen_dir=3;
  11. // WiFi物联网管理实例,处理热点连接、IP查询、无线状态监测
  12. DFRobot_Iot       myIot;
  13. // UDP客户端通信实例,建立与服务端的UDP通信链路、收发文本数据包
  14. DFRobot_UDPClient myclient;
  15. // 全局字符串缓存:接收服务端UDP消息的中转站
  16. // 安全规则:网络后台回调禁止操作屏幕,仅把消息存入此变量,屏幕渲染全部交给主线程loop
  17. String udp_msg_cache = "";
  18. // 毫秒时间戳变量,用于RGB灯光非阻塞计时,替代会卡死线程的delay()
  19. unsigned long rgb_time = 0;
  20. // RGB灯光状态标记:true=收到消息需要点亮灯光计时,false=灯光熄灭待机
  21. bool rgb_flag = false;
  22. // 前置声明两个事件回调函数,编译器提前识别函数标识用于绑定事件
  23. void onUdpClientRecvMsg(String message);
  24. void onButtonAPressed();
  25. /**
  26. * setup 上电一次性初始化函数
  27. * 严格执行固定顺序:屏幕硬件初始化→绘制初始界面→绑定事件回调→连接WiFi热点→连接UDP服务端
  28. * 屏幕初始化必须放在最开头,防止WiFi射频抢占SPI屏幕总线导致黑屏、屏幕失效
  29. */
  30. void setup() {
  31.         // 步骤1:强制第一顺位初始化整套K10底层硬件(屏幕总线、按键IO、RGB驱动、系统时钟)
  32.         k10.begin();
  33.         // 根据参数3初始化屏幕翻转朝向
  34.         k10.initScreen(screen_dir);
  35.         // 创建内存绘图画布缓冲区,文字先写入缓存再整体刷新,降低屏幕闪烁撕裂
  36.         k10.creatCanvas();
  37.         // 设置屏幕整体背景底色为纯黑色 0x000000
  38.         k10.setScreenBackground(0x000000);
  39.         // 画布第3行绿色标题文字,标记本机身份为UDP客户端
  40.         k10.canvas->canvasText("        行空板K10-客户端", 3, 0x00FF00);
  41.         // 第一次刷新画布,把客户端标题渲染显示到屏幕
  42.         k10.canvas->updateCanvas();
  43.         // 步骤2:绑定事件回调函数
  44.         // 给UDP客户端绑定消息接收回调:后台监听到服务端数据包自动执行onUdpClientRecvMsg
  45.         myclient.setCallback(onUdpClientRecvMsg);
  46.         // 给A物理按键绑定按下中断回调:按下A键立刻执行发送UDP消息函数
  47.         k10.buttonA->setPressedCallback(onButtonAPressed);
  48.         // 步骤3:最后启动WiFi网络、UDP客户端
  49.         // 发起WiFi连接:接入服务端板子搭建的AP热点,热点名AP,密码88888888
  50.         myIot.wifiConnect("AP", "88888888");
  51.         // 阻塞死循环,不完成WiFi连接则程序暂停向下执行,保证网络就绪再启动UDP
  52.         while (!myIot.wifiStatus()) {}
  53.         // WiFi联网成功后,绘制联网提示文字
  54.         // 第5行红色文字提示热点连接成功
  55.         k10.canvas->canvasText("         成功连接AP热点", 5, 0xFF0000);
  56.         // 拼接字符串,读取本机被热点分配的内网IP,第7行蓝色字体打印IP地址
  57.         k10.canvas->canvasText((String("       配置 IP:") + String(myIot.getWiFiLocalIP())), 7, 0x0000FF);
  58.         // UDP客户端主动对接服务端地址
  59.         // 目标服务端IP:192.168.4.1(服务端SoftAP固定网关IP),统一通信端口8888
  60.         myclient.connectToServer("192.168.4.1",8888);
  61.         // 批量刷新画布,展示联网状态、本机IP界面
  62.         k10.canvas->updateCanvas();
  63. }
  64. /**
  65. * loop 程序主线无限循环
  66. * 所有屏幕绘制刷新、灯光延时逻辑全部放在主线程运行,保证屏幕稳定渲染
  67. * UDP网络监听、按键检测由库后台反文旁虫立线程运行,loop只做界面刷新与状态轮询
  68. */
  69. void loop() {
  70.         // 第一模块:主线程安全刷新屏幕,展示服务端下发的UDP消息
  71.         if(udp_msg_cache != ""){
  72.                 // 清空画布全部旧绘制内容
  73.                 k10.canvas->canvasClear();
  74.                 // 还原黑色屏幕背景
  75.                 k10.setScreenBackground(0x000000);
  76.                 // 重绘顶部客户端标题
  77.                 k10.canvas->canvasText("        行空板K10-客户端", 3, 0x00FF00);
  78.                 // 重绘热点连接成功提示文字
  79.                 k10.canvas->canvasText("         成功连接AP热点", 5, 0xFF0000);
  80.                 // 重绘本机内网IP文本
  81.                 k10.canvas->canvasText((String("       配置 IP:") + String(myIot.getWiFiLocalIP())), 7, 0x0000FF);
  82.                 // 画布第9行黄色字体,打印服务端发送过来的完整消息内容
  83.                 k10.canvas->canvasText("收到服务端:"+udp_msg_cache,9,0xFFFF00);
  84.                 // 一次性批量刷新整屏所有文字到显示屏
  85.                 k10.canvas->updateCanvas();
  86.                 // 清空消息缓存,避免循环重复刷屏同一条消息
  87.                 udp_msg_cache = "";
  88.         }
  89.         // 第二模块:非阻塞方式控制RGB彩灯,无delay不卡住UDP网络线程
  90.         // 判断灯光标记为开启,且点亮时长已经超过2000毫秒(2秒)
  91.         if(rgb_flag && millis()-rgb_time>2000){
  92.                 // 参数-1代表控制全部板载RGB灯珠,赋值黑色熄灭彩灯
  93.                 k10.rgb->write(-1,0x000000);
  94.                 // 关闭灯光状态标记,等待下一次消息触发点亮
  95.                 rgb_flag = false;
  96.         }
  97. }
  98. /**
  99. * UDP客户端消息接收回调函数(后台WiFi子线程运行)
  100. * 严格安全规范:仅允许赋值全局缓存、点亮RGB灯;禁止画布绘制、屏幕刷新、长延时delay
  101. * 入参message:服务端广播下发的完整字符串数据包
  102. */
  103. void onUdpClientRecvMsg(String message) {
  104.         udp_msg_cache = message;        // 将服务端消息存入全局缓存,交给主线程屏幕展示
  105.         rgb_flag = true;                // 标记需要点亮RGB灯并计时
  106.         rgb_time = millis();            // 记录当前系统毫秒时间戳,作为灯光计时起点
  107.         k10.rgb->write(-1, 0xFF0000);   // 全部RGB灯点亮纯红色,作为收到消息提示
  108. }
  109. /**
  110. * A按键按下专属回调函数
  111. * 触发动作:按下A物理按键,UDP客户端向192.168.4.1:8888发送文本UDP数据包
  112. */
  113. void onButtonAPressed() {
  114.         // 发送字符串消息:hello,I am client
  115.         myclient.sendUdpMsg("hello,I am client");
  116. }
复制代码



回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】K10实验之UDP广播双K10双向通信屏显消息

行空板 K10 UDP 客户端代码解读

一、头文件与全局对象、变量定义

  1. // DFR物联网WiFi驱动库,用于连接外部WiFi热点、读取本地IP、检测联网状态
  2. #include <DFRobot_Iot.h>
  3. // K10整机硬件驱动库,统一操控屏幕、绘图画布、A按键、RGB彩灯外设
  4. #include "unihiker_k10.h"
  5. // WiFi UDP客户端专用库,实现连接UDP服务端、发送消息、绑定接收回调事件
  6. #include <DFRobot_UDPClient.h>
  7. // K10硬件总控制实例
  8. UNIHIKER_K10      k10;
  9. // 屏幕翻转角度参数3,适配设备摆放正反视角
  10. uint8_t           screen_dir=3;
  11. // WiFi管理对象,处理热点连接、IP查询
  12. DFRobot_Iot       myIot;
  13. // UDP客户端通信对象,负责和服务端建立UDP链路收发数据
  14. DFRobot_UDPClient myclient;
  15. // 全局消息缓存:网络回调不能操作屏幕,收到消息先存这里,主线程loop渲染屏幕
  16. String udp_msg_cache = "";
  17. // 毫秒时间戳,用来实现RGB灯无阻塞延时,替换会卡线程的delay()
  18. unsigned long rgb_time = 0;
  19. // RGB灯状态标记:true=灯点亮计时中,false=灯熄灭待机
  20. bool rgb_flag = false;
  21. // 提前声明两个回调函数,编译器预识别函数标识
  22. void onUdpClientRecvMsg(String message);
  23. void onButtonAPressed();
复制代码


二、setup () 上电一次性初始化

  1. void setup() {
  2.         // ========== 第一优先级:先初始化屏幕硬件(顺序不可调换,防止WiFi抢占总线黑屏) ==========
  3.         k10.begin();
  4.         // 设置屏幕显示翻转方向
  5.         k10.initScreen(screen_dir);
  6.         // 创建画布缓存,文字批量刷新,减少屏幕闪烁
  7.         k10.creatCanvas();
  8.         // 屏幕底色设纯黑色
  9.         k10.setScreenBackground(0x000000);
  10.         // 第3行绿色大字,标注本机为UDP客户端
  11.         k10.canvas->canvasText("        行空板K10-客户端", 3, 0x00FF00);
  12.         // 首次刷新画布,把标题显示到屏幕
  13.         k10.canvas->updateCanvas();
  14.         // ========== 绑定按键、UDP接收回调事件 ==========
  15.         // UDP收到消息自动执行onUdpClientRecvMsg
  16.         myclient.setCallback(onUdpClientRecvMsg);
  17.         // A按键按下自动执行发送消息函数
  18.         k10.buttonA->setPressedCallback(onButtonAPressed);
  19.         // ========== 最后启动WiFi网络与UDP客户端 ==========
  20.         // 连接服务端板子搭建的WiFi热点:名称AP,密码88888888
  21.         myIot.wifiConnect("AP", "88888888");
  22.         // 阻塞循环:必须等待WiFi连接成功,才往下执行,避免无网络启动UDP失败
  23.         while (!myIot.wifiStatus()) {}
  24.         // WiFi连上后,绘制联网提示文字
  25.         k10.canvas->canvasText("         成功连接AP热点", 5, 0xFF0000);
  26.         // 拼接字符串,读取本机被热点分配的内网IP并打印在第7行
  27.         k10.canvas->canvasText((String("       配置 IP:") + String(myIot.getWiFiLocalIP())), 7, 0x0000FF);
  28.         // UDP客户端连接固定服务端:IP192.168.4.1,端口8888(服务端热点默认网关IP)
  29.         myclient.connectToServer("192.168.4.1",8888);
  30.         // 刷新画布,展示全部联网信息
  31.         k10.canvas->updateCanvas();
  32. }
复制代码


三、loop () 主线无限循环(屏幕、灯光逻辑全部放在主线程,稳定不卡死)

  1. void loop() {
  2.         // 1、主线程安全刷新屏幕,展示服务端发来的UDP消息
  3.         if(udp_msg_cache != ""){
  4.                 // 清空旧画布所有内容
  5.                 k10.canvas->canvasClear();
  6.                 // 恢复黑色背景
  7.                 k10.setScreenBackground(0x000000);
  8.                 // 重绘固定界面标题、联网状态、本机IP
  9.                 k10.canvas->canvasText("        行空板K10-客户端", 3, 0x00FF00);
  10.                 k10.canvas->canvasText("         成功连接AP热点", 5, 0xFF0000);
  11.                 k10.canvas->canvasText((String("       配置 IP:") + String(myIot.getWiFiLocalIP())), 7, 0x0000FF);
  12.                 // 第9行黄色文字打印收到的服务端消息
  13.                 k10.canvas->canvasText("收到服务端:"+udp_msg_cache,9,0xFFFF00);
  14.                 // 一次性批量刷新整屏画面
  15.                 k10.canvas->updateCanvas();
  16.                 // 清空缓存,避免反复刷新同一条消息
  17.                 udp_msg_cache = "";
  18.         }
  19.         // 2、非阻塞控制RGB灯,无delay,不占用UDP网络线程
  20.         if(rgb_flag && millis()-rgb_time>2000){
  21.                 // 熄灭全部RGB灯珠
  22.                 k10.rgb->write(-1,0x000000);
  23.                 // 关闭灯光标记
  24.                 rgb_flag = false;
  25.         }
  26. }
复制代码

四、两个事件回调函数(后台子线程运行,严格限制操作)

1、UDP 消息接收回调

  1. void onUdpClientRecvMsg(String message) {
  2.         // 只做安全操作:存消息、标记灯光、开灯;禁止屏幕绘制、长delay
  3.         udp_msg_cache = message;       // 消息存入全局缓存,交给loop主线程显示
  4.         rgb_flag = true;               // 标记需要点亮灯光计时
  5.         rgb_time = millis();          // 记录开灯的时间起点
  6.         k10.rgb->write(-1, 0xFF0000); // -1代表所有RGB灯,点亮纯红色提示收到消息
  7. }
复制代码

2、A 按键按下发送消息回调

  1. void onButtonAPressed() {
  2.         // 向服务端IP:8888发送UDP文本数据包
  3.         myclient.sendUdpMsg("hello,I am client");
  4. }
复制代码



1、和配套服务端完整配对关系

【花雕动手做】K10 实验之 UDP 广播双K10双向通信屏显消息图1

双向交互流程
先上电运行服务端,热点开启、UDP 端口打开;
客户端上电自动连接热点,联网成功后自动对接 UDP 服务端;
客户端按 A → 发送 client 消息 → 服务端屏幕显示文字、亮浅青灯;
服务端按 A → 广播 server 消息 → 客户端屏幕显示文字、亮红灯。

2、代码核心稳定优化点(解决屏幕不显示、卡死问题)
线程隔离铁则
UDP 接收运行在 WiFi 后台子线程,回调里完全禁止 canvasText/updateCanvas 屏幕操作,仅存数据、点灯;所有画面渲染统一放在 loop 主线程,杜绝 SPI 屏幕总线资源抢占黑屏。
无阻塞计时
彻底删掉回调里阻塞式delay(2000),用millis()毫秒时间戳在 loop 里延时关灯,UDP 监听全程不卡顿、不丢包。
初始化顺序锁死
代码第一行必须k10.begin()初始化屏幕硬件,后开 WiFi/UDP;颠倒顺序会直接屏幕驱动初始化失败、黑屏无画面。
消息防重复刷屏
展示完一条 UDP 消息立刻清空udp_msg_cache,不会无限循环刷新同一行文字。

3、通信协议定性
DFRobot_UDPClient/UDPServer属于标准 WiFi 局域网 UDP(User Datagram Protocol)传输层协议,和你截图里 IP + 端口的图形化 UDP 积木是同一套网络体系;必须依靠 2.4G WiFi 组网,和DFRobot_ESP32_Radio蓝牙离线广播属于两套完全独立的无线方案。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2026 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail