Доброе утро господа! Подскажите пожалуйста, есть простенький проект, ардуинка, кнопка, LED лента, задача кнопкой переключать эффекты. Все эффекты в процедурах, в основном цикле в зависимости от переменной выбирается эффект… И всё вроде работает, но с костылём! Дело в том, что при нажатии на кнопку, хочется сразу видеть новый эффект, но из за блокирующих циклов эффект продолжает работать пока не закончит работу и только потом перепрыгивает на новый.
Вопрос, как в данном коде грамотно реализовать моментальный выход из эффекта?
Пока это сделано путям помещения переменной в память и перезагрузки контроллера, что в принципе работает но я считаю это костыль… Быть может есть что то более изящное?
#define BUTTON 2
volatile byte counter = 1;
//=============================
#include <EEPROM.h>
#include "Adafruit_NeoPixel.h"
#define PIN 5
#define NUM_LEDS 28
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
int yarkost = 96;
void setup() {
Serial.begin(115200);
pinMode(BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON), buttonPressed, CHANGE);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
strip.setBrightness(yarkost);
EEPROM.get(0, counter);
}
void loop() {
// Serial.println(counter);
switch(counter) {
case 1: {
strip.setBrightness(yarkost);
for(int i=0; i< 5; i++) {
colorWipe ( 0x00 , 0xff , 0x00 , 5 ) ;
colorWipe ( 0x00 , 0x00 , 0xff , 5 ) ;
colorWipe ( 0xff , 0x00 , 0x00 , 5 ) ;
}
FadeOUT();
strip.setBrightness(yarkost);
for(int i=0; i< 10; i++) Rpulse();
strip.setBrightness(yarkost);
rainbowCycle(7);
FadeOUT();
strip.setBrightness(yarkost);
for(int i=0; i< 10; i++) Bpulse();
strip.setBrightness(yarkost);
for(int i=0; i< 8; i++) {
meteorRain(0xff,0xff,0xff, 20, 32, false, 50);
}
FadeOUT();
setAll(0,0,0);
break;
}
case 2: {
strip.setBrightness(yarkost);
Bpulse();
break;
}
case 3: {
strip.setBrightness(yarkost);
Rpulse();
break;
}
case 4: {
strip.setBrightness(yarkost);
rainbowCycle(7);
FadeOUT();
break;
}
case 5: {
strip.setBrightness(yarkost);
meteorRain(0xff,0xff,0xff, 20, 32, false, 50);
FadeOUT();
setAll(0,0,0);
break;
}
case 6: {
FadeOUT();
setAll(0,0,0);
break;
}
}
}
//===================
void buttonPressed() {
if ( digitalRead ( BUTTON ) == LOW ) {
counter ++;
if (counter > 6)counter = 1;
EEPROM.put(0, counter);
asm volatile ("jmp 0");
}
}
void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
setAll(0,0,0);
for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) {
// fade brightness all LEDs one step
for(int j=0; j<NUM_LEDS; j++) {
if( (!meteorRandomDecay) || (random(10)>5) ) {
fadeToBlack(j, meteorTrailDecay );
}
}
// draw meteor
for(int j = 0; j < meteorSize; j++) {
if( ( i-j <NUM_LEDS) && (i-j>=0) ) {
setPixel(i-j, red, green, blue);
}
}
showStrip();
delay(SpeedDelay);
}
}
void fadeToBlack(int ledNo, byte fadeValue) {
// NeoPixel
uint32_t oldColor;
uint8_t r, g, b;
int value;
oldColor = strip.getPixelColor(ledNo);
r = (oldColor & 0x00ff0000UL) >> 16;
g = (oldColor & 0x0000ff00UL) >> 8;
b = (oldColor & 0x000000ffUL);
r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
b=(b<=10)? 0 : (int) b-(b*fadeValue/256);
strip.setPixelColor(ledNo, r,g,b);
}
void rainbowCycle(int SpeedDelay) {
byte *c;
uint16_t i, j;
for(j=0; j<256*10; j++) { // 5 cycles of all colors on wheel
for(i=0; i< NUM_LEDS; i++) {
c=Wheel(((i * 256 / NUM_LEDS) + j) & 255);
setPixel(i, *c, *(c+1), *(c+2));
}
showStrip();
delay(SpeedDelay);
}
}
byte * Wheel(byte WheelPos) {
static byte c[3];
if(WheelPos < 85) {
c[0]=WheelPos * 3;
c[1]=255 - WheelPos * 3;
c[2]=0;
} else if(WheelPos < 170) {
WheelPos -= 85;
c[0]=255 - WheelPos * 3;
c[1]=0;
c[2]=WheelPos * 3;
} else {
WheelPos -= 170;
c[0]=0;
c[1]=WheelPos * 3;
c[2]=255 - WheelPos * 3;
}
return c;
}
//=====================
void colorWipe ( byte red , byte green , byte blue , int SpeedDelay ) {
for ( uint16_t i = 0 ; i < NUM_LEDS ; i ++ ) {
setPixel ( i , red , green , blue ) ;
showStrip ( ) ;
delay ( SpeedDelay ) ;
}
}
void FadeOUT() {
// Fade OUT
for(int k = yarkost; k > 0; k--) {
strip.setBrightness(k);
showStrip();
delay(5);
}
}
void Rpulse() {
// Fade IN
for(int k = 50; k < 256; k=k+15) {
setAll(k,0,0);
showStrip();
delay(5);
}
// Fade OUT
for(int k = 255; k >= 180; k=k-3) {
setAll(k,0,0);
showStrip();
delay(3);
}
for(int k = 179; k >= 10; k--) {
setAll(k,0,0);
showStrip();
delay(15);
}
}
void Bpulse() {
// Fade IN
for(int k = 50; k < 256; k=k+15) {
setAll(0,k,k);
showStrip();
delay(5);
}
// Fade OUT
for(int k = 255; k >= 180; k=k-3) {
setAll(0,k,k);
showStrip();
delay(3);
}
for(int k = 179; k >= 10; k--) {
setAll(0,k,k);
showStrip();
delay(15);
}
}
//=====================
void RGBpulse(){
for(int j = 0; j < 3; j++ ) {
// Fade IN
for(int k = 0; k < 256; k++) {
switch(j) {
case 0: setAll(k,0,0); break;
case 1: setAll(0,k,0); break;
case 2: setAll(0,0,k); break;
}
showStrip();
delay(5);
}
// Fade OUT
for(int k = 255; k >= 0; k--) {
switch(j) {
case 0: setAll(k,0,0); break;
case 1: setAll(0,k,0); break;
case 2: setAll(0,0,k); break;
}
showStrip();
delay(5);
}
}
}
void showStrip() {
strip.show();
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
}
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
showStrip();
}