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]);
}