Почему я не могу выйти из цикла while, читая из serial?
Я пытаюсь работать с библиотеками FastLED и управляю светодиодным Stip через WEMOS D1 MINI на базе ESP8266, чего я пытаюсь добиться, так это перехода от анимации fastled к другой .. эти анимации находятся внутри цикла While, как показано в коде, поэтому я подумал: просто прочитайте еще раз из серийного номера, чтобы изменить целое число для выхода из цикла while, но по какой-то причине оно работает не так, как ожидалось. Кто-нибудь может помочь мне понять?
CRGB leds[NUM_LEDS];
int incomingByte = 0;
int exit = 0;
void setup() {
Serial.begin(115200);
delay( 1000 );
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );
}
void loop()
{
while (Serial.available()>0)
{
Serial.write("Serial.available");
incomingByte = Serial.read();
switch (incomingByte)
{
case '1':
GreenYellow();
break;
case '2':
Sparkle();
break;
}
}
}
void Sparkle() {
while(exit = 0){
int Pixel = random(NUM_LEDS);
setPixel(Pixel,random(255),random(255),random(255));
FastLED.show();
delay(50);
setPixel(Pixel,0,0,0);
if(Serial.available()>0){
incomingByte = Serial.read();
if(incomingByte != '2'){
exit = 1;
}
}
}
}
}
void GreenYellow()
{
for(int x =0; x< NUM_LEDS/2; x++){
leds[x]= CRGB::Green;
}
for(int x =NUM_LEDS/2; x< NUM_LEDS; x++){
leds[x]= CRGB::Yellow;
}
FastLED.show();
}
void setPixel(int Pixel, byte red, byte green, byte blue)
{
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
FastLED.show();
}
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
FastLED.show();
}
Бонусный вопрос: я читал, что на ESP2866 нет программирования потоков через Arduino IDE, я прав?
@FabioEnne, 👍0
1 ответ
Проблема в том, что вы проверяете внутри двух функций Sparkle
и GreenYellow
наличие другого последовательного байта. Затем, когда он неравен, вы возвращаетесь к циклу while, где ждете следующего последовательного байта, но я думаю, что вам нужно использовать тот же самый байт, чтобы решить перейти к правильной функции, а не ждать следующего последовательного байта.
Вероятно, проще всего не читать serial в цикле while, а проверить
глобальную переменную incomingByte (содержащую последний прочитанный байт и, например, 1 изначально), и ТОЛЬКО в двух функциях установить эту глобальную переменную. Затем, возвращаясь к циклу
while, вы проверяете эту глобальную переменную, чтобы перейти к правильной функции.
Таким образом, вы создаете функцию установки, которая устанавливает глобальную переменную в 1 (или вы делаете это в самой инициализации):
int incomingByte = 1; // Начать с GreenYellow
Затем в функции цикла
вы используете:
void loop()
{
switch (incomingByte)
{
case '1':
GreenYellow();
break;
case '2':
Sparkle();
break;
}
}
Если вы не хотите начинать ни с того, ни с другого, то используйте 3 значения (0, 1, 2) и ТОЛЬКО в функции цикла
считывайте последовательный байт, но не считывайте его в функциях.
Таким образом, он немного чище, так как отделяет функциональность светодиода от последовательной функциональности.
Результат (используя последний метод), приводит к следующему коду (компилируется, не проверяется).
Комментарии:
Использовал перечисление для режима
Разделение функций последовательных данных, обработка режимов и подпрограмм RGB
Я добавил некоторые строки инициализации (т.Е. константы), чтобы сделать его компилируемым.
#include <FastLED.h> #define NUM_LEDS 60 // количество светодиодов, присутствующих в вашей ленте #define LED_PIN 6 #define BRIGHTNESS 100 enum EMode { ModeNone, ModeSparkle, ModeGreenYellow }; CRGB leds[NUM_LEDS]; EMode mode; void ParseSerialData(); void ProcessMode(); void GreenYellow(); void Sparkle(); void setPixel(int Pixel, byte red, byte green, byte blue); void setup() { Serial.begin(115200); delay( 1000 ); FastLED.addLeds<WS2811, LED_PIN, EOrder::RGB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); FastLED.setBrightness( BRIGHTNESS ); mode = EMode::ModeNone; } void loop() { ParseSerialData(); ProcessMode(); } void ParseSerialData() { while (Serial.available() > 0) { Serial.write("Serial.available"); char incomingByte = Serial.read(); switch (incomingByte) { case '1': mode = EMode::ModeGreenYellow; break; case '2': mode = EMode::ModeSparkle; break; default: // Игнорировать break; } } } void ProcessMode() { switch (mode) { case EMode::ModeNone: // Ничего не делать break; case EMode::ModeGreenYellow: GreenYellow(); break; case EMode::ModeSparkle: Sparkle(); break; default: // Игнорировать break; } } void Sparkle() { int Pixel = random(NUM_LEDS); setPixel(Pixel,random(255),random(255),random(255)); FastLED.show(); delay(50); setPixel(Pixel,0,0,0); } void GreenYellow() { for(int x =0; x< NUM_LEDS/2; x++) { leds[x]= CRGB::Green; } for(int x =NUM_LEDS/2; x< NUM_LEDS; x++) { leds[x]= CRGB::Yellow; } FastLED.show(); } void setPixel(int Pixel, byte red, byte green, byte blue) { leds[Pixel].r = red; leds[Pixel].g = green; leds[Pixel].b = blue; FastLED.show(); } void setAll(byte red, byte green, byte blue) { for(int i = 0; i < NUM_LEDS; i++ ) { setPixel(i, red, green, blue); } FastLED.show(); }
- Как создать несколько запущенных потоков?
- Как читать и записывать EEPROM в ESP8266
- Как сделать выводы Tx и Rx на ESP-8266-01 в выводах GPIO?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Как заставить 5-вольтовое реле работать с NodeMCU
- Как исправить: Invalid conversion from 'const char*' to 'char*' [-fpermissive]
- ESP8266 не подключается к Wi-Fi
- AT-команда не отвечает на последовательный монитор
спасибо за повтор, можете ли вы изменить мой фрагмент кода? Мне трудно понять ваше решение, так что, возможно, чтение кода поможет. Спасибо., @FabioEnne
Я бы пошел другим путем. Оставьте все последовательные чтения внутри функции
цикл
. Удалите цикл while внутри функцииSparkle
. Сохраните текущий режим, который был выбран, в переменной. Затем вцикле
вызовите функцию, основанную на текущем режиме., @Gerben@Gerben Я тоже, но первое было самым "простым", а не самым чистым решением., @Michel Keijzers
Я попытался изменить код (он компилируется)... Я удалил код выхода и попытался навести порядок., @Michel Keijzers