news 2026/4/18 8:19:52

ESP32-S3实现远程虚拟的USB有线鼠标键盘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ESP32-S3实现远程虚拟的USB有线鼠标键盘

ESP32-S3实现远程虚拟的USB有线鼠标键盘

想要用ESP32-S3实现远程虚拟USB有线鼠标键盘,让ESP32-S3同时具备两个关键能力:一是模拟成电脑可识别的USB有线HID设备(鼠标+键盘),二是通过远程通信(WiFi/BLE)接收控制指令,最终让电脑像接了真实USB键鼠一样,响应远程的操作。这个方案无需额外USB转串口模块,直接利用ESP32-S3的USB-OTG功能实现“有线键鼠模拟”,远程端通过WiFi(推荐,传输距离远)或BLE控制。

一、核心实现原理

ESP32-S3的USB-OTG接口支持USB Device模式,可配置为HID(人机接口设备)类,向电脑发送标准的鼠标/键盘HID报告,电脑会自动识别为“USB有线键鼠”;同时ESP32-S3通过WiFi建立TCP/UDP连接,接收远程端(比如手机/另一台电脑)的控制指令,解析后转换成HID报告发送给电脑,完成远程操作。

简单来说:
远程控制端WiFi(TCP)ESP32-S3(解析指令)USB HID模拟电脑(识别为有线键鼠)

二、硬件准备(极简,新手友好)

组件规格/要求作用说明
ESP32-S3开发板带USB-OTG口(如ESP32-S3-DevKitC-1)核心,同时实现WiFi通信和USB HID模拟
USB Type-C数据线数据款(非仅充电)连接ESP32-S3的USB-OTG口到电脑
电脑(Windows/Linux)任意版本识别ESP32-S3为USB键鼠并响应操作
远程控制端手机/另一台电脑(带网络调试助手)发送键鼠控制指令(如“移动鼠标”“按键盘A”)

三、软件环境准备

  1. Arduino IDE配置(新手首选,无需复杂编译):
    • 安装Arduino IDE,在「文件→首选项」中添加ESP32开发板地址:https://dl.espressif.com/dl/package_esp32_index.json
    • 在「工具→开发板→ESP32 Arduino」中选择ESP32-S3 Dev Module
    • 关键配置:USB ModeUSB-OTG (HID)CPU Frequency80MHz(降频降功耗),Flash Size4MB

四、完整实现代码(WiFi+USB HID键鼠,开箱即用)

以下代码实现核心功能:

  • ESP32-S3连接指定WiFi,作为TCP服务器等待远程指令;
  • 模拟USB有线鼠标(移动、左键点击)+ 键盘(单键、组合键);
  • 自定义简单指令协议,远程端发送指令即可控制。
#include<Arduino.h>#include<WiFi.h>#include<USBHID.h>#include<HIDReports.h>#include<HIDTypes.h>// ===================== 配置项(修改为你的信息)=====================#defineWIFI_SSID"你的WiFi名称"#defineWIFI_PWD"你的WiFi密码"#defineTCP_PORT8888// TCP通信端口#defineBAUD_RATE115200// 串口波特率(调试用)// ===================== USB HID 配置(鼠标+键盘)=====================USBHID hid;// 鼠标HID报告描述符(标准格式:X/Y移动、滚轮、按键)uint8_tmouseReportDesc[]={0x05,0x01,// USAGE_PAGE (Generic Desktop)0x09,0x02,// USAGE (Mouse)0xA1,0x01,// COLLECTION (Application)0x09,0x01,// USAGE (Pointer)0xA1,0x00,// COLLECTION (Physical)0x05,0x09,// USAGE_PAGE (Button)0x19,0x01,// USAGE_MINIMUM (Button 1)0x29,0x03,// USAGE_MAXIMUM (Button 3)0x15,0x00,// LOGICAL_MINIMUM (0)0x25,0x01,// LOGICAL_MAXIMUM (1)0x95,0x03,// REPORT_COUNT (3)0x75,0x01,// REPORT_SIZE (1)0x81,0x02,// INPUT (Data,Var,Abs)0x95,0x01,// REPORT_COUNT (1)0x75,0x05,// REPORT_SIZE (5)0x81,0x01,// INPUT (Cnst,Var,Abs)0x05,0x01,// USAGE_PAGE (Generic Desktop)0x09,0x30,// USAGE (X)0x09,0x31,// USAGE (Y)0x09,0x38,// USAGE (Wheel)0x15,0x81,// LOGICAL_MINIMUM (-127)0x25,0x7F,// LOGICAL_MAXIMUM (127)0x75,0x08,// REPORT_SIZE (8)0x95,0x03,// REPORT_COUNT (3)0x81,0x06,// INPUT (Data,Var,Rel)0xC0,// END_COLLECTION0xC0// END_COLLECTION};// 键盘HID报告描述符(标准104键+修饰键)uint8_tkeyboardReportDesc[]={0x05,0x01,// USAGE_PAGE (Generic Desktop)0x09,0x06,// USAGE (Keyboard)0xA1,0x01,// COLLECTION (Application)0x05,0x07,// USAGE_PAGE (Keyboard/Keypad)0x19,0xE0,// USAGE_MINIMUM (Keyboard Left Control)0x29,0xE7,// USAGE_MAXIMUM (Keyboard Right GUI)0x15,0x00,// LOGICAL_MINIMUM (0)0x25,0x01,// LOGICAL_MAXIMUM (1)0x95,0x08,// REPORT_COUNT (8)0x75,0x01,// REPORT_SIZE (1)0x81,0x02,// INPUT (Data,Var,Abs)0x95,0x01,// REPORT_COUNT (1)0x75,0x08,// REPORT_SIZE (8)0x81,0x03,// INPUT (Cnst,Var,Abs)0x95,0x06,// REPORT_COUNT (6)0x75,0x08,// REPORT_SIZE (8)0x15,0x00,// LOGICAL_MINIMUM (0)0x25,0x65,// LOGICAL_MAXIMUM (101)0x05,0x07,// USAGE_PAGE (Keyboard/Keypad)0x19,0x00,// USAGE_MINIMUM (Reserved)0x29,0x65,// USAGE_MAXIMUM (Keyboard Application)0x81,0x00,// INPUT (Data,Array)0xC0// END_COLLECTION};// 定义HID报告结构HIDReport mouseReport={mouseReportDesc,sizeof(mouseReportDesc)};HIDReport keyboardReport={keyboardReportDesc,sizeof(keyboardReportDesc)};// ===================== TCP通信相关 =====================WiFiServertcpServer(TCP_PORT);WiFiClient tcpClient;String recvData="";// ===================== 键鼠控制函数(核心)=====================// 鼠标控制:x/y为移动偏移(-127~127),btn为按键(1=左键,2=右键,4=中键),wheel为滚轮(-127~127)voidmouseControl(int8_tx,int8_ty,uint8_tbtn,int8_twheel=0){uint8_treport[4]={btn,x,y,wheel};// 鼠标报告:按键、X、Y、滚轮hid.sendReport(&mouseReport,report,sizeof(report));}// 键盘控制:modifier为修饰键(如0x01=左Ctrl,0x02=左Shift),key为按键(如0x04=A,0x05=B)voidkeyboardControl(uint8_tmodifier,uint8_tkey){uint8_treport[8]={modifier,0,key,0,0,0,0,0};// 键盘报告格式hid.sendReport(&keyboardReport,report,sizeof(report));delay(50);// 按键保持时间// 释放按键(避免长按)memset(report,0,sizeof(report));hid.sendReport(&keyboardReport,report,sizeof(report));}// ===================== 指令解析(自定义简单协议)=====================// 指令格式示例:// 鼠标移动:M|x|y (如M|10|5 → 鼠标右移10,下移5)// 鼠标左键点击:MB|1 (MB|0=释放,MB|1=按下)// 键盘按键:K|mod|key (如K|0|4 → 按A键;K|1|4 → 按Ctrl+A)voidparseCmd(String cmd){cmd.trim();// 去除空格if(cmd.startsWith("M|")){// 鼠标移动cmd=cmd.substring(2);intx=cmd.substring(0,cmd.indexOf("|")).toInt();inty=cmd.substring(cmd.indexOf("|")+1).toInt();mouseControl((int8_t)x,(int8_t)y,0);Serial.printf("鼠标移动:X=%d, Y=%d\n",x,y);}elseif(cmd.startsWith("MB|")){// 鼠标按键intbtn=cmd.substring(3).toInt();mouseControl(0,0,btn);Serial.printf("鼠标按键:%d\n",btn);}elseif(cmd.startsWith("K|")){// 键盘按键cmd=cmd.substring(2);intmod=cmd.substring(0,cmd.indexOf("|")).toInt();intkey=cmd.substring(cmd.indexOf("|")+1).toInt();keyboardControl((uint8_t)mod,(uint8_t)key);Serial.printf("键盘按键:修饰键=%d, 按键=%d\n",mod,key);}}// ===================== WiFi连接 =====================voidconnectWiFi(){WiFi.begin(WIFI_SSID,WIFI_PWD);Serial.print("连接WiFi...");while(WiFi.status()!=WL_CONNECTED){delay(500);Serial.print(".");}Serial.println("\nWiFi连接成功!");Serial.print("ESP32-S3 IP地址:");Serial.println(WiFi.localIP());tcpServer.begin();// 启动TCP服务器Serial.printf("TCP服务器已启动,端口:%d\n",TCP_PORT);}// ===================== 初始化 =====================voidsetup(){Serial.begin(BAUD_RATE);delay(1000);// 初始化USB HIDhid.addReport(&mouseReport);hid.addReport(&keyboardReport);hid.begin();while(!hid.ready()){// 等待HID初始化完成delay(100);Serial.print(".");}Serial.println("\nUSB HID初始化完成,电脑应识别为USB键鼠!");// 连接WiFiconnectWiFi();}// ===================== 主循环 =====================voidloop(){// 检测TCP客户端连接if(!tcpClient.connected()){tcpClient=tcpServer.available();if(tcpClient){Serial.println("远程客户端已连接!");}delay(100);return;}// 读取远程指令while(tcpClient.available()>0){charc=tcpClient.read();if(c=='\n'){// 按换行符分割指令parseCmd(recvData);recvData="";}else{recvData+=c;}}delay(10);}

