Closed xj650t closed 3 years ago
What version of Esp32 for Arduino board support are you using?
Try changing the starting "image" to just the first pixel lit. What do you see?
Try moving the show from the loop to the bottom of the LoopAnimUpdate.
I tried updating the https://dl.espressif.com/dl/package_esp32_index.json but the certificate has expired and Arduino IDE refuses to download :-( I pulled out an esp8266 and the animation is smooth, no judder. I'll try the other steps above when I can download the json again.
If you go to the board manager, what version of the esp32 board support does it state that you have? Is this where you hit checked if its updateable? I just updated last night; but I just checked and I see the same json issue now.
I removed the json and restarted the ide then tried to add in the ESp32 which errors Error downloading https://dl.espressif.com/dl/package_esp32_index.json So can't actually add in the board support. Hopefully, they'll fix the certificate tomorrow.
Espressif fixed the certificate issue so I've downloaded and used version 1.0.3. With the first pixel lit the juddering is still evident, I'm using a 60-pixel strip. Moving the Show() to the LoopAnimUpdate did not cure the juddering.
I will take a deeper look. I know 1.0.4 is coming soon to fix some blocking issues.
seeing the same issue (was not seeing it using the adafruit library, but it had "color accuracy" corruption issues
Here is my test sketch, I am not seeing pausing in the code as the output is consistently showing a 66ms update. Switch to the alternate RMT (see code, comment out one def and uncomment the other).
Do you know what LEDs you have? Exact model (link to store where purchased)?
Try my sketch below and let me know the numbers you see.
output:
1024
min delta : 65767
max delta : 66001
ave delta : 65999
sketch:
#include <NeoPixelBus.h>
#include <NeoPixelAnimator.h>
const uint16_t PixelCount = 60; // make sure to set this to the number of pixels in your strip
const uint16_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
const uint16_t AnimCount = 1; // we only need one
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
//NeoPixelBus<NeoGrbFeature, NeoEsp32Rmt0800KbpsMethod> strip(PixelCount, PixelPin);
NeoPixelAnimator animations(AnimCount); // NeoPixel animation management object
class TimeTrak
{
public:
TimeTrak( size_t maxSamples ) :
_prev(0),
_current(0),
_minDelta(0xffffffff),
_maxDelta(0),
_sampleCount(maxSamples),
_sample(0)
{
_samples = new uint32_t[_sampleCount];
}
~TimeTrak()
{
delete [] _samples;
}
void begin() {
_prev = micros();
_current = _prev;
_minDelta = 0xffffffff;
_maxDelta = 0;
_sample = 0;
}
void start() {
_prev = micros();
}
void restart() {
_prev = _current;
}
void stop() {
_current = micros();
if (_sample != _sampleCount) {
uint32_t delta = _current - _prev;
_samples[_sample++] = delta;
if (delta < _minDelta) {
_minDelta = delta;
}
else if (delta > _maxDelta) {
_maxDelta = delta;
}
}
}
uint32_t getLastDelta() {
return _current - _prev;
}
uint32_t getMinDelta() {
return _minDelta;
}
uint32_t getMaxDelta() {
return _maxDelta;
}
uint32_t getAverageDelta() {
if (_sample == 0) {
return 0;
}
uint64_t sum = 0;
for (size_t sample = 0; sample < _sample; sample++) {
sum += _samples[sample];
}
return sum / _sample;
}
size_t currentSample() {
return _sample;
}
bool maxSampleTaken() {
return (_sample == _sampleCount);
}
private:
uint32_t _prev;
uint32_t _current;
uint32_t _minDelta;
uint32_t _maxDelta;
const size_t _sampleCount;
uint32_t* _samples;
size_t _sample;
};
TimeTrak animUpdate(1024);
void LoopAnimUpdate(const AnimationParam& param)
{
// wait for this animation to complete,
// we are using it as a timer of sorts
if (param.state == AnimationState_Completed)
{
// done, time to restart this position tracking animation/timer
animations.RestartAnimation(param.index);
// rotate the complete strip one pixel to the right on every update
strip.RotateRight(1);
animUpdate.stop();
animUpdate.restart();
}
}
void DrawTailPixels() {
for (uint16_t index = 0; index < strip.PixelCount(); index += 20)
{
strip.SetPixelColor(index, RgbColor(128,0,0));
}
}
void setup() {
Serial.begin(115200);
while (!Serial); // wait for serial attach
Serial.println();
Serial.println("Initializing...");
Serial.flush();
strip.Begin();
strip.Show();
// Draw the tail that will be rotated through all the rest of the pixels
DrawTailPixels();
animUpdate.begin();
// we use the index 0 animation to time how often we rotate all the pixels
animations.StartAnimation(0, 66, LoopAnimUpdate);
Serial.println();
Serial.println("Running...");
}
void loop() {
if (animUpdate.maxSampleTaken()) {
Serial.println(animUpdate.currentSample());
Serial.print(" min delta : ");
Serial.println(animUpdate.getMinDelta());
Serial.print(" max delta : ");
Serial.println(animUpdate.getMaxDelta());
Serial.print(" ave delta : ");
Serial.println(animUpdate.getAverageDelta());
animUpdate.begin();
}
animations.UpdateAnimations();
strip.Show();
}
And note, I changed it to every 20 pixels, as every 3 pixels means that any single pixel will change state 5 times a second; which is hard to percieve.
This is the led strip purchased https://www.amazon.co.uk/gp/aw/d/B01CDTED80 I’ll have a look at the code and update you later.
Video of the code above running: https://www.youtube.com/watch?v=vg1YV1eMUmc
This is running on a DOIT esp32 clone https://www.amazon.com/gp/product/B079PVCF2G and the neopixels im not 100% sure, but the packages says WS2812B on it, 75% sure it was this: https://www.amazon.com/gp/product/B019HWACOA
And the numbers from the sketch serial: Initializing...
Running... 1024 min delta : 65855 max delta : 66001 ave delta : 65999
Here is another recording in "slow motion" (recorded using slow motion on s10 Frame rate: 237.526528, transferred to computer, then changed the framerate to 30 via ffmpeg) https://youtu.be/QUZ1PYlv3eQ
For the first method 1024 min delta : 65633 max delta : 66001 ave delta : 65999 1024 min delta : 65789 max delta : 66001 ave delta : 65999
For the second method Running... 1024 min delta : 65448 max delta : 66001 ave delta : 65999 1024 min delta : 65720 max delta : 66001 ave delta : 65999
Interestingly I'm not seeing the judder stuttering using the second method. If you change in DrawTailPixels for (uint16_t index = 0; index < strip.PixelCount(); index += 3)
and then change animations.StartAnimation(0, 100, LoopAnimUpdate);
It all runs fine now.
The debug out confirms that it should not be having issues as it has plenty of time and consistent time to update the pixels.
So it seems I2s DMA isn't writing a frame about every 18th one sent. I am escalating to the Esp32 folks now.
Captured using an iPhone SlowMo https://www.youtube.com/watch?v=-STZt7L61FY Judder is about 10s in, this is with the Neo800KbpsMethod
Thanks so much for the great library and your help, I'll continue developing with the RMT method for just now.
Until we find what's going on in the lower core, I switch the default over to RMT chan 6.
Since this is related see https://github.com/esphome/issues/issues/858
I just discovered that my random flickers on i2s very much depends on the wifi state. When the wifi is not connected, there is no flickering. As soon as the wifi connects, flickering starts. Interestingly, RMT is currently broken on esphome for unknown reasons :(
I'm creating a rather complex project which uses a lot of networking (ESPAsyncWebServer - with WebSockets, AsyncMqttClient, AsyncUDP) and it seems that there are some problems with timings on ESP32 with all methods. Here are my observations for various LED libraries (using 72 LEDs, updates every 20ms): NeoPixelBus (RMT) - periodic flickering when sending AsyncMqtt messages, almost every time I send a message (every 3 sec) I get random LEDs blinking with a different color for example: all LEDs set to red, I get a couple of green LEDs. Separating Show() into a different task according to this suggestion helps a bit, but not much. NeoPixelBus (I2S) - This is almost OK, it seems to work when something is displayed, but when clearing the LEDs in every loop, once every couple of minutes I get a white flash on all LEDs. It seems that separating this method into a separate task helps this (I'm still confirming, but seems better). FastLED (RMT) - the same behavior as in NeoPixelBus (RMT) FastLED (I2S) - this one seems to be the solution that works for me, no random blinks, no white blinks, even without a separate task.
I'll post my additional findings about RMT in #321 not to mix issues (or maybe we could make some other issue that can combine ESP32 problems)
@drzony Thanks for cross checking with FastLED. I will examine what he is doing in his i2s support and look for differences. Are you running my latest github version or the released? Github has a few fixes but I was still seeing the issue. Note that what I am using was written by esprisif for me (check out the file header). Things change in the core and while this used to work great, it stopped functioning at some point.
@Makuna I'm running the latest master
https://github.com/Makuna/NeoPixelBus/releases/tag/2.6.0 Has some improvements.
NOTE: If you are seeking help or have questions, this is NOT the place to do it. For questions and support, jump on Gitter and ask away.
![Gitter](https://badges.gitter.im/Join%20Chat.svg)
Describe the bug Animation judders or stops briefly about every second then continues smoothly again
To Reproduce Steps to reproduce the behavior: 1.Load NeoPixelRotateLoop example 2.Replace contents of DrawTailPixels with "for(uint16_t index = 0; index < strip.PixelCount(); index+=3) strip.SetPixelColor(index, RgbColor(128, 0, 0));"""
Expected behavior Smooth Animation loop of pixel lit every 3 pixels.
Development environment (please complete the following information):
Minimal Sketch that reproduced the problem: See To Reproduce above
Additional context I'm not sure this is a library bug or an ESP32 issue. I've also tried connecting to a WiFi access point but the juddering continued