Skocz do zawartości

Przerwanie działania pętli


Pomocna odpowiedź

Napisano

Witam

Mam problem z przerwaniem działania pętli po naciśnięciu przycisku w przerwaniu zewnętrznym (przycisk zwiera do masy)

pętla:

void rainbow(uint8_t wait) {
 uint16_t i, j;

 do {
   digitalWrite(LED, LOW);
   j++;
   if (j > 256){
     j == 0;
   }
     for (i = 0; i < strip_1.numPixels(); i++) {
     strip_1.setPixelColor(i, Wheel((i + j) & 255));
     strip_2.setPixelColor(i, Wheel((i + j) & 255));
     strip_3.setPixelColor(i, Wheel((i + j) & 255));
   }
   strip_1.show();
   strip_2.show();
   strip_3.show();
   delay(wait);

 } while (logika == 1);
 logika = 0;
}

przerwanie:

void przycisk() {
 logika = 1;
 digitalWrite(LED, HIGH);
}

ustawienia:

volatile byte logika = 0;
attachInterrupt(digitalPinToInterrupt(2), przycisk, LOW);
pinMode(BUTTON_PIN, INPUT_PULLUP);

w przerwaniu zapalam diodę a w pętli gaszę więc moim zdaniem samo przerwanie jest obsługiwane poprawnie.

A nie masz przypadkiem problemu z wartościami zmiennej "logika" (nie najlepsza nazwa)? W przerwaniu ustawiasz na 1, pętlę wykonujesz dopóki wartość wynosi właśnie 1... chyba powinno być 0.

wklejam cały kod jedynie bez wszystkich funkcji wywoływanych z switcha

jest to przykłady kod do obsługi WS2812B

różnica polega ba tym że chcę aby tryb rainbow wykonywał się cały czas w kółko aż do wciśnięcia przycisku i przejściu do kolejnego trybu.

ewidentnie chyba coś źle robię tylko co?

#include <Adafruit_NeoPixel.h>

#define BUTTON_PIN  2
#define PIXEL_COUNT 8
#define LED 13

Adafruit_NeoPixel strip_1 = Adafruit_NeoPixel(PIXEL_COUNT, 5, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_2 = Adafruit_NeoPixel(PIXEL_COUNT, 6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_3 = Adafruit_NeoPixel(PIXEL_COUNT, 7, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH;
int showType = 0;
volatile byte logika = 1;

void setup() {
 pinMode(BUTTON_PIN, INPUT_PULLUP);
 pinMode(LED, OUTPUT);
 digitalWrite(LED, LOW);
 strip_1.begin();
 strip_1.show();
 strip_2.begin();
 strip_2.show();
 strip_3.begin();
 strip_3.show();
 attachInterrupt(digitalPinToInterrupt(2), przycisk, LOW);
}

void loop() {
 bool newState = digitalRead(BUTTON_PIN);
 if (newState == LOW && oldState == HIGH) {
   // Short delay to debounce button.
   delay(20);
   newState = digitalRead(BUTTON_PIN);
   if (newState == LOW) {
     showType++;
     if (showType > 9)
       showType = 0;
     startShow(showType);
   }
 }
 oldState = newState;
}

void startShow(int i) {
 switch (i) {
   case 0: colorWipe(strip_1.Color(0, 0, 0), 0);    // Black/off
     colorWipe(strip_2.Color(0, 0, 0), 0);
     colorWipe(strip_3.Color(0, 0, 0), 0);
     break;
   case 1: colorWipe(strip_1.Color(255, 0, 0), 20);  // Red
     colorWipe(strip_2.Color(255, 0, 0), 20);
     colorWipe(strip_3.Color(255, 0, 0), 20);
     break;
   case 2: colorWipe(strip_1.Color(0, 255, 0), 20);  // Green
     colorWipe(strip_2.Color(0, 255, 0), 20);
     colorWipe(strip_3.Color(0, 255, 0), 20);
     break;
   case 3: colorWipe(strip_1.Color(0, 0, 255), 20);  // Blue
     colorWipe(strip_2.Color(0, 0, 255), 20);
     colorWipe(strip_3.Color(0, 0, 255), 20);
     break;
   case 4: theaterChase(strip_1.Color(255, 255, 255), 20); // White
     theaterChase(strip_2.Color(255, 255, 255), 20);
     theaterChase(strip_3.Color(255, 255, 255), 20);
     break;
   case 5: theaterChase(strip_1.Color(255,   0,   0), 20); // Red
     theaterChase(strip_2.Color(255,   0,   0), 20);
     theaterChase(strip_3.Color(255,   0,   0), 20);
     break;
   case 6: theaterChase(strip_1.Color(  0,   0, 255), 20); // Blue
     theaterChase(strip_2.Color(  0,   0, 255), 20);
     theaterChase(strip_3.Color(  0,   0, 255), 20);
     break;
   case 7: 
     logika = 1;
     rainbow(50);
     break;
   case 8: rainbowCycle(20);
     break;
   case 9: theaterChaseRainbow(50);
     break;
 }
}
void rainbow(uint8_t wait) {
 uint16_t i, j;

 //for(j=0; j<256; j++) {
 do {
   digitalWrite(LED, LOW);
   j++;
   if (j > 256){
     j == 0;
   }
     for (i = 0; i < strip_1.numPixels(); i++) {
     strip_1.setPixelColor(i, Wheel((i + j) & 255));
     strip_2.setPixelColor(i, Wheel((i + j) & 255));
     strip_3.setPixelColor(i, Wheel((i + j) & 255));
   }
   strip_1.show();
   strip_2.show();
   strip_3.show();
   delay(wait);

 } while (logika == 1);
 logika = 1;
}

void przycisk() {
 logika = 0;
 digitalWrite(LED, HIGH);
}

zmieniłem na 0 ale efekt jest dokładnie bez zmian, tak jakby wartość zmiennej logika nie była brana pod uwagę po jej zmianie w przerwaniu

Albo ja coś źle rozumuje albo...

jak program wejdzie do pętli to nie ma prawa wykonać nić innego poza komendami zawartymi w pętli (pomijam przerwania) więc polecenie logika==1 zaraz za pętlą nie ma prawa się wykonać.

Ale dla pewności wywaliłem tą linijkę i przyniosło to żadnych rezultatów.

Nie uruchamiam zaraz rainbow() w loop().

A problem rozwiązany zmiana sposoby wyzwalania przerwania z poziomu niskiego na zbocze opadające rozwiązało wszystko.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...