五、关键代码解析(新手必看)

  1. USB HID报告描述符

    • 是电脑识别“USB键鼠”的核心,上述代码用的是标准HID报告格式,无需修改,电脑会自动驱动;
    • 鼠标报告包含“3个按键(左/右/中)、X/Y移动、滚轮”,键盘报告包含“8个修饰键(Ctrl/Shift/Alt等)+ 6个普通按键”。
  2. 指令协议

    • 自定义极简协议,远程端发送指令时按格式(如M|10|5),ESP32-S3解析后调用mouseControl/keyboardControl发送HID报告;
    • 键盘按键码参考标准HID值(如0x04=A、0x05=B、0x1E=0、0x44=Enter),修饰键码:0x01=左Ctrl、0x02=左Shift、0x04=左Alt、0x08=左Win。
  3. TCP通信

    • ESP32-S3作为TCP服务器,远程端(手机/电脑)用“网络调试助手”连接其IP+端口(8888),发送指令即可控制。

六、测试步骤(5分钟验证)

  1. 烧录代码:修改WIFI_SSIDWIFI_PWD后,烧录到ESP32-S3,用USB Type-C线连接ESP32-S3的USB-OTG口到电脑;
  2. 识别设备:电脑会自动识别“USB Human Interface Device”(无需装驱动),在「设备管理器」可看到“鼠标”“键盘”;
  3. 远程控制
    • 打开串口监视器,查看ESP32-S3的IP地址(如192.168.1.100);
    • 远程端(如电脑)打开“网络调试助手”,选择「TCP客户端」,输入IP+8888,连接成功后发送指令:
      • 发送M|10|5→ 鼠标向右移动10像素、向下移动5像素;
      • 发送MB|1→ 鼠标左键按下,发送MB|0→ 释放;
      • 发送K|0|4→ 按下并释放A键,发送K|1|4→ 按下并释放Ctrl+A。

七、避坑指南(新手常踩)

  1. USB线选数据款:仅充电的USB线会导致电脑无法识别HID设备,务必用带数据传输的Type-C线;
  2. HID初始化等待:代码中while (!hid.ready())必须保留,否则HID未就绪会导致指令无响应;
  3. 指令格式严格:远程指令需按M|x|y/MB|btn/K|mod|key格式,且以换行符结尾(网络调试助手勾选“发送新行”);
  4. WiFi断连处理:代码可扩展“重连WiFi”逻辑,避免远程端断连后无法恢复。

总结

实现ESP32-S3远程虚拟USB有线键鼠的核心关键点:

  1. USB HID配置:用标准报告描述符让电脑识别为有线键鼠,无需额外驱动;
  2. 远程通信:WiFi TCP是最通用的远程方式,传输距离远、稳定性高;
  3. 指令解析:自定义简单协议,降低远程端开发成本,适配手机/电脑等控制端。

这套方案无需复杂硬件,代码开箱即用,既实现了“USB有线键鼠模拟”的稳定性,又具备“远程控制”的灵活性,适合远程办公、智能家居控制等场景。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 6:27:14

基于Java Web的线上超市购物管理系统

目录摘要项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作摘要 随着电子商务的快速发展&#xff0c;线上超市购物系统成为现代零售行业的重要组成部分。本系统基于Java Web技术开发&#xff0c;采用B/S架构…

作者头像 李华
网站建设 2026/4/13 8:36:40

GEO赛道榜单:AI营销获客难?看原圈科技如何领跑2026

原圈科技在GEO&#xff08;生成式引擎优化&#xff09;领域表现突出&#xff0c;被普遍视为2026年度领跑者。其核心优势在于&#xff0c;拥有能够兼容国内外主流大模型的自主技术底座&#xff0c;并打造了从洞察、内容到转化的"AI营销员工"产品矩阵。通过在金融、汽车…

作者头像 李华
网站建设 2026/4/8 23:08:45

人类自然语言与大模型的桥梁——Embedding嵌入模型

“ Embedding模型是自然语言和模型的桥梁。” 了解过RAG技术的人应该都知道Embedding嵌入模型&#xff0c;但很多人可能并没有认真了解过这个核心组件&#xff1b;在大部分人眼中&#xff0c;Embedding模型是一个“不重要”的组件&#xff0c;只需要把文档切分之后&#xff0c;…

作者头像 李华
网站建设 2026/4/6 10:24:17

网络安全学习路线图:从零基础到全栈工程师

网络安全学习路线图&#xff1a;从零基础到全栈工程师 “看了 3 个月网络安全教程&#xff0c;学了 TCP/IP、防火墙原理&#xff0c;却连‘怎么用 Nmap 扫一个端口’都不会&#xff1b;跟着视频做了 DVWA 漏洞复现&#xff0c;换个靶场就一脸懵&#xff1b;不知道该先学 Web 渗…

作者头像 李华