• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Sterowanie Led WS2812B zmiana efektu przyciskiem bez opóźnienia
#1
Witam
Mam pytanie jak ustawić w tym szkicu, żeby zmiana efektu przyciskiem odbywała się bez opóźnienia. Ledy chce tak ustawić, żeby zapalały się co sekundę, ale kiedy ustawie co sekundę to po przyciśnięciu przycisku zmiana następuje po 28s, ponieważ pasek ma 30 diod a program liczy cały ten czas od wcisnięcia przycisku. Czy da się to ustawić, żeby pasek szedł rosnąco co sekundę do końca, a potem przycisk i od razu wraca malejąco co sekundę.


Kod:
#include <Adafruit_NeoPixel.h> // Biblioteka do sterowania diodami
#define PIN            6      // Pin do sterowania diodami ws2812
#define NUMPIXELS      30    // Ilość diod ws2812

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int licznik = 1;

void przycisk()
{
  delay(200);
  if (digitalRead(2)== LOW)
  {
    licznik++;
   
    if (licznik > 2)
    {
      licznik=1;
    }
  }
 
}

void efekt_1() 
{

  Serial.println("Efekt 1");
  for(int i=0;i <NUMPIXELS ;i++) // Zapalenie stopniowo całego paska na zielono
    {
        strip.setPixelColor(i, 0, 70, 200);
        strip.show();
        delay(1000);
    }


}


void efekt_2() // Zapalanie rosnąco
{
  Serial.println("Efekt 2");
  for(int i=NUMPIXELS;i >0 ;i--) // Gaszenie stopniowo całego paska na zielono
    {
        strip.setPixelColor(i, 0, 0, 0);
        strip.show();
        delay(1000);
    }
}
void setup()
{
  Serial.begin(9600);
  strip.begin(); // Uruchomienie działania biblioteki Adafruit_NeoPixel
  pinMode(2, INPUT);
  attachInterrupt(0, przycisk, FALLING);

 
}


void loop()
{
 

  switch (licznik)
  {
    case 1:
      efekt_1();
      break;

    case 2:
      efekt_2();
      break;
  }
 
 

}
 
Odpowiedź
#2
Nie używaj delay, możesz przerwać pętlę/funkcję używając break lub return. Przycisk odczytaj w przerwaniu PCINT lub INT lub w przerwaniu timera.
Ładniejsze efekty wymagają więcej wiedzy ogólnej, bardziej rozbudowany warsztat, znajomość większej ilości technik, blablabla - nauka.
 
Odpowiedź
#3
Niestety nie mam jeszcze takiej wiedzy,  kombinowałem w biblioteczce i udało mi się znaleźć i pozmieniać i uzyskałem efekt, który chciałem tylko nie wiem jak zmienić żeby po podłączeniu arduino od razu ledy się zapalały stopniowo, muszę wcisnąć dodatkowo guzik. Podpowiedziałbyś co trzeba usunąć, żeby po podłączeniu zasilania ledy sie zapały stopniowo bez wyzwalania guzikiem?


Kod:
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define BUTTON_PIN  2
#define PIXEL_PIN    6  // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 30  // Number of NeoPixels

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
boolean oldState = HIGH;
int    mode    = 0;    // Currently-active animation mode, 0-9

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin(); // Initialize NeoPixel strip object (REQUIRED)
  strip.show();  // Initialize all pixels to 'off'
}

void loop() {
  // Get current button state.
  boolean newState = digitalRead(BUTTON_PIN);

  // Check if state changed from high to low (button press).
  if((newState == LOW) && (oldState == HIGH)) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if(newState == LOW) {      // Yes, still low
      if(++mode > 1) mode = 0; // Advance to next mode, wrap around after #8
      switch(mode) {          // Start the new animation...
        case 0:
          colorWipe(strip.Color(  0,  0,  0), 50);    // Black/off
          break;
        case 1:
          colorWipe(strip.Color(255,  0,  0), 50);    // Red
          break;
   

      }
    }
  }

  // Set the last-read button state to the old state.
  oldState = newState;
}

void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, color);       
    strip.show();                         
    delay(1000);                         
  }
}
 
Odpowiedź
#4
Pierwszy program działał na przerwaniu (i dobrze) i wystarczyło w pętlach for(int i=0;i <NUMPIXELS ;i++),
wstawić gdzieś if(efekt==2) break; dla funkcji efekt_1() ;
oraz if(efekt==1) break; dla funkcji efekt_2() ;

Drugi program jest bardziej rozbudowany i podejrzewam, że blokuje się tak samo jak pierwszy, ale nie chciało mi się go czytać, bojest napisany bardzo nie optymalnie. To znaczy, że jeśli program miałby robić jeszcze inne rzeczy, to się wysypie (przez delaye). Te inne rzeczy to nawet sprawdzanie stanu przycisku, które mu nie wychodzą tak, jak wyjść powinny.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#5
Robson Kerman, dziękuję za pomoc dzisiaj jak wrócę to sprawdzę, spróbuję wstawić tak jak piszesz. To napisze czy mi się udało. Jeśli chodzi o pamięć arduino np na Uno ile można podłączyć takich ledow?
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości