Multiple Short Led strip setup help

I found a warpcore project and I had a 24 LED neopixel strip, so I hacked up a crude warpcore for the laboratory here.

I didn't realize how much I was missing without this! It is almost as good as having a Jacob's Ladder cranking away, that hallmark of serious scientific undertakings.

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library

// http://alexrobertscreations.blogspot.com/2015/02/3d-printed-mini-star-trek-next.html

/* hacked just a bit by alto777 */

#include <Adafruit_NeoPixel.h>

#define PIN            6

# define NUMPIXELS      24
# define MAXPIXEL		23

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

int delayval = 92; // cycle time NUMPIXELS / 2 * delayval, adjust to taste

void setup() {
  pixels.begin();
}

# define X255	99
# define X100	47
# define X40	15

void loop() {
while(1){
  for(int i = MAXPIXEL; i >= (NUMPIXELS/2); i--) {

    pixels.setPixelColor(i, pixels.Color(0,0,X255)); // Blue Bright
    pixels.setPixelColor(i+1, pixels.Color(0,0,X100)); // Blue Medium
    pixels.setPixelColor(i+2, pixels.Color(0, 0, X40)); // Blue Dim
    pixels.setPixelColor(MAXPIXEL-i, pixels.Color(0,0,X255));
    pixels.setPixelColor(MAXPIXEL-(i+1), pixels.Color(0, 0, X100));
    pixels.setPixelColor(MAXPIXEL-(i+2), pixels.Color(0, 0, X40));

    pixels.show(); // This sends the updated pixel color to the hardware.
    delay(delayval); // Delay for a period of time (in milliseconds).

    pixels.setPixelColor(i, pixels.Color(0,0,0));
    pixels.setPixelColor(i+1, pixels.Color(0,0,0));    
    pixels.setPixelColor(i+2,pixels.Color(0,0,0));
    pixels.setPixelColor(MAXPIXEL-i,pixels.Color(0,0,0));
    pixels.setPixelColor(MAXPIXEL-(i+1),pixels.Color(0,0,0));
    pixels.setPixelColor(MAXPIXEL-(i+2),pixels.Color(0,0,0));
  }
}
}

Make one for yourself. Replace that ozone monster and safety hazard you are using now.

a7

If you use high power PWM, you have to pay close attention to conductor layout and bypassing, otherwise you will be radiating strong RFI at multiple frequencies and in all directions.

jimLee:
NeoPixles, one wire, daisy chaining ring to ring. Write the code for one ring. Then, set it up with a linked list of rings.

Well, that's how I'd do it.. Actually, have a library for doing that.

-jim lee

I think i may go this route, seems easier
i went ahead and got some of these https://www.amazon.com/gp/product/B018X04ES2/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
figured it's about the same price to buy components to wire my dumb leds and saves time.

I will use a 5v 2.0amp usb charger for the power, since i'm only powering AT MOST, with effects, 36 leds at one time but not all at full brightness.

So each strip i will use will have 9 leds. I can't power that from a PWM pin, so i'll have to split the power to the Arduino and led strips...then connect the data line of each strip to each PWM pin right? Now there are 22 strips total to run, but only 12 PWM pins. Can i run 2 strips from each pin? Since two strips are to be lit at once anyway.

I've got my mega wired up to power supply , usb (disconnecting power while usb plugged in) and led strip and i'm playing with it. I got a test sketch to run a loop of different effects on my 8 led test strip. it works fine.

how would i write a sketch to light each pin in sequence while turning off the previous pin.

Also i keep seeing some recommend a resistor between data wire and pwm pin...is that required or just a safety precaution?

Ready to buy the Corvette huh?

-jim lee

The LEDs you linked are so-called “smart”.

You will not need PWM.

You do not need more than one output pin to run them.

You do need to learn about this smart LED or neopixel technology.

I posted a simple working warp core program in this thread, take a look. Much nicer animations are possible by upping the frame rate. I did some inspiring experiments running at 100 FPS.

a7

i actually did try out your sketch to test, but i'm not using multiple long strips vertically to create that chase, i'm using 22 separate 9led strips placed horizontally and need each strip lit in that chase pattern.

Right.

Doing it with the strip's LEDs placed differently in your warp core, you just have to do a little math on the fly to figure out, at each step, which of all the LEDs should be bright, medium or dim.

If you have 9 LEDs in each ring, just light up LEDs 0 trough 8 to light up the first ring.

The Nth ring would be LED number (N - 1) * 9 and the next 8.

13th ring is LED 117, 118, 119 &c.

Write a subroutine (oops, function) to set a given ring N to bright, medium, dim or off. Slot it into my sketch. Boom.

Or use someone else's abstraction to split the strip into sections conceptual ly.

a7

alto777:
The LEDs you linked are so-called “smart”.

You will not need PWM.

You do not need more than one output pin to run them.

You do need to learn about this smart LED or neopixel technology.

If the link you are referring to is in reply #14, it is clearly not a smart strip. Compare one of the product images to the close up in reply #15, it is a passive strip.

Reply #22, smart:

HTH

a7

aarg:
If the link you are referring to is in reply #14, it is clearly not a smart strip. Compare one of the product images to the close up in reply #15, it is a passive strip.

That makes sense to me, so with doing this. .I would need to solder each ring in series, as if they were never cut. instead of running each ring to a seperate pin. each ring sitting above parallel to the next, solder the ends at a 45 degree angle to the next lower rings end. with only 8led per ring, that gives me 5 1/2 in strips. more space between ends to solder. 6in strips almost touched..too tight for me.

Yes. You are on the right track.

You can get a quick feel for it and test firmware by simply wrapping the uncut strip around a cylinder object of appropriate diameter - the rings will be slanted, but if the circumference is right, the rings elements will line up. Even if not exact, it will still be an inspiring display. Don't ask how I know that. :wink:

Another entire area of research is the diffusing of the ring LEDs. I've had some luck with tissue paper and photography filter gel… and I would truly love to add some good warp core background throbbing sound effects, yeah that's the ticket.

a7

this is what i am printing. as you can see, the rings are printed in semi opaque filament...it diffuses the light very well. as long as led aren't too close to the inside wall, if too close than you see the concentration of light from each led.

alto777:
I found a warpcore project and I had a 24 LED neopixel strip, so I hacked up a crude warpcore for the laboratory here.

I didn't realize how much I was missing without this! It is almost as good as having a Jacob's Ladder cranking away, that hallmark of serious scientific undertakings.

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson

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

// Alex Roberts Creations: 3D Printed Mini Tabletop Warp Core

/* hacked just a bit by alto777 */

#include <Adafruit_NeoPixel.h>

#define PIN            6

define NUMPIXELS      24

define MAXPIXEL 23

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

int delayval = 92; // cycle time NUMPIXELS / 2 * delayval, adjust to taste

void setup() {
 pixels.begin();
}

define X255 99

define X100 47

define X40 15

void loop() {
while(1){
 for(int i = MAXPIXEL; i >= (NUMPIXELS/2); i--) {

pixels.setPixelColor(i, pixels.Color(0,0,X255)); // Blue Bright
   pixels.setPixelColor(i+1, pixels.Color(0,0,X100)); // Blue Medium
   pixels.setPixelColor(i+2, pixels.Color(0, 0, X40)); // Blue Dim
   pixels.setPixelColor(MAXPIXEL-i, pixels.Color(0,0,X255));
   pixels.setPixelColor(MAXPIXEL-(i+1), pixels.Color(0, 0, X100));
   pixels.setPixelColor(MAXPIXEL-(i+2), pixels.Color(0, 0, X40));

pixels.show(); // This sends the updated pixel color to the hardware.
   delay(delayval); // Delay for a period of time (in milliseconds).

pixels.setPixelColor(i, pixels.Color(0,0,0));
   pixels.setPixelColor(i+1, pixels.Color(0,0,0));    
   pixels.setPixelColor(i+2,pixels.Color(0,0,0));
   pixels.setPixelColor(MAXPIXEL-i,pixels.Color(0,0,0));
   pixels.setPixelColor(MAXPIXEL-(i+1),pixels.Color(0,0,0));
   pixels.setPixelColor(MAXPIXEL-(i+2),pixels.Color(0,0,0));
 }
}
}




Make one for yourself. Replace that ozone monster and safety hazard you are using now.

a7

so i tried this, it's cool and it's helping me ot learn better by altering it and see the effects in real time. Rather than read a website tutorial.

I added more leds then less to each row to see how wide i could make the pattern. so i am learning. Now that i see how it works in CHASE..."chase" is not exactly what i want. instead of having the leading leds start to fade in and the trailing fade out..i want 8 leds to just TURN ON for x amount of time, then when they turn off, the next 8 leds turn on....so on. As if each ring were a seperate strip being turned off\on individually. I believe that means setting up arrays with 8 leds each ..then going from there....still absorbing all of this.

Trying to change the first program as little as possible more, I changed it to animate a set of rings. The key function and idea are at the bottom - expandRings takes each ring value and copies it to ring number of LEDs.

The first three # define set up the hardware parameters.

Oh, look at the Adafruit_Neopixel call that creates the pixels object. I have RGBW LEDs, just put the right constant in there for the LEDs you have.

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library

// http://alexrobertscreations.blogspot.com/2015/02/3d-printed-mini-star-trek-next.html

/* hacked just a bit more by alto777 */

# include <Adafruit_NeoPixel.h>

# define NRINGS	20
# define KPER	12
# define PIN            6

# define NUMPIXELS      (NRINGS * KPER)
# define MAXPIXEL		(NUMPIXELS - 1)

/* virtual array, each element is the value for a ring section */
/* + 3 is a kludge for obviating array range check! */
unsigned long ring[NRINGS];

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);

int delayval = 92; // cycle time NUMPIXELS / 2 * delayval, adjust to taste

void setup() {
  Serial.begin(115200);
  Serial.println("Warp Core Rings");

  pixels.begin();
}

# define X255	50
# define X100	20
# define X40	5

unsigned int counta = 0;

void loop() {
while (1)
  for(int i = NRINGS; i >= (NRINGS/2); i--) {

    ring[i] = pixels.Color(0, 0, X255); // Blue Bright
    ring[i + 1] = pixels.Color(0, 0, X100); // Blue Medium
    ring[i + 2] = pixels.Color(0, 0, X40); // Blue Dim
    ring[NRINGS - i] = pixels.Color(0, 0, X255);
    ring[NRINGS - (i + 1)] = pixels.Color(0, 0, X100);
    ring[NRINGS - (i + 2)] = pixels.Color(0, 0, X40);

	expandRings();

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

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

    ring[i] = pixels.Color(0, 0, 0);
    ring[i + 1] = pixels.Color(0, 0, 0);  
    ring[i + 2] = pixels.Color(0, 0, 0);
    ring[NRINGS - i] = pixels.Color(0, 0, 0);
    ring[NRINGS - (i + 1)] = pixels.Color(0, 0, 0);
    ring[NRINGS - (i + 2)] = pixels.Color(0, 0, 0);
  }
}

void expandRings()
{
	unsigned int pixel = 0;

	for (unsigned char ii = 0; ii < NRINGS; ii++)
		for (unsigned char kk = 0; kk < KPER; kk++, pixel++)
			pixels.setPixelColor(pixel, ring[ii]);
}

HTH.

a7

I believe that means setting up arrays with 8 leds each ..then going from there

The arrays are already setup. This is how the library works. Its just one long array you write colors to.

When I do stuff like this I just write one ring. Decide how that ring will act from time 0 - off through time n - off.

Are you guys comfortable with creating classes etc. because this is screaming for a one ring class that you stack in a list. Each would do its on->off animation then trigger the next ones that its linked to on the list.

One ring class and a list that's linked in order of flashing.

-jim lee

I discovered an error in the code in post #33. The original author relied on setPixel to quietly handle setting non-existent pixels. I tried to fix it w/o properly analysing the entire problem; the program started to work so WTH.

But. Removing the Serial.begin from setup causes some error to manifest. Believing entirely that it was a matter of writing outside of array bonds, I tweaked the code a bit to allow for range checking. The code below works and at this moment I believe is behaving correctly. [EDIT: I looked closely at the original program and indeed it goes outside the array on both sides, so my confidence in the fix is high.]

@jimlee I wondered when you would get around/back to your very good suggestion. I do believe, however, that for beginners there is something to be said for studying and writing little programs like these, which are what I call more literal expressions of algorithms. I learned when modern abstractions were not popular, widely known or even in existence, and I think coming up that way allows more flexibility and creativity, especially when we are talking about dinky little LED chasers.

Just to see directly the reaction between hardware and lines of code.

I would want two classes (for starts). One for a ring, as suggested. The other I am thinking about would be a classic of classes, so to speak, the first of which would implement sort of a "traveler", that is a light effect that moves by a set of rules and parameters, so in the warp core case, when the high speed second shock wave of also a different energy level is added like Geordi thought might work and Picard said "make it so", it's just another instance of a traveler.

One can imagine that other light animation things could be done similart.

Also I see coming a problem where real LEDs might be involved with several animated objects. I'd like to make the each real LED capable of combining the states of all entities wanting to illuminate it.

OMG there is a tiny tiny spider walking around on my screen!

Anyway, this is works:

It still has the annoying inside out for loop and a while() the original author used to kludge that up. Easily fixed, don't care - it works and isn't the starting point, for me, for advancing this. Just a nice hack to prove the concept, test the hardware and inspire.

Sorry about the bogus hacked error-not-free code earlier. Mind the LED type in the strip object creation! I have RGBW strips…

a7

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library

// http://alexrobertscreations.blogspot.com/2015/02/3d-printed-mini-star-trek-next.html

/* hacked just a bit more by alto777 */

#include <Adafruit_NeoPixel.h>

# define NRINGS	20
# define KPER	12

#define PIN            6

# define NUMPIXELS      (NRINGS * KPER)
# define MAXPIXEL		(NUMPIXELS - 1)

/* virtual array, each element is the value for a ring section */
/* + 3 was a kludge for obviating array range check! */
unsigned long ring[NRINGS];

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);

int delayval = 92; // cycle time NUMPIXELS / 2 * delayval, adjust to taste

void setup() {
  pixels.begin();
}

# define X255	50
# define X100	20
# define X40	5

unsigned int counta = 0;

void loop() {
while (1)
  for(int i = NRINGS; i >= (NRINGS/2); i--) {
    setRingColor(i, pixels.Color(0,0,X255)); // Blue Bright
    setRingColor(i+1, pixels.Color(0,0,X100)); // Blue Medium
    setRingColor(i+2, pixels.Color(0, 0, X40)); // Blue Dim
    setRingColor(NRINGS-i, pixels.Color(0,0,X255));
    setRingColor(NRINGS-(i+1), pixels.Color(0, 0, X100));
    setRingColor(NRINGS-(i+2), pixels.Color(0, 0, X40));

    expandRings();

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

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

    setRingColor(i, pixels.Color(0,0,0));
    setRingColor(i+1, pixels.Color(0,0,0));    
    setRingColor(i+2,pixels.Color(0,0,0));
    setRingColor(NRINGS-i,pixels.Color(0,0,0));
    setRingColor(NRINGS-(i+1),pixels.Color(0,0,0));
    setRingColor(NRINGS-(i+2),pixels.Color(0,0,0));
  }
}

void setRingColor(int theRing, unsigned long theColor)
{
	if ((theRing < 0) || (theRing >= NRINGS)) return;

	ring[theRing] = theColor;
}

void expandRings()
{
	unsigned int pixel = 0;

	for (unsigned char ii = 0; ii < NRINGS; ii++)
		for (unsigned char kk = 0; kk < KPER; kk++, pixel++)
			pixels.setPixelColor(pixel, ring[ii]);
}

Hey guys, thanks for effort here. I deliver for amazon..10-12hrdays, 5 days a week. I'm exhausted and don't work on project on those days, but I do check her every few days.. until I get back to working on it. thanks.

FWIW- I have 785 LEDs in an outdoor Christmas display tree running on a Wemos D1 Mini and it's all on one GPIO port. For one effect where random colors fall "down" the tree, I defined a 33x24 2-dimensional array that identifies the LED numbers for each ring. A simple for loop provides the effect. Starting at the top each ring is lit up in succession with 10ms between them.

- YouTube is what i've got so far.

Many of my pieces are printed yet. Center chambe is an 18hr print and ABS is hard to print when it's really cold out even with an enclosure. The base requires me know how tall all the wiring and arudino will be AFTER the lighting is done.

I need to change colors to all blue, not RBG. I played with the code (from original that Alto777 made me) to narrow down to 2 "ring" lit (as set up in the video) because Nring 32 and Kper 8 made it look like 5 rows were lit at once, but i will change the all of that AFTER i cut the strips up and secure them to the pipe. I was just playing with it to see how it changes everything.

One thing i noticed, every 3 leds lit it skips an led all together. I need ALL lit otherwise you can see the missing light between leds. I changed to 7 leds...and because it's skipping on every 3.. each segment is 10 leds. Meaning led 1 is blue, 2(off), 3,4,5(grb) 6(off) 7,8,9(grb), 10(off). How do i change that so every led is on

/* warp core display by alto777, thassall */
/* animate chase pattern on ring virtual display elements */

# define NRINGS  92
# define KPER 2

unsigned long timeTo;

# define TICK 600   /* 100 frames/ second */

# define OFF  13
# define ON   14
# define WAX  15
# define WANE 16
# define DWELL  17

/* lamp abstraction section */
/* modify this block for different smart LED types or library

 need
 (creation of the LED strip object)
 initLamps any initialization
 lampSet sets one LED to a color
 lampGet returns the color of one LED
 lampsShow transfer the current strip colors to the actual strip

*/
# include <Adafruit_NeoPixel.h>

# define PIN 6
# define NLAMPS (NRINGS * KPER)

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NLAMPS, PIN, NEO_GRBW + NEO_KHZ800);

void initLamps()
{
  strip.begin();
  for (int ii = 0; ii < NLAMPS; ii++)
    lampSet(ii, 0x0L);
  strip.show();
}

void lampSet(int theLamp, unsigned long theColor)
{
  strip.setPixelColor(theLamp, theColor);
}

unsigned long lampGet(int theLamp)
{
  strip.getPixelColor(theLamp);
}

void lampsShow()
{
    strip.show();
}
/* end lamp abstraction section */

typedef struct {
  unsigned char state;
  unsigned long color;    // just 0..0xff right now.
  unsigned int timerToo;
} element;

element theRINGS[NRINGS];

void setup() {
  Serial.begin(115200);
  Serial.println("PWM Warpcore RINGS v2");

  timerOneInit();

  pinMode(13, OUTPUT);
  timeTo = fakeMilcros();

  for (unsigned char ii = 0; ii < NRINGS; ii++)
    setRingState(ii, (ii & 0x1) ? OFF : ON);

  initLamps();    /* those be the real LEDs */
}

void setRingState(unsigned char theLED, unsigned char onOff)
{
  theRINGS[theLED].state = onOff;
}

/* color all LEDs from each ring identically
   "color" is, at this point 0..0xff, so is used here just as intensity for one
   of the bytes in the GRBW long. Scale and shift in the lampSet call:
  
BLUE
bright theRINGS[ii].color
dim    theRINGS[ii].color >> 2

GREEN
bright theRINGS[ii].color << 8
dim    (theRINGS[ii].color >> 3) << 8  

RED
bright theRINGS[ii].color << 16
dim    (theRINGS[ii].color >> 3) << 16  

WHITE
bright theRINGS[ii].color << 24
dim    (theRINGS[ii].color >> 3) << 24  
*/

void expandRings()
{
  unsigned int pixel = 0;

  for (unsigned char ii = 0; ii < NRINGS; ii++)
    for (unsigned char kk = 0; kk < KPER; kk++, pixel++)
      lampSet(pixel, theRINGS[ii].color >> 3);
}

/* run all the LED FSMs */
void ageLEDs()
{
  for (unsigned char ii = 0; ii < NRINGS; ii++) {
    switch (theRINGS[ii].state) {

    case ON :   /* the agent has turned on an LED */
      theRINGS[ii].state = WAX;
      theRINGS[ii].color = 0x10;

      break;

    case WAX :
      theRINGS[ii].color += 0x20;     /* intensity ramp up increment */
      if (theRINGS[ii].color >= 0xc0) { /* intensity max */
        theRINGS[ii].state = DWELL;
        theRINGS[ii].timerToo = 1;    /* how long to wait at max intensity */
      }
      break;

    case DWELL :
      if (!--theRINGS[ii].timerToo) theRINGS[ii].state = WANE;
      break;

    case WANE :
      if (theRINGS[ii].color >= 8) theRINGS[ii].color -= 8; /* intensity ramp down increment */
      else theRINGS[ii].state = OFF;

      break;

    case OFF :
      theRINGS[ii].color = 0;

      break;
    }

  } /* for every ring */
}

unsigned char bigTick;


void loop() {
  static unsigned char bigTick = 0;   /* divisor for ring speed */
  unsigned long timeTemp;

/* poor man's RTOS, hang on clock capability */   
  digitalWrite(13, HIGH);
  while ((timeTemp = fakeMilcros()) - timeTo < TICK)
    ;
  timeTo = timeTemp;
  digitalWrite(13, LOW);
  
/* at ~100 Hz */

  ageLEDs();

  if (++bigTick >= 8) {   /* every 8 frames */
    bigTick = 0;

    warpCoreFSM();      /* advance the ring */
  }

  expandRings();  
  lampsShow();
}

void warpCoreFSM()
{
  static unsigned char ring = 0;

/* the LEDs turn themselves off. ON triggers the standard profile */
//  setRingState(ring, OFF);
//  setRingState(MAXPIXEL - ring, OFF);

  ring++;
  if (ring >= NRINGS / 2) ring = 0;

  setRingState(ring, ON);
  setRingState(NRINGS - 1 - ring, ON);
}

/* functions to provide a simulated millis that does not care about interrupts */
/* voo doo. who do? you do! */
void timerOneInit()
{
 noInterrupts();           // disable all interrupts

  TCCR1A = 0;
  TCCR1B = 0;

  TCNT1  = 0;
  TCCR1B = TCCR1B & B11111000 | B00000100;    // set timer 1 divisor to ??? _not necessarily_ 256 for PWM frequency of   122.55 Hz

interrupts();             // enable all interrupts
}

unsigned int fakeMilcros()
{
  return (TCNT1);
}

First idea - make sure this

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NLAMPS, PIN, NEO_GRBW + NEO_KHZ800);

is consistent with your exact LED strip

a7