This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
DUDA Adafruit Neo Pixel, 2 aros led a diferentes ms...? SOLUCIONADO
#1
Información 
Hola a todos, como están?

Le cuento que tengo 2 ring leds HW-159 de 7 leds cada uno (imagen 1). El primero quiero que este con una animación por ejemplo rainbow() con una velocidad de 500ms y el segundo al mismo tiempo con (por ejemplo) theaterChaseRainbow() en 900ms ambos con la librería de Adafruit Neo Pixel y no logro que funcionen bien. El código que estoy compartiendo es uno de los códigos de ejemplo que vienen con la librería de NeoPixel la cual reemplaza la función delay() por millis(), ideal para lo que quiero hacer pero a la hora de agregar un segundo aro de led es donde fallo y uno de los dos hace mal el efecto.  

Imagen 1:
[Imagen: ring-led.jpg]

Link a la librería:
https://github.com/adafruit/Adafruit_NeoPixel

Componentes:
- Arduino UNO R3.
- 2 ring leds HW-159.

Esquema:
- Pin 3 conectado al led ring 1.
- Pin 5 conectado al led ring 2.

Código original:
Código:
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

#define LED_PIN    3 //Aro 1
#define LED_COUNT    7 //Leds por aro
#define LED_PIN2    5//Aro 2

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); //Aro 1

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip2(LED_COUNT, LED_PIN2, NEO_GRB + NEO_KHZ800); //Aro 2

unsigned long pixelPrevious = 0;        // Previous Pixel Millis
unsigned long patternPrevious = 0;      // Previous Pattern Millis
int          patternCurrent = 0;      // Current Pattern Number
int          patternInterval = 5000;  // Pattern Interval (ms)
int          pixelInterval = 50;      // Pixel Interval (ms)
int          pixelQueue = 0;          // Pattern Pixel Queue
int          pixelCycle = 0;          // Pattern Pixel Cycle
uint16_t      pixelCurrent = 0;        // Pattern Current Pixel Number
uint16_t      pixelNumber = LED_COUNT;  // Total Number of Pixels

// setup() function -- runs once at startup --------------------------------
void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.
  strip.begin();          // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)

  strip2.begin();          // INITIALIZE NeoPixel strip object (REQUIRED)
  strip2.show();            // Turn OFF all pixels ASAP
  strip2.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
}
// loop() function -- runs repeatedly as long as board is on ---------------
void loop() {
  unsigned long currentMillis = millis();                    //  Update current time
  if((currentMillis - patternPrevious) >= patternInterval) {  //  Check for expired time
    patternPrevious = currentMillis;
    patternCurrent++;                                        //  Advance to next pattern
    if(patternCurrent >= 7)
      patternCurrent = 0;
  }
 
  if(currentMillis - pixelPrevious >= pixelInterval) {        //  Check for expired time
    pixelPrevious = currentMillis;                            //  Run current frame
    switch (patternCurrent) {
      case 7:
        theaterChaseRainbow(50); 
        theaterChaseRainbow2(120);
        break;
      case 6:
        rainbow(10); 
        break;   
      case 5:
        theaterChase(strip.Color(0, 0, 127), 50); // Blue
        break;
      case 4:
        theaterChase(strip.Color(127, 0, 0), 50); // Red
        break;
      case 3:
        theaterChase(strip.Color(127, 127, 127), 50); // White
        break;
      case 2:
        colorWipe(strip.Color(0, 0, 255), 50); // Blue
        break;
      case 1:
        colorWipe(strip.Color(0, 255, 0), 50); // Green
        break;       
      default:
        colorWipe(strip.Color(255, 0, 0), 50); // Red
        break;
    }
  }
}
void colorWipe(uint32_t color, int wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                  //  Update delay time
  strip.setPixelColor(pixelCurrent, color); //  Set pixel's color (in RAM)
  strip.show();                            //  Update strip to match
  pixelCurrent++;                          //  Advance current pixel
  if(pixelCurrent >= pixelNumber)          //  Loop the pattern from the first LED
    pixelCurrent = 0;
}
void theaterChase(uint32_t color, int wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                  //  Update delay time
  for(int i = 0; i < pixelNumber; i++) {
    strip.setPixelColor(i + pixelQueue, color); //  Set pixel's color (in RAM)
  }
  strip.show();                            //  Update strip to match
  for(int i=0; i < pixelNumber; i+=3) {
    strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0)); //  Set pixel's color (in RAM)
  }
  pixelQueue++;                            //  Advance current pixel
  if(pixelQueue >= 3)
    pixelQueue = 0;                        //  Loop the pattern from the first LED
}
// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(uint8_t wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                 
  for(uint16_t i=0; i < pixelNumber; i++) {
    strip.setPixelColor(i, Wheel((i + pixelCycle) & 255)); //  Update delay time 
  }
  strip.show();                            //  Update strip to match
  pixelCycle++;                            //  Advance current cycle
  if(pixelCycle >= 256)
    pixelCycle = 0;                        //  Loop the cycle back to the begining
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                  //  Update delay time 
  for(int i=0; i < pixelNumber; i+=3) {
    strip.setPixelColor(i + pixelQueue, Wheel((i + pixelCycle) % 255)); //  Update delay time 
  }
  strip.show();
  for(int i=0; i < pixelNumber; i+=3) {
    strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0)); //  Update delay time 
  }     
  pixelQueue++;                          //  Advance current queue 
  pixelCycle++;                          //  Advance current cycle
  if(pixelQueue >= 3)
    pixelQueue = 0;                      //  Loop
  if(pixelCycle >= 256)
    pixelCycle = 0;                      //  Loop
}
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void theaterChaseRainbow2(uint8_t wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                  //  Update delay time 
  for(int i=0; i < pixelNumber; i+=3) {
    strip2.setPixelColor(i + pixelQueue, Wheel2((i + pixelCycle) % 255)); //  Update delay time 
  }
  strip2.show();
  for(int i=0; i < pixelNumber; i+=3) {
    strip2.setPixelColor(i + pixelQueue, strip2.Color(0, 0, 0)); //  Update delay time 
  }     
  pixelQueue++;                          //  Advance current queue 
  pixelCycle++;                          //  Advance current cycle
  if(pixelQueue >= 3)
    pixelQueue = 0;                      //  Loop
  if(pixelCycle >= 256)
    pixelCycle = 0;                      //  Loop
}

uint32_t Wheel2(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip2.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip2.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip2.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Calculo que mi error viene por no duplicar las variables de tiempo (pixelCycle, pixelQueue, etc) ahora que redacto esta duda en el foro pero también con esto abro la siguiente pregunta, hay alguna forma mas prolija de hacerlo? No encontré en las funciones de Adafruit Neo Pixel la posibilidad de agregar otro modulo led con distinta animación o delay/tiempo pero no quiere decir que no exista, alguien sabe si existe?

Cualquier consejo será bienvenido.
Muchas gracias!
  Responder
#2
Lo solucione!

Por si a alguien mas le sirve les dejo el código. En si es hacer funcionar dos aros led a distinto tiempo o tipo de animación uno de otro.

Código:
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif


#define LED_PIN1    3
#define LED_PIN2    5

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 7

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip1(LED_COUNT, LED_PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2(LED_COUNT, LED_PIN2, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 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)
//  NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)

unsigned long pixelPrevious = 0;        // Previous Pixel Millis
unsigned long patternPrevious = 0;      // Previous Pattern Millis
int          patternCurrent = 0;      // Current Pattern Number
int          patternInterval = 5000;  // Pattern Interval (ms)
int          pixelInterval = 50;      // Pixel Interval (ms)
int          pixelQueue = 0;          // Pattern Pixel Queue
int          pixelCycle = 0;          // Pattern Pixel Cycle
uint16_t      pixelCurrent = 0;        // Pattern Current Pixel Number
uint16_t      pixelNumber = LED_COUNT;  // Total Number of Pixels

/////////////////////////////////////////////////////////////////////////////
unsigned long pixelPrevious2 = 0;        // Previous Pixel Millis
unsigned long patternPrevious2 = 0;      // Previous Pattern Millis
int          patternCurrent2 = 0;      // Current Pattern Number
int          patternInterval2 = 5000;  // Pattern Interval (ms)
int          pixelInterval2 = 50;      // Pixel Interval (ms)
int          pixelQueue2 = 0;          // Pattern Pixel Queue
int          pixelCycle2 = 0;          // Pattern Pixel Cycle
uint16_t      pixelCurrent2 = 0;        // Pattern Current Pixel Number
uint16_t      pixelNumber2 = LED_COUNT;  // Total Number of Pixels
/////////////////////////////////////////////////////////////////////////////


// setup() function -- runs once at startup --------------------------------
void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip1.begin();          // INITIALIZE NeoPixel strip object (REQUIRED)
  strip1.show();            // Turn OFF all pixels ASAP
  strip1.setBrightness(100); // Set BRIGHTNESS to about 1/5 (max = 255)

  strip2.begin();          // INITIALIZE NeoPixel strip object (REQUIRED)
  strip2.show();            // Turn OFF all pixels ASAP
  strip2.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
}

// loop() function -- runs repeatedly as long as board is on ---------------
void loop() {
  unsigned long currentMillis = millis();                    //  Update current time
 
  if((currentMillis - patternPrevious) >= patternInterval) {  //  Check for expired time
    patternPrevious = currentMillis;
    patternCurrent++;                                        //  Advance to next pattern
    if(patternCurrent >=2)//<<<<>>>>------------------------------------------------------------------>>>><<<<
      patternCurrent = 0;
  }

  if(currentMillis - pixelPrevious >= pixelInterval) {        //  Check for expired time
    pixelPrevious = currentMillis;                            //  Run current frame   

    //theaterChaseRainbow(50);
    switch (patternCurrent) {
      case 7:
        theaterChaseRainbow(50); // Rainbow-enhanced theaterChase variant
        break;
      case 6:
        rainbow(10); // Flowing rainbow cycle along the whole strip
        break;   
      case 5:
        theaterChase(strip1.Color(0, 0, 127), 50); // Blue
        break;
      case 4:
        theaterChase(strip1.Color(127, 0, 0), 50); // Red
        break;
      case 3:
        theaterChase(strip1.Color(127, 127, 127), 50); // White
        break;
      case 2:
        colorWipe(strip1.Color(0, 0, 255), 50); // Blue
        break;
      case 1:
        //colorWipe(strip1.Color(0, 255, 0), 50); // Green
        theaterChase(strip1.Color(255, 30, 0), 100);
        break;       
      default:
        //colorWipe(strip1.Color(255, 0, 0), 50); // Red
        theaterChase(strip1.Color(200, 20, 0), 70);
        break;
    }
  }

    unsigned long currentMillis2 = millis();
  if((currentMillis2 - patternPrevious2) >= patternInterval2) {  //  Check for expired time
    patternPrevious2 = currentMillis2;
    patternCurrent2++;                                        //  Advance to next pattern
    if(patternCurrent2 >=0)//<<<<>>>>------------------------------------------------------------------>>>><<<<
      patternCurrent2 = 0;
  }

  if(currentMillis2 - pixelPrevious2 >= pixelInterval2) {        //  Check for expired time
    pixelPrevious2 = currentMillis2;                            //  Run current frame 
    //Si presiono el boton

    colorWipe2(strip2.Color(0, 255, 0), 250); // Green
    //theaterChase2(strip2.Color(127, 127, 127), 150); // White
    //rainbow2(5);
    //theaterChase2(strip2.Color(  255, 30, 0), 120);
    //theaterChase2(strip2.Color(  255, 30, 0), 100);
    //theaterChaseRainbow2(80);
  } 
   
}

// Some functions of our own for creating animated effects -----------------

// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color, int wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                  //  Update delay time
  strip1.setPixelColor(pixelCurrent, color); //  Set pixel's color (in RAM)
  strip1.show();                            //  Update strip to match
  pixelCurrent++;                          //  Advance current pixel
  if(pixelCurrent >= pixelNumber)          //  Loop the pattern from the first LED
    pixelCurrent = 0;
}

void colorWipe2(uint32_t color2, int wait2) {
  Serial.println("s");
  if(pixelInterval2 != wait2)
    pixelInterval2 = wait2;                  //  Update delay time
  strip2.setPixelColor(pixelCurrent2, color2); //  Set pixel's color (in RAM)
  strip2.show();                            //  Update strip to match
  pixelCurrent2++;                          //  Advance current pixel
  if(pixelCurrent2 >= pixelNumber2)          //  Loop the pattern from the first LED
    pixelCurrent2 = 0;
}


// Theater-marquee-style chasing lights. Pass in a color (32-bit value,
// a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms)
// between frames.
void theaterChase(uint32_t color, int wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                  //  Update delay time 
  for(int i=0; i < pixelNumber; i+=3) {
    strip1.setPixelColor(i + pixelQueue, color); //  Update delay time 
  }
  strip1.show();
  for(int i=0; i < pixelNumber; i+=3) {
    strip1.setPixelColor(i + pixelQueue, strip1.Color(0, 0, 0)); //  Update delay time 
  }     
  pixelQueue++;                          //  Advance current queue 
  pixelCycle++;                          //  Advance current cycle
  if(pixelQueue >= 3)
    pixelQueue = 0;                      //  Loop
  if(pixelCycle >= 256)
    pixelCycle = 0;                      //  Loop                      //  Loop
}

void theaterChase2(uint32_t color2, int wait2) {
  if(pixelInterval2 != wait2)
    pixelInterval2 = wait2;                  //  Update delay time 
  for(int i=0; i < pixelNumber2; i+=3) {
    strip2.setPixelColor(i + pixelQueue2, color2); //  Update delay time 
  }
  strip2.show();
  for(int i=0; i < pixelNumber2; i+=3) {
    strip2.setPixelColor(i + pixelQueue2, strip2.Color(0, 0, 0)); //  Update delay time 
  }     
  pixelQueue2++;                          //  Advance current queue 
  pixelCycle2++;                          //  Advance current cycle
  if(pixelQueue2 >= 3)
    pixelQueue2 = 0;                      //  Loop
  if(pixelCycle2 >= 256)
    pixelCycle2 = 0;                      //  Loop
}

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(uint8_t wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                 
  for(uint16_t i=0; i < pixelNumber; i++) {
    strip1.setPixelColor(i, Wheel((i + pixelCycle) & 255)); //  Update delay time 
  }
  strip1.show();                            //  Update strip to match
  pixelCycle++;                            //  Advance current cycle
  if(pixelCycle >= 256)
    pixelCycle = 0;                        //  Loop the cycle back to the begining
}

void rainbow2(uint8_t wait2) {
  if(pixelInterval2 != wait2)
    pixelInterval2 = wait2;                 
  for(uint16_t i=0; i < pixelNumber2; i++) {
    strip2.setPixelColor(i, Wheel2((i + pixelCycle2) & 255)); //  Update delay time 
  }
  strip2.show();                            //  Update strip to match
  pixelCycle2++;                            //  Advance current cycle
  if(pixelCycle2 >= 256)
    pixelCycle2 = 0;                        //  Loop the cycle back to the begining
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  if(pixelInterval != wait)
    pixelInterval = wait;                  //  Update delay time 
  for(int i=0; i < pixelNumber; i+=3) {
    strip1.setPixelColor(i + pixelQueue, Wheel2((i + pixelCycle) % 255)); //  Update delay time 
  }
  strip1.show();
  for(int i=0; i < pixelNumber; i+=3) {
    strip1.setPixelColor(i + pixelQueue, strip1.Color(0, 0, 0)); //  Update delay time 
  }     
  pixelQueue++;                          //  Advance current queue 
  pixelCycle++;                          //  Advance current cycle
  if(pixelQueue >= 3)
    pixelQueue = 0;                      //  Loop
  if(pixelCycle >= 256)
    pixelCycle = 0;                      //  Loop                      //  Loop
}

void theaterChaseRainbow2(int wait2) {
  if(pixelInterval2 != wait2)
    pixelInterval2 = wait2;                  //  Update delay time 
  for(int i=0; i < pixelNumber2; i+=3) {
    //strip2.setPixelColor(i + pixelQueue2, color2); //  Update delay time 
    strip2.setPixelColor(i + pixelQueue2, Wheel2((i + pixelCycle2) % 255)); //  Update delay time 
  }
  strip2.show();
  for(int i=0; i < pixelNumber2; i+=3) {
    strip2.setPixelColor(i + pixelQueue2, strip2.Color(0, 0, 0)); //  Update delay time 
  }     
  pixelQueue2++;                          //  Advance current queue 
  pixelCycle2++;                          //  Advance current cycle
  if(pixelQueue2 >= 3)
    pixelQueue2 = 0;                      //  Loop
  if(pixelCycle2 >= 256)
    pixelCycle2 = 0;                      //  Loop
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip1.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip1.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip1.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

uint32_t Wheel2(byte WheelPos2) {
  WheelPos2 = 255 - WheelPos2;
  if(WheelPos2 < 85) {
    return strip2.Color(255 - WheelPos2 * 3, 0, WheelPos2 * 3);
  }
  if(WheelPos2 < 170) {
    WheelPos2 -= 85;
    return strip2.Color(0, WheelPos2 * 3, 255 - WheelPos2 * 3);
  }
  WheelPos2 -= 170;
  return strip2.Color(WheelPos2 * 3, 255 - WheelPos2 * 3, 0);
}

Seguramente hay mejores maneras de hacerlo, mas prolijas etc. pero por ahora esta funcional 100%. Luego me dedicare a hacer todo desde funciones únicas. También quiero aclarar que en este código que comparto esta corregido el error en la función theaterChase(); que por algún motivo Adafruit descuido en el archivo de ejemplo "standtest_nodelay.ino".

Espero ayude a alguien. Saludos!
  Responder


Posibles temas similares…
Tema Autor Respuestas Vistas Último mensaje
  CONTROLAR CUATRO TIRAS LED WS2812B CON ARDUINO NAVIDADES MAFALDA74 10 6,257 28-03-2019, 08:44 AM
Último mensaje: shiryou
  Tiras de Led NeoPixel. hansugrove 2 1,778 01-01-2018, 05:25 PM
Último mensaje: hansugrove
  led rgb tazma 3 1,721 06-05-2016, 03:46 PM
Último mensaje: WeSo
  Problema de parpadeo: Control de luz LED usando PWM lloyder 5 4,486 16-09-2015, 10:50 AM
Último mensaje: WeSo
  Proyecto: Iluminación Led para escritorio giltesa 25 13,231 07-09-2013, 08:49 PM
Último mensaje: Regata