Or directly drive the stepper without a library. Or use a different library -- 660steps/sec = 1515us/step which should be long enough to update a pretty big strip of neopixels.
From the Neopixel side, an update of 10 pixels should take 20*30us+50us = 300us which should leave plenty of time for a step. (Adafruit reference)
But this code updates NEO_COUNT times per update() so it takes 3000us per update:
void BlinkyPixel::update()
{
for (size_t i = 0; i < numPixels(); i++)
{
if (millis() >= timer[i].nextUpdateMillis)
{
if (timer[i].state)
{
setPixelColor(i, 0, 0, 0); // off
}
else
{
setPixelColor(i, colors[random(sizeof(colors)/sizeof(uint32_t))]); // random colour
//setPixelColor(i, random(0xFF), random(0xFF), random(0xFF));
}
timer[i].state = !timer[i].state;
timer[i].nextUpdateMillis = millis() + random(MIN_RANDOM_NUM, MAX_RANDOM_NUM);
}
show();
}
}
You could save a lot of time by moving the show() outside the for() loop. And if you set a flag for whether anything triggered inside the loop(), you could trim it further:
void BlinkyPixel::update()
{
bool dirty = false;
for (size_t i = 0; i < numPixels(); i++)
{
if (millis() >= timer[i].nextUpdateMillis)
{
dirty = true;
if (timer[i].state)
{
setPixelColor(i, 0, 0, 0); // off
}
else
{
setPixelColor(i, colors[random(sizeof(colors) / sizeof(uint32_t))]); // random colour
//setPixelColor(i, random(0xFF), random(0xFF), random(0xFF));
}
timer[i].state = !timer[i].state;
timer[i].nextUpdateMillis = millis() + random(MIN_RANDOM_NUM, MAX_RANDOM_NUM);
}
}
if (dirty) {
show();
}
}
I think those two changes would speed things up considerably. If you rate-limited the checks to every 2ms, it wouldn't be noticeable, and you'd leave plenty of time for the stepping.
There's a lot of tricks you can do to speed up random neopixel blinking: