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的主要内容,如果未能解决你的问题,请参考以下文章