基于ESP32-S2实现一个简易USB键鼠设备
【视频已修改】2023寒假在家一起练活动。要求实现一个基于ESP32-S2处理器的USB鼠标、键盘复合设备,拨动游戏摇杆实现鼠标的移动,一个按键实现左键点击。
标签
ESP32-S2
2023寒假在家练
fyjh2023
更新2023-03-27
复旦大学
1028

【”效果展示“前的视频已重新录制】

一、项目需求与硬件介绍

在IO扩展板上有一个用X、Y二轴电位计制作的游戏摇杆,并且处理器芯片支持USB通信。要求实现一个基于ESP32-S2处理器的USB鼠标、键盘复合设备,拨动游戏摇杆实现鼠标的移动,一个按键实现左键点击,另一个按键按下实现键盘敲入一串字符"eetree.cn"。

ESP32-S2是一款高度集成、高性价比、低功耗、主打安全的单核 Wi-Fi SoC。本项目使用ESP32-S2-MINI-1模组,它支持2.4 GHz WiFi,内置 ESP32­S2系列芯片以及4MB flash。核心板集成了USB TYPE -C接口,两个按键,一个电源指示灯,一个用户LED灯和2排10pin的排针,方便与扩展板连接。

二、设计思路

不断查询摇杆、按键的状态,然后分别作出鼠标移动、点击和键盘输入的动作。由于任务并不复杂,因此不需要使用中断,在主循环中顺序执行各项操作。具体操作如流程图所示(与MSP430F5529是一样的)。综合考虑程序编译速度和使用的难易程度,本项目使用Arduino平台进行编程。

Fh-PA3XeD6m7CmscpSSJ4pU1bwPb

三、技术细节

自然是面向例程的编程,省时省力又省心。USB-HID设备的实现,参照例程,针对IO扩展板上外设的特点进行补充修改,即可实现相关功能。Arduino开发平台生态环境良好,丰富的第三方库对于各种外设都有合适的例程供用户参考。

3.1 摇杆

经过示波器的测量,发现摇杆在x、y方向上的位置,被转化成输出波形的频率和占空比。用示波器测量了摇杆拨动到正前、正后、正左、正右,四个极限位置的输出波形。因为该波形的频率很低(具体测量结果我放在MSP430那篇报告里),同时不存在占空比极小或极大的情况,最初准备沿用MSP430上的采集手段:使用一个用while循环模拟的时钟,从第1个上升沿起,依次记录高电平和低电平所用的时钟周期数,到第2个上升沿停止计数。然而,在Arduino平台下,ESP32的IO操作函数被一层层地封装,导致函数的运行效率不高,该方法无法奏效。

因此,直接在Arduino平台下调用PulseIn函数测量一个周期下高电平和低电平的时间。接着,从中提取频率和占空比信息,映射到摇杆在x、y方向上的具体位置。

D1=0;D2=0;
D1 = pulseIn(pwmPin, HIGH);
D2 = pulseIn(pwmPin, LOW);

3.2 按键

根据IO扩展板的电路,读取模拟信号输入端口的电压后,与设定的阈值进行比较,然后判断按键的动作。特别的,在“鼠标左键”对应的按键按下后,执行“按下左键”的操作。然后在该按键松开前,需要不断检测摇杆位置。

sensorValue = analogRead(sensorPin);

3.3 键鼠操作

面向例程编程实现相关操作。使用ESP32TinyUSB的开源代码,实现HID复合设备。 将摇杆输出的频率和占空比数值线性映射到指针的移动量上。以左键按下时为例:

else if(sensorValue>2000 && sensorValue<2550){
  delay(10);
  //device.pressRight();
  device.buttons(LEFT_BTN); //阅读源代码,在hidcomposite.cpp中pressLeft的实现
  delay(2);
  sensorValue = analogRead(sensorPin);
  while(sensorValue>1800 && sensorValue<2750){
    sensorValue = analogRead(sensorPin);
    //让左键按下时指针依然正常工作,“按下”时继续检测摇杆位置
    D1=0;D2=0;
    D1 = pulseIn(pwmPin, HIGH);//检测高电平
    D2 = pulseIn(pwmPin, LOW);
    s=D1+D2;
    m=(float)D1/D2;
    dx=0;dy=0;
    if(s<3650 && s>3160){
      //水平方向不移动  
    }
    else if(s>3650){
      dx=-(s-3650.0)/(4580.0-3650.0)*15.0;
    }
    else if(s<3160){
      dx=(3160.0-s)/(3160.0-2450.0)*15.0;
    }
    if(m<2.4 && m>1.0){
      //垂直方向不移动  
    }
    else if(m<1.0 && m>0.50){
      dy=-(1.0-m)/(1.0-0.50)*15.0;
    }
    else if(m>2.4 && m<4.09){
      dy=(m-2.4)/(4.09-2.4)*15.0;
    }
    device.move(dx, dy);
    delay(2);
    //Serial.print(",adc=");Serial.println(sensorValue);
  }
  device.buttons(0);
  delay(10);
}

3.4 其他

使用Ucglib的开源代码,以软件SPI的方式驱动LCD屏幕,显示简单的图案。

四、实现功能

本项目使用到IO扩展板上的:按键、旋转编码器,摇杆,LCD屏幕和按键。本项目成功实现按键控制文字输入、鼠标点击;摇杆控制鼠标指针;另外使用LCD屏幕显示了简单的文字。

五、遇到的问题

5.1 USB调试

根据以前使用CH552G的经验,使用Bus Hound工具在Windows电脑上直接观察设备发出的HID数据。根据HID数据的内容,及其发送的频率,判断设备的工作是否符合预期。

5.2 烫手

IO扩展板上有4个加热电阻,如果不在程序里拉低加热功能的控制引脚,它们的温度会非常高。注意安全。

5.3 开发环境

Arduino的简单好用,不必多说。而IDF的功能更加丰富,可以对ESP32实现更深层次的控制。原先准备用IDF编程,但是它在Windows下的编译速度令人无法忍受。最终我使用编译相对较快的Arduino。

如果要解决IDF的编译速度问题,更换高性能的电脑不是最主要的解决方式。在Linux中,IDF的编译速度至少是Windows的2倍(我用完全相同的一份代码试过)。不妨采用Windows+VSCode+WSL+ESP-IDF的组合开发ESP32。在配置WSL上消耗的时间,总归能在之后一次次编译代码时赚回来的。下载程序时,相比于常用的115200,选择921600的波特率能够减少一些等待的时间。

FoO7YMtvcGolEynleeIPwgAjhsi8

5.4 调试

我不知道怎么调试啊……项目的需求简单,可以盲调。

六、未来计划

该项目已实现所要求的全部功能。首先,希望能找到硬件SPI驱动LCD屏幕的代码,从而实现丰富的动画效果。其次,希望能利用上旋转编码器,实现键盘/鼠标动作的自由切换。(摇杆向下拨到底好像程序出了小的bug,需要改下程序的阈值)

不过,仔细思考了下代码的整个流程,隐隐约约感觉用CH552也可以实现项目的要求。摇杆位置读取的算法在51单片机上自然能用,鼠标、键盘按键的功能我之前做过并取得成功,同时网上也有许多开源资料供参考。

某宝上CH552G的单价为1.85元。也可以发3个CH552G的核心板。或者考虑用ESP32-C3制作核心板,它比ESP-S2多了蓝牙功能。

 

附件下载
esp32版本键鼠.rar
直接烧录的文件位于压缩包的“新建文件夹”下
团队介绍
杨君昊
团队成员
fyjh2023
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号