FastLED.h 阻止 ezButton.h

Posted

技术标签:

【中文标题】FastLED.h 阻止 ezButton.h【英文标题】:FastLED.h blocks ezButton.h 【发布时间】:2020-08-20 06:28:45 【问题描述】:

我正在使用 Arduino 来控制一个包含可寻址 LED 和按钮的项目。 我正在使用的库在标题中。 由于未知的原因,当我单独使用每个代码时,一切正常,但是当我将它们组合起来时,FastLED 库会阻止按钮读取并导致奇怪的事情——比如双击,或者停止做其他事情。

我该如何解决这个问题? (我试图消除延迟(),但它没有帮助) 提前致谢!

/*
  Author: Yuval Kedar - KD Technology
  Instagram: https://www.instagram.com/kd_technology/
  Date: Oct 19
  Dev board: Arduino Uno
  
    There are two button types: Red and Blue.
    Red btn = -1
    Blue btn = +1

    On the machine's background there is an LED matrix which shows the user's progress.
    There are 4 levels (square frames) until one reaches the core and wins.

    The trick? The floor, which includes the buttons, is spinning.
*/

#include <FastLED.h>
#include <ezButton.h>
#include "Arduino.h"

#define WINNING_SENSOR_PIN (12)
#define LED_DATA_PIN (6)
#define BLUE_BTN_PIN (A0)
#define RED_BTN_PIN (A3)

#define SERIAL_BAUDRATE (115200)
#define NUM_LEDS (64)
#define LED_BRIGHTNESS (200)
#define WINNING_FX_TIME (1000)

ezButton blue_btn(BLUE_BTN_PIN);
ezButton red_btn(RED_BTN_PIN);
CRGB leds[NUM_LEDS];

uint8_t score = 0;
uint8_t last_score = 0;
uint8_t level[] = 0, 28, 48, 60, 63;  //levels 0 to 4

void level_up(uint8_t led_num) 
    uint8_t start_point = 0;
    if (led_num == level[1]) start_point = 0;   //up from level 0 to 1
    if (led_num == level[2]) start_point = 28;  //up from level 1 to 2
    if (led_num == level[3]) start_point = 48;  //up from level 2 to 3
    if (led_num == level[4]) start_point = 60;  //...

    for (uint8_t current_pixel = start_point; current_pixel < led_num; current_pixel++) 
        leds[current_pixel] = CRGB::Blue;
        FastLED.show();
        delay(50);
    
    delay(2500); //debounce


void level_down(uint8_t led_num)   //clear prev level's frame and do the opposite direction effect with red color
    uint8_t start_point = 0;
    if (led_num == level[0]) start_point = 28;  //down from level 1 to 0
    if (led_num == level[1]) start_point = 48;  //down from level 2 to 1
    if (led_num == level[2]) start_point = 60;  //down from level 3 to 2
    if (led_num == level[3]) start_point = 63;  //...

    for (int8_t i = start_point - 1; i > led_num; i--) 
        leds[i] = CRGB::Red;
        FastLED.show();
        delay(50);
    
    for (int8_t i = start_point - 1; i > led_num; i--) 
        leds[i] = CRGB::Black;
        FastLED.show();
    
    delay(2500); //debounce


void fadeall() 
    for(uint8_t i = 0; i < NUM_LEDS; i++) 
        leds[i].nscale8(250);
    


void winning() 
    static uint8_t hue = 0;
    for(uint8_t x = 0; x < 5; x++) 
        for(int8_t i = 0; i < NUM_LEDS; i++) 
            leds[i] = CHSV(hue++, 255, 255);
            FastLED.show(); 
            fadeall();
            // delay(10);
        
        for(int8_t i = (NUM_LEDS)-1; i >= 0; i--) 
            leds[i] = CHSV(hue++, 255, 255);
            FastLED.show();
            fadeall();
            // delay(10);
        
    
    


void reset_game() 
    score = 0;
    last_score = 4;
    digitalWrite(WINNING_SENSOR_PIN, LOW);
    FastLED.clear();
    FastLED.show();

void winning_check() 
    (score == 4) ? analogWrite(WINNING_SENSOR_PIN, 175) : digitalWrite(WINNING_SENSOR_PIN, LOW);


void update_score() 
    if (blue_btn.isPressed()) 
        Serial.println("+PLUS+");
        if (score++ >= 4) score = 4;
    

    if (red_btn.isPressed()) 
        Serial.println("-MINUS-");
        if (score-- <= 0) score = 0;
    

    if (score == 0)
        if (last_score == 1) level_down(level[0]);
        last_score = 0;
        digitalWrite(WINNING_SENSOR_PIN, LOW);
    
    else if (score == 1) 
        if (last_score == 0) level_up(level[1]);    // if last_score was 0 make the blue effect because level is up
        if (last_score == 2) level_down(level[1]);  // if last_score was 2 make the red effect because level is down
        last_score = 1;
        digitalWrite(WINNING_SENSOR_PIN, LOW);
    
    else if (score == 2) 
        if (last_score == 1) level_up(level[2]);
        if (last_score == 3) level_down(level[2]);
        last_score = 2;
        digitalWrite(WINNING_SENSOR_PIN, LOW);
    
    else if (score == 3) 
        if (last_score == 2) level_up(level[3]);
        if (last_score == 4) level_down(level[3]);
        last_score = 3;
        digitalWrite(WINNING_SENSOR_PIN, LOW);
    
    else if (score == 4) 
        winning_check();
        // winning();  //this func makes issue when using ezButton.h. It calls "show" too many times.
        reset_game();
    


void setup() 
    Serial.begin(SERIAL_BAUDRATE);

    pinMode(WINNING_SENSOR_PIN, OUTPUT);
    digitalWrite(WINNING_SENSOR_PIN, LOW);

    blue_btn.setDebounceTime(150);
    red_btn.setDebounceTime(150);

    FastLED.addLeds<NEOPIXEL, LED_DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
    FastLED.setBrightness(LED_BRIGHTNESS);
    FastLED.clear();
    FastLED.show();


    Serial.println(F(
        "_______________________________\n"
        "\n"
        "   G e a r   M a c h i n e     \n"
        "_______________________________\n"
        "\n"
        "   ~ Made by KD Technology ~   \n"
        "\n"));


void loop() 
    blue_btn.loop();
    red_btn.loop();
    Serial.println(score);

    update_score();
    FastLED.show();


【问题讨论】:

不要经常在 LED 上做show(),更新所有然后显示所有更改。另外 - 延迟 2.5 秒肯定会影响按钮状态的读取方式/时间... 当我延迟 2.5 秒时,按钮不应该被按下,所以我不在乎(除非它影响代码和制造问题)。关于 show(),我正在制作需要更新每个像素更改的效果。我该怎么做? 您的程序花费(2.5 秒 + 10 毫秒* LED 数量)更新 LED,然后可能需要 1 毫秒左右检查按钮。这可能就是按钮显示被阻止的原因... 我刚刚检查过,如果我只调用一次 show() 并删除 delay() 效果很好。你能告诉我如何只调用一次 show() 仍然得到我想要的效果吗? 既然我现在知道你想要什么样的效果,我就不能那样做了。但是您可以尝试确保它仅在数据发生更改时更新 LED,而不是总是这样做。 【参考方案1】:

原因是,您使用了delay() 函数。如果你使用延迟,一些按下的事件将被错过,不仅对于 ezButton,而且对于任何类型的按钮按下实现。 ezButton 已经具有内部去抖动功能。

【讨论】:

以上是关于FastLED.h 阻止 ezButton.h的主要内容,如果未能解决你的问题,请参考以下文章

右键、阻止冒泡

阻止默认事件,滚轮事件与滚动事件

jquery 阻止默认行为

在jq中看到”阻止冒泡“,请问阻止冒泡啥意思?

vue阻止冒泡事件 阻止点击事件的执行 结合div和组件阻止点击事件

js阻止默认事件与js阻止事件冒泡示例分享 js阻止冒泡事件