Go Down

Topic: Neopixel Project Struggles  (Read 1 time) previous topic - next topic

alonsoperez1st

So I've been messing around with the Star Wars style death lamp project which I modified with one 60 RGB LED ring and another small 24 RGB LED ring. I've got one mode that does a twinkle effect that affects both rings and another mode that affects the 60 LED ring which it makes the ring go in loops through different colors. (I am new at this and only have like a month of experience in this) I've been trying to compile both of these codes together, so the twinkle effect is outputted in pin 3 and the loop effect is outputted in pin 2.

Here's the twinkle effect:
Code: [Select]

#include <Adafruit_NeoPixel.h>

#define PIN 2
#define Pixels 84

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 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)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(Pixels, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

float redStates[Pixels];
float blueStates[Pixels];
float greenStates[Pixels];
float fadeRate = 0.93;

/* A name for the switch on pin 2. */
int sw = 2;
/* A name for the LED on pin 13. */
int ledPin = 2;
 
void setup()
{
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
 
  for(uint16_t l = 0; l < Pixels; l++) {
    redStates[l] = 0;
    greenStates[l] = 0;
    blueStates[l] = 0;
      /* Set the LED pin as output. */
  pinMode(sw, INPUT);
  /* Set the LED pin as output. */
  pinMode(ledPin, OUTPUT);
  }
}
 
void loop()
{
  if (digitalRead(sw) == 1) {
      /* Turn on the LED. */
    digitalWrite(ledPin, HIGH);
  }
  else {
       /* Turn off the LED. */
    digitalWrite(ledPin, LOW);
  }

   if (random(2) == 1) {
      uint16_t i = random(Pixels);
      if (redStates[i] < 1 && greenStates[i] < 1 && blueStates[i] < 1) {
        redStates[i] = random(256);
        greenStates[i] = random(256);
        blueStates[i] = random(256);
      }
    }
   
    for(uint16_t l = 0; l < Pixels; l++) {
      if (redStates[l] > 1 || greenStates[l] > 1 || blueStates[l] > 1) {
        strip.setPixelColor(l, redStates[l], greenStates[l], blueStates[l]);
       
        if (redStates[l] > 1) {
          redStates[l] = redStates[l] * fadeRate;
        } else {
          redStates[l] = 0;
        }
       
        if (greenStates[l] > 1) {
          greenStates[l] = greenStates[l] * fadeRate;
        } else {
          greenStates[l] = 0;
        }
       
        if (blueStates[l] > 1) {
          blueStates[l] = blueStates[l] * fadeRate;
        } else {
          blueStates[l] = 0;
        }
       
      } else {
        strip.setPixelColor(l, 0, 0, 0);
      }
    }
    strip.show();
    delay(10);
 
}


And here is the "loop" effect:
Code: [Select]

// NeoPixel Ring simple sketch
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN            2

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      60

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int delayval = 50; // delay for half a second

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code

  pixels.begin(); // This initializes the NeoPixel library.
}

void loop() {

  // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.

  for(int i=0;i<NUMPIXELS;i++){

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(0,255,0)); // Moderately bright green color.

    pixels.show(); // This sends the updated pixel color to the hardware.

    delay(delayval); // Delay for a period of time (in milliseconds).
  }
    // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.

  for(int i=0;i<NUMPIXELS;i++){

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(0,0,0)); // LEDs Off.

    pixels.show(); // This sends the updated pixel color to the hardware.

    delay(delayval); // Delay for a period of time (in milliseconds).
  }  // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.

  for(int i=0;i<NUMPIXELS;i++){

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(255,0,0)); // Moderately bright red color.

    pixels.show(); // This sends the updated pixel color to the hardware.

    delay(delayval); // Delay for a period of time (in milliseconds).
  }
    // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.

  for(int i=0;i<NUMPIXELS;i++){

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(0,0,0)); // LEDs Off.

    pixels.show(); // This sends the updated pixel color to the hardware.

    delay(delayval); // Delay for a period of time (in milliseconds).
  }  // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.

  for(int i=0;i<NUMPIXELS;i++){

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(0,0,255)); // Moderately bright Blue color.

    pixels.show(); // This sends the updated pixel color to the hardware.

    delay(delayval); // Delay for a period of time (in milliseconds).
  }
    // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.

  for(int i=0;i<NUMPIXELS;i++){

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(0,0,0)); // LEDs Off.

    pixels.show(); // This sends the updated pixel color to the hardware.

    delay(delayval); // Delay for a period of time (in milliseconds).
  }
}


It has been a challenge for me, but i got no where near close to finishing it, i know for sure that i should not use the delay() but instead use milli() but that has become very confusing for me. It would be an honor to have someone advice me on what i should do, I will definitely keep working on this and will keep you updated. Thank you!

PaulS

Code: [Select]
for(uint16_t l = 0; l < Pixels; l++) {
    redStates[l] = 0;
    greenStates[l] = 0;
    blueStates[l] = 0;
      /* Set the LED pin as output. */
  pinMode(sw, INPUT);
  /* Set the LED pin as output. */
  pinMode(ledPin, OUTPUT);
  }

Why do you need to set the mode of the two pins 84 times? Why not 168? Or 1?

The pixel colors are int. Why are you storing the data in floats?

You need to complete scrap all that code and start over. You will have ONE loop - the loop() function.

On every pass through loop(), it might, or might not, be time to do something. Look at the blink without delay example to see how to determine that.

If it is time to twinkle another pixel, make whatever changes are needed to the color of a specific pixel, and set the color of the pixel.

If it is time to do something in the loop, do that.

It will always be time to call strip.show(), even if nothing has changed.
The art of getting good answers lies in asking good questions.

PaulMurrayCbr

Yeah, if you want two run two asynchronous things, you can't use delay().


The two effects can be re-engineered to not use delay. The basic trick is that each place where delay is used becomes a 'state', a sort of resting-spot, because most of the time the code is doing nothing else other than delaying.

I'll tell you what: I'll have a bash at it. The result won't be proper, tested code or anything. I'll just hack up what you have to show you how it's done.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

PaulMurrayCbr

#3
Jun 13, 2017, 04:28 am Last Edit: Jun 13, 2017, 04:30 am by PaulMurrayCbr
Ok, man. This isn't the best way to write your particular thing, however, it demonstrates how to unroll a loop with delays into code without delays, and it demonstrates one way to combine two sketches.

I have kept most of your comments and whatnot so that you can perhaps see how the code has been moved around. Unrolling code like this is kinda-sorta a mechanical thing. As a result, there's a huge amount of repeated code. For instance, the 'fade to black' code is duplicated. You could clean this up quite a bit.

Enjoy.

Code: [Select]

#include "Adafruit_NeoPixel.h"

void setup() {
  twinkle_setup();
  loop_setup();
}

void loop() {
  twinkle_loop();
  loop_loop();
}


/////// TWINKLE EFFECT /////////



#define twinkle_PIN 2
#define twinkle_Pixels 84

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 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)
Adafruit_NeoPixel twinkle_strip = Adafruit_NeoPixel(twinkle_Pixels, twinkle_PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

float twinkle_redStates[twinkle_Pixels];
float twinkle_blueStates[twinkle_Pixels];
float twinkle_greenStates[twinkle_Pixels];
float twinkle_fadeRate = 0.93;

/* A name for the switch on pin 2. */
int twinkle_sw = 2;
/* A name for the LED on pin 13. */
int twinkle_ledPin = 2;

const unsigned long twinkle_delay_ms = 10;
unsigned long twinkle_mark_ms; // setting this value to millis() starts a delay

void twinkle_setup() {
  twinkle_strip.begin();
  twinkle_strip.show(); // Initialize all pixels to 'off'

  for (uint16_t l = 0; l < twinkle_Pixels; l++) {
    twinkle_redStates[l] = 0;
    twinkle_greenStates[l] = 0;
    twinkle_blueStates[l] = 0;
    /* Set the LED pin as output. */
    pinMode(twinkle_sw, INPUT);
    /* Set the LED pin as output. */
    pinMode(twinkle_ledPin, OUTPUT);
  }

  twinkle_mark_ms = millis() - twinkle_delay_ms;
}

void twinkle_loop() {
  if (millis() - twinkle_mark_ms < twinkle_delay_ms) return;

  if (digitalRead(twinkle_sw) == 1) {
    /* Turn on the LED. */
    digitalWrite(twinkle_ledPin, HIGH);
  }
  else {
    /* Turn off the LED. */
    digitalWrite(twinkle_ledPin, LOW);
  }

  if (random(2) == 1) {
    uint16_t i = random(twinkle_Pixels);
    if (twinkle_redStates[i] < 1 && twinkle_greenStates[i] < 1 && twinkle_blueStates[i] < 1) {
      twinkle_redStates[i] = random(256);
      twinkle_greenStates[i] = random(256);
      twinkle_blueStates[i] = random(256);
    }
  }

  for (uint16_t l = 0; l < twinkle_Pixels; l++) {
    if (twinkle_redStates[l] > 1 || twinkle_greenStates[l] > 1 || twinkle_blueStates[l] > 1) {
      twinkle_strip.setPixelColor(l, twinkle_redStates[l], twinkle_greenStates[l], twinkle_blueStates[l]);

      if (twinkle_redStates[l] > 1) {
        twinkle_redStates[l] = twinkle_redStates[l] * twinkle_fadeRate;
      } else {
        twinkle_redStates[l] = 0;
      }

      if (twinkle_greenStates[l] > 1) {
        twinkle_greenStates[l] = twinkle_greenStates[l] * twinkle_fadeRate;
      } else {
        twinkle_greenStates[l] = 0;
      }

      if (twinkle_blueStates[l] > 1) {
        twinkle_blueStates[l] = twinkle_blueStates[l] * twinkle_fadeRate;
      } else {
        twinkle_blueStates[l] = 0;
      }

    } else {
      twinkle_strip.setPixelColor(l, 0, 0, 0);
    }
  }
  twinkle_strip.show();
  twinkle_mark_ms = millis();
}


/////// LOOP EFFECT /////////


// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define loop_PIN            3

// How many NeoPixels are attached to the Arduino?
#define loop_NUMPIXELS      60

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel loop_pixels = Adafruit_NeoPixel(loop_NUMPIXELS, loop_PIN, NEO_GRB + NEO_KHZ800);

unsigned long loop_delayval = 50; // delay for half a second

unsigned long loop_mark_ms; // setting this value to millis() starts a delay

int loop_step; // this balue ranges from 1 to 6 - not from 0 to 5
int loop_i;

void loop_setup() {

  loop_pixels.begin(); // This initializes the NeoPixel library.

  loop_mark_ms = millis() - loop_delayval;
  loop_step = 1;
  loop_i = 0;
}

void loop_loop() {
  if (millis() - loop_mark_ms < loop_delayval) return;

  switch (loop_step) {
    case 1:
      if (loop_i < loop_NUMPIXELS) {
        loop_pixels.setPixelColor(loop_i, loop_pixels.Color(0, 255, 0)); // Moderately bright green color.
        loop_pixels.show(); // This sends the updated pixel color to the hardware.
        loop_mark_ms = millis();
        loop_i++;
      }
      else {
        loop_i = 0;
        loop_step++;
      }
      break;

    case 2:
      if (loop_i < loop_NUMPIXELS) {
        loop_pixels.setPixelColor(loop_i, loop_pixels.Color(0, 0, 0)); // LEDs Off.
        loop_pixels.show(); // This sends the updated pixel color to the hardware.
        loop_mark_ms = millis();
        loop_i++;
      }
      else {
        loop_i = 0;
        loop_step++;
      }
      break;

    case 3:
      if (loop_i < loop_NUMPIXELS) {
        loop_pixels.setPixelColor(loop_i, loop_pixels.Color(255, 0, 0)); // Moderately bright red color.
        loop_pixels.show(); // This sends the updated pixel color to the hardware.
        loop_mark_ms = millis();
        loop_i++;
      }
      else {
        loop_i = 0;
        loop_step++;
      }
      break;

    case 4:
      if (loop_i < loop_NUMPIXELS) {
        loop_pixels.setPixelColor(loop_i, loop_pixels.Color(0, 0, 0)); // LEDs Off.
        loop_pixels.show(); // This sends the updated pixel color to the hardware.
        loop_mark_ms = millis();
        loop_i++;
      }
      else {
        loop_i = 0;
        loop_step++;
      }
      break;
      break;

    case 5:
      if (loop_i < loop_NUMPIXELS) {
        loop_pixels.setPixelColor(loop_i, loop_pixels.Color(0, 0, 255)); // Moderately bright Blue color.
        loop_pixels.show(); // This sends the updated pixel color to the hardware.
        loop_mark_ms = millis();
        loop_i++;
      }
      else {
        loop_i = 0;
        loop_step++;
      }
      break;

    case 6:
      if (loop_i < loop_NUMPIXELS) {
        loop_pixels.setPixelColor(loop_i, loop_pixels.Color(0, 0, 0)); // LEDs Off.
        loop_pixels.show(); // This sends the updated pixel color to the hardware.
        loop_mark_ms = millis();
        loop_i++;
      }
      else {
        loop_i = 0;
        loop_step = 1;
      }
      break;
  }


}

http://paulmurraycbr.github.io/ArduinoTheOOWay.html

Go Up