Skocz do zawartości

Przerwanie działania pętli


morswin89

Pomocna odpowiedź

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.