2023寒假一起练平台(5)- 基于ESP32 WiFi 的综合应用 项目5鼠标
利用ESP32 S2板做一个USB设备,用摇杆当作手柄移动电脑上的鼠标箭头,实现鼠标的左键完成选择,右键打印相关的字符。
标签
嵌入式系统
接口
USB
yao
更新2023-03-29
501

2023寒假一起练平台(5)- 基于ESP32 WiFi 的综合应用——USB键盘鼠标设备

项目5- 实现一个USB键盘鼠标设备

  • IO扩展板上有一个用X、Y二轴电位计制作的游戏手柄,并且此芯片支持USB通信。

要求:实现一个USB鼠标&键盘复合设备,摇动游戏手柄实现鼠标的移动,一个按键实现左键点击,另一个按键按下实现键盘敲入一串字符"eetree.cn".

进行此项目前,我做了如下的动作:

功能框图:

 

ESP32-S2板框架:

Fsrwz4_hqtaUhn-QnzM9M8OxextZ

 

扩展板功能:

 

摇杆工作原理:

Fv1KQ_nDsrjWowyverEvhMaOdisQ

ESP32连接框图:

FkgCz_pD6QNEtymPNzZOTL4cbuPy

模块功能:

1、ESP32:S2实现对数据的处理和USB设备.

2、摇杆:实现X和Y坐标功能。

3、轻触按键,一个实现左键另一个按下打印字符。

一、具体功能:

下载好程序后,电脑PC会识别设备,这个时候就可以操作ESP32和扩展板上的摇杆,上下左右(也就是X/Y坐标方向 )摇动,当摇杆摇动过程中,电脑PC端鼠标就会移动,而且速度与实际鼠标移动速度不相上下;打开一个TXT文档或者待输入的界面,可以利用扩展板上的轻触开关选定当前状况,这个时候光标就是闪烁,再按下编码器开关,就会打印一条字符串eetree.cn。

二、摇杆功能的实现

 

根据时间间隔计算PWM信号的频率和占空比是一种常见的方法,可以在嵌入式系统中用于测量PWM信号的特性。根据时间间隔可以计算出引脚GPIO2的PWM信号的周期和高电平时间,从而计算出频率和占空比。假设一个PWM信号的周期为T,高电平时间为H,低电平时间为L,则有以下关系式:PWM信号的周期等于高电平时间加上低电平时间,占空比等于高电平时间除以周期 T = H + L  Duty Cycle = H / T 。由于在本例中,中断服务程序只能在上升沿触发,因此需要记录上一个上升沿的时间raiseTime,并在下一个上升沿到来时,根据时间间隔计算出PWM信号的周期和高电平时间,从而计算出频率和占空比。具体来说,计算频率的公式为: Freq = 1e6 / T 其中,T为周期,单位为微秒,因此频率的单位为赫兹(Hz)。计算占空比的公式为: Duty Cycle = H / T * 100% ,其中,H为高电平时间,单位为秒,T为周期,因此占空比的单位为百分比(%)但是为了和屏幕匹配这里乘于1000。

代码中实现了测量PWM信号频率和占空比的中断服务程序。

 

代码分析:

portMUX_TYPE timerMux2 = portMUX_INITIALIZER_UNLOCKED;
void changeISR()
{
  if (digitalRead(pwmPin)) // 现在是高
  {
    portENTER_CRITICAL_ISR(&timerMux2);   // 进入临界区
    auto total = micros() - raiseTime;   // the raisTime is the last raiseTime
    // the total time is from last raiseTime till recent raiseTime.
    freq = 1e6 / (double)total;
    auto h = fallTime - raiseTime;       // last fallTime - last rasieTime
    duty = h / (double)total * 1000;
    portEXIT_CRITICAL_ISR(&timerMux2); // 离开临界区
    raiseTime = micros();                // recent raiseTime ,prepare for next caculation.
  }
  else
  {
    fallTime = micros();                 // update the recent fallTime ,prepare for next caculation.
  }
}

 当PWM信号的电平由低变高时,会触发一个中断,中断服务程序会进行以下操作:判断当前PWM信号的电平是否为高电平,如果是高电平则执行下一步,否则直接返回。计算从上一个上升沿到这个上升沿的时间间隔,根据时间间隔计算PWM信号的频率和占空比。新上一个上升沿的时间,以便下一次计算。其中,变量pwmPin为需要测量的PWM信号所连接的引脚,变量raiseTime和fallTime分别记录上一个上升沿和下降沿的时间,变量freq和duty分别记录PWM信号的频率和占空比。进入临界区,保证多个中断不会同时访问共享的变量。变量timerMux2为一个

portMUX_TYPE类型的变量,用于实现中断服务程序的临界区保护。

首先使用了portENTER_CRITICAL和portEXIT_CRITICAL函数来进入和离开临界区,以保证多个任务不会同时访问共享的变量freq和duty。 

 经前期测试频率的变化与x轴方向的变化相关,而且其数值变化范围227~ 430 ,占空比的变化与y轴方向的变化相关,而且其数值变化范围357~802,为了方便判断处理将其分别映射到0~100范围之间。为了控制鼠标的灵敏度,设定为如果x小于30,则鼠标向左移动10个像素;如果x大于70,则鼠标向右移动10个像素;如果y小于30,则鼠标向上移动10个像素;如果y大于70,则鼠标向下移动10个像素。最后,使用delay函数延迟20毫秒,以避免过快地移动鼠标。

 

  • 按键的实现

使用esp32内置的硬件定时器定时检测编码器模拟数值的变化并将读取到的数值传给判断函数,获取对应的键值。ESP32 支持多个定时器,因此需要指定编号。timer1 = timerBegin(0, 80, true);第二个参数为定时器的分频系数,该参数用于设置定时器时钟的分频,ESP32 的定时器时钟频率为 80MHz,因此分频系数为 80 表示将时钟频率除以 80,得到 1MHz 的计数频率。第三个参数为定时器的重复模式,如果设置为 true,则定时器达到设定的时间后会自动重启。timerAttachInterrupt() 函数用于为定时器设置中断回调函数,在定时器达到设定的时间后会触发中断,并调用该回调函数。

定制一个函数的作用是根据传入的编码器的模拟数值 val 返回一个对应的 key 值。具体实现为,遍历 keyMap 的数组,如果 val 大于等于 3700,则直接返回 0;否则,该数组的每两个元素分别表示一个 key 和一个对应的值,如果 val 在该值的范围内,则返回对应的 key 值。需要注意的是,keyMap 数组的下标从 0 开始,其中 keyPrecision 是一个全局变量,表示 key 的精度。

uint32_t getKey(uint32_t val) {
  if (val >= 3700) {
    //
  } else {
    for (int i = 0; i < keyNum; i++) {
      if (keyMap[i * 2 + 1] > 0 && val > keyMap[i * 2 + 1] - keyPrecision && val < keyMap[i * 2 + 1] + keyPrecision) return keyMap[i * 2];

    }
  }
  return 0;
}

注意事项

(1)函数中用到了 keyNum 和 keyPrecision 两个变量,需要在函数外部定义并初始化。

(2)函数中用到的 keyMap 数组需要在函数外部定义并初始化,且数组长度必须为偶数。每两个相邻的元素组成一个键值-阈值对,其中第一个元素为键值,第二个元素为对应的阈值。

(3)函数中没有对输入参数 val 的取值范围进行限制,需要在函数外部进行判断并保证其合法性。

 

  • 鼠标和键盘的实现

 

因为Arduino已经提供了鼠标、键盘和 USB 设备支持库,这里只要很轻松的启动库函数 Mouse.begin()、Keyboard.begin() 和 USB.begin()。在使用 Mouse 和 Keyboard 函数库时,需要在程序中包含 #include <Mouse.h> 和 #include <Keyboard.h> 头文件。

Mouse.begin() 函数用于启动鼠标设备,允许通过 USB 接口向计算机发送鼠标事件,例如鼠标的移动、按下和松开等操作。

Keyboard.begin() 函数用于启动键盘设备,允许通过 USB 接口向计算机发送键盘事件,例如键盘的按下和松开等操作。

USB.begin() 函数用于启动 USB 设备,并初始化 USB 接口。在调用该函数之前,需要先调用 Mouse.begin() 或 Keyboard.begin() 函数,以确保 USB 接口正确初始化。

然后接收按键和摇杆传来的数据就可以执行,相应的操作。

 

总结:

本实验难点在于摇杆PWM的频率和占空比的检测。基于PWM的基本原理但通过该引脚的中断进行启动高电平的检测,思路非常巧妙,使得遥控控制非常流畅。但是按键的功能却有点不尽人意。按键的判断逻辑有些复杂,硬件上可能也存在一些硬伤。本项目硬件方面主办方巧妙的只采用1个引脚实现了摇杆和旋转编码器的功能,操作惊为天人,非常值得学习和推广。

 

附件下载
Mouse_2.ino
团队介绍
个人
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号