Arduino Polska Forum

Pełna wersja: Problem z wyjściem z petli przy sterowaniu efektami na WS2812B za pomocą pilota IR
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Witam mam problem z tym że jeśli za pomocą pilota wybiorę jakich efekt na moich pasku led WS2812B (300 diód) to nie mogę przełączyć na inny tryb ponieważ jest to otwarzane w nieskończonej pętli.
Pętla musi być ponieważ nie chcę po każdym skończeniu efektu znowu go wybierać. Proszę o pomoc i z góry dziękuje
Arduino Uno R3
Dioda IR 1838B + pilot Car mp3
5m WS2812B 60diód/m
Użyj przerwań, zapisuj w zmiennej jaką pętla ma lecieć, jak efekt zobaczy że zmienną nie odpowiada pętli która jest aktualna przerwie ja.
Niestety nie mam jak pobrać na telefonie.
Nie mniej, masz powyżej odpowiedź co trzeba zrobić Smile
Tutaj jest kawałek własnie tego kodu

void loop() {
irrecv.blink13(true); // mrugamy diodami w arduino
if (irrecv.decode(&results)) {

switch (results.value) {

case 0x511DBB: //przycisk1 ON
ZMIENNA=0;
poweron();
break;

case 0xE318261B: //przycisk2 OFF
ZMIENNA=0;
poweroff();
break;

case 0xD7E84B1B: //przycisk|<< KOLEJNY KOLOR
ZMIENNA=0;
if(ZMIENNAKOLORU<=9){ZMIENNAKOLORU++;}
USTAWKOLOR(); WYSWIETL();
break;

case 0x52A3D41F: //przycisk>>| COFNIJ KOLOR
ZMIENNA=0;
if(ZMIENNAKOLORU>=2){ZMIENNAKOLORU--;}
USTAWKOLOR(); WYSWIETL();
break;

case 0x9716BE3F: //przycisk1 EFEKT TECZA
ZMIENNA=1;
break;

case 0x3D9AE3F7: //przycisk2 EFEKT TECZA 2
ZMIENNA=2;
break;

case 0x6182021B: //przycisk3 PRZEJSCIE POMIEDZY R G B
ZMIENNA=3;
break;

case 0x8C22657B: //przycisk4 POJAWIĄJĄCE SIĘ LOSOWE ŚWIATEŁKA
ZMIENNA=4;
break;

case 0x488F3CBB: //przycisk5 METEORYT
ZMIENNA=5;
break;

case 0x00000009: //przycisk6
//ZMIENNA=X;
break;

//case 0x00000009: //przycisk6 KOPIA
//ZMIENNA=X;
//break;

}
irrecv.resume();
}
if (ZMIENNA == 1){rainbow(20);}
if (ZMIENNA == 2){theaterChaseRainbow(50);}
if (ZMIENNA == 3){RGBLoop();}
if (ZMIENNA == 4){TwinkleRandom(275, 110, false);}
if (ZMIENNA == 5){ meteorRain(random(0,255),random(0,255),random(0,255),25, 64, true, 30);}
//if (ZMIENNA == X){*efekt*}
//if (ZMIENNA == X){*efekt*}
//if (ZMIENNA == X){*efekt*}
//if (ZMIENNA == X){*efekt*}
//if (ZMIENNA == X){*efekt*} KOPIA
}
Dalej twierdzę, że musisz w pętli włączyć wykrywanie kodów pilota i by zmieniał w zależności co odczyta zmienną zmieniająca aktualnie uruchomiona pętlę. I w każdej pętli musi być takie coś.
error105 dobrze prawi.
Struktura kodu jest do przebudowania. Ustaw sobie przerwanie od pilota i wartość zmiennej ZMIENNA ustawiaj w przerwaniu. W każdej pętli odpowiadającej za efekt świetlny, w najbardziej zagnieżdżonej pętli for musisz cyklicznie sprawdzać wartość tej zmiennej i jeśli nie jest tą, która odpowiada za ten efekt, to Break.
Przerwanie od pilota zakłóci komunikację z LED. Ponadto, libs Arduino zawieszają przerwania na czas komunikacji z LED. Problem rozwiąże transmisja do LED przez UART w przerwaniu. Wypróbowane w praktyce, poza dekodowaniem IR ok 20 standardów na przerwaniu 15kHz, realizowana jest komunikacja po przez UART z ESP oczywiście w przerwaniach, USB po I2C, zapis na kartę SD i multipleksowany LED 7-SEG, Ostatecznie może być SPI. Najlepiej jednak użyć DMA.
Można nie używać DMA i obciążać CPU w 100% i mieć problemy z obsługą pilota.
Można się namęczyć aby na AVR (na ARM tak 7..20 razy łatwiej) sterować LED'ami przez UART na przerwaniach. Z obsługa pilota nie będzie problemu.

Chcesz bez DMA, przerwań, DA SIĘ!
Nakombinujesz się wstawiając jakieś sprawdzania w czasie wystawiania "L" do WS2812 czy jest aktywne wejście odbiornika IR, obsłużysz go. Wszystko będzie chodzić kulawo, bo w czasie transmisji IR LED będzie głupieć.
Ja bym takiego szmelcu nie chciał.

Rób jak uważasz.
Rozwiązanie na USART + IRQ na AVR działa, obciążenie CPU 80..90%.
Z DMA obciążenie 1..2% zależnie od uC, zegara.
Dostałeś dwa rozwiązania, jedno proste do zastosowania drugie ciut więcej będzie gimnastyki wymagało (chyba że jesteś na tyle biegły w programowaniu, ale czy wtedy szukałbyś pomocy ?).
Tak na prawdę program do migania ledem może być bardziej zaawansowany Smile