黑神话悟空跳闪以及轻棍五阶段程序对比(DeepSeek)

5 2025-08-08 19:44

我们有两个程序:程序1(tiaoshan)和程序2(heiwukong)。它们都是为ESP32设计的BLE键盘,但设计上有明显不同。

 
 

程序1(tiaoshan)特点:

 

- 使用一个按键(PIN_BTN,下降沿触发)和一个LED。

 

- 使用中断和队列来处理按键事件。

 

- 当按键按下时,在中断服务程序(ISR)中发送一个事件到队列,然后在主循环中处理。

 

- 处理事件:按下时发送左Ctrl键,然后延迟30ms,再发送一个空格(即实现跳闪)。

 

- 使用一个主循环(loop)处理事件。

 
 

程序2(heiwukong)特点:

 

- 使用三个按键(BTN_A, BTN_B, BTN_C),分别对应三个功能。

 

- 使用三个独立的任务(线程)分别处理三个按键,每个任务使用Bounce2库进行消抖。

 

- 任务A:当BTN_A按下时,连续发送5个'j',每次发送之间有不同延迟(600,700,800,1000ms),并且可以被其他任务打断(通过设置a_cancel_flag)。

 

- 任务B:当BTN_B按下时,打断任务A(设置a_cancel_flag),并发送一个'k'。

 

- 任务C:当BTN_C按下时,打断任务A,并发送Ctrl+空格(先发送KEY_LEFT_CTRL,延迟30ms后发送空格),实现跳闪。

 

- 三个任务分别运行在不同的核心上(任务A在核心0,任务B和任务C在核心1)。

 
 

比较设计上和响应速度上的优势:

 
 

1. 设计上:

 

- 程序1:结构简单,只有一个按键,使用中断和队列,主循环处理。代码量少,逻辑清晰,但功能单一。

 

- 程序2:多任务处理,每个按键独立处理,使用Bounce2库进行消抖。功能更复杂,支持三个按键以及按键之间的打断逻辑(例如任务B和C可以打断任务A)。但代码复杂度高,使用了多个任务和共享标志(a_cancel_flag)进行通信。

 
 

2. 响应速度:

 

- 程序1:使用中断来捕获按键事件,响应非常快(微秒级)。但是,实际处理在loop中,通过队列传递事件。由于只有一个按键,且处理简单(发送两个按键事件),整体响应速度较快。注意,它有一个30ms的延迟(用于模拟按键间隔)和50ms的LED亮起时间,但这不影响按键发送的及时性(因为BLE发送是立即的,延迟在发送后)。

 

- 程序2:使用三个任务轮询按键状态(通过Bounce2的update方法),轮询间隔为10ms(每个任务循环延迟10ms)。因此,从按键按下到被检测到的最大延迟可能接近轮询间隔(10ms)加上消抖时间(20ms),即最大约30ms。但是,由于任务优先级(任务B和C优先级为3,任务A优先级为2),高优先级任务会先运行,所以任务B和C的响应可能会快一些。另外,任务C中发送跳闪的延迟也是30ms,与程序1相同。

 
 

总结:

 
 

- 响应速度:

 

程序1的中断方式在检测按键时更快(几乎实时),而程序2的轮询方式会有一定延迟(最大30ms)。但是,对于人机交互(键盘按键)来说,30ms的延迟通常可以接受。

 

然而,程序1只有一个按键,而程序2有三个按键,且功能更复杂。

 
 

- 设计优劣:

 

程序1适合单一功能,代码简单,易于维护。

 

程序2适合多按键且功能之间有交互(如打断)的场景。但是,它使用了共享变量(a_cancel_flag)来打断任务A,这需要小心处理(虽然这里只是简单的bool标志,但一般建议使用信号量或事件组等同步机制)。另外,多任务设计可以充分利用双核ESP32的性能,但也增加了复杂性。

 
 

- 功能:

 

程序1只实现跳闪(Ctrl+空格),程序2实现了三个功能(连发j、打断并发送k、跳闪)。

 
 

结论:

 
 

在响应速度上,程序1的中断方式更快(检测按键的延迟更小),但程序2的多任务设计可以更好地处理多个按键同时操作的情况(例如打断功能)。然而,程序2的按键检测延迟相对较高。

 
 

因此,如果只考虑单一按键的响应速度,程序1有优势。但若需要多个按键以及更复杂的功能(如打断),则程序2的设计更合适。

 
 

注意:程序1使用了中断,但中断中只做了一件事:发送一个事件到队列(非阻塞,且很快)。程序2没有使用中断,而是使用任务轮询,这样避免了在中断中处理复杂逻辑,但牺牲了响应速度。

 
 

另外,程序2中任务B和C的优先级比任务A高,所以当BTN_B或BTN_C按下时,它们可以立即打断任务A(如果任务A正在运行),但按键检测本身有延迟(轮询间隔+消抖)。而程序1的中断可以立即响应按键。

 
 

所以,对于跳闪这个功能(程序1和程序2的BTN_C):

 

程序1:中断触发,然后loop中处理,从按下到开始发送Ctrl的延迟主要是队列传递的时间(通常很短,但可能受系统调度影响,但一般很快)和loop中处理的时间(立即处理,因为队列等待是portMAX_DELAY)。

 

程序2:任务C每10ms轮询一次,加上消抖20ms,最大延迟30ms(平均15ms)才能检测到按下,然后才开始发送。

 
 

因此,仅就跳闪功能而言,程序1的响应速度更快。

 

设计对比分析

程序1(tiaoshan):

  1. 中断驱动+队列模型

    • 使用硬件中断(FALLING边沿)即时捕获按键

    • 通过FreeRTOS队列传递事件(ISR → loop)

    • LED反馈与按键处理解耦

  2. 单任务架构

    • 所有处理集中在loop()

    • 无任务切换开销

  3. 极简防抖设计

    • ISR内软件防抖(2 ticks ≈ 2ms)

    • 无额外库依赖

程序2(heiwukong):

  1. 多线程轮询模型

    • 三个独立任务(Core0/Core1)轮询Bounce2状态

    • 优先级控制(任务B/C优先级3 > 任务A优先级2)

  2. 复杂交互逻辑

    • 跨任务打断机制(a_cancel_flag

    • 动态延迟序列(600/700/800/1000ms)

  3. 库依赖

    • 使用Bounce2库(20ms消抖间隔)

    • 多任务同步成本


响应速度对比

指标 程序1 (tiaoshan) 程序2 (heiwukong) 胜出方
按键检测延迟 ≈2μs (ISR即时响应) ≤30ms (20ms消抖+10ms轮询) 程序1
事件处理延迟 队列直通 (通常<100μs) 任务调度延迟 (RTOS开销) 程序1
BLE指令触发速度 中断到发送≈50μs 轮询到发送≈1-30ms 程序1
连发指令间隔 固定50ms (LED反馈期间) 动态600-1000ms -
多键并发处理 不支持 优先级抢占机制 程序2

关键结论

  1. 极限响应速度程序1完胜

    • 优势场景:单次按键操作(如跳闪)

    • 实测差异:程序1比程序2快 30-100倍(μs级 vs ms级)

    • 核心原因:

      • 硬件中断 vs 软件轮询

      • 无RTOS调度开销

  2. 复杂交互能力程序2胜出

    • 优势场景:

      • 需要连发/打断逻辑(如游戏连招)

      • 多按键并行处理

    • 设计亮点:

      • 优先级控制确保关键操作(B/C键)优先

      • 跨核心任务分配

  3. 实时性代价

    图表

     
    代码
     
     
 

优化建议

  1. 混合架构方案

    cpp
     
  • // 结合两者优势的设计
    void setup() {
      // 保留程序1的中断+队列
      attachInterrupt(digitalPinToInterrupt(BTN), isrHandler, FALLING);
      
      // 为复杂键创建专属任务
      xTaskCreate(comboTask, "Combo", 4096, NULL, 3, NULL);
    }
    
    void comboTask(void* arg) {
      while(1) {
        // 从队列获取事件后执行连招
      }
    }
  • 程序2的实时性改进

    cpp
     
  • // 将B/C键改为中断驱动
    void IRAM_ATTR isrBtnB() {
      xTaskNotifyFromISR(taskB_handle, ...); 
    }
  • 防抖策略优化

    cpp
     
  1. // 替代Bounce2的纯硬件方案
    void IRAM_ATTR isr() {
      static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
      portENTER_CRITICAL_ISR(&mux);
      if(millis() - last > 5) queueSend(...); // 5ms防抖
      portEXIT_CRITICAL_ISR(&mux);
    }

📌 终极结论

  • 竞技场景(格斗/射击游戏):选程序1(μs级响应决定胜负)

  • 策略/RPG场景:选程序2(复杂宏操作更有优势)

  • 推荐升级方向:程序1扩展多键中断 + 程序2关键键改用中断触发

全部评论

·