-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flickering when using wifi from esp_idf_svc with this crate #33
Comments
I am also experiencing some flickering/incorrect output from time to time. If I run my test pattern before starting the Wi-Fi, it works flawlessly. With Wi-Fi, I get the incorrect output. Most likely this is due to Wi-Fi interrupts firing during a critical section causing a slight delay in the output timing. I have not been able to dig deeper into the code to try to figure out what is causing it. IMG_9972.mov |
It irritates me tho that this is not happening with WLED considering that codebase also runs on esp32, has wifi and can control hundreds of leds. Maybe they implemented it without anything from esp-idf or they edited the source from esp-idf to make it not flicker. I don't have a video of it at hand but I can confirm that a lamp with 240 leds in serial powered by WLED is not affected by our issue |
If your hardware is dual-core, try running all of your display code on Core 1 as all of the wifi activity (and its interrupts, as @thorhs mentions) will run on Core 0. Try using |
Interesting idea. I'm currently using std threads, is there a simple migration between them that you know of? |
I don't think it'll be too difficult to migrate from std threads, and in fact, you might not have to do so everywhere in your code. Depending on your implementation, you may just need to call xTaskCreatePinnedToCore() once to spawn your display code. In my use case, my recommendation works perfectly -- and it took quite a bit of digging into the C++ ESP-IDF and Arduino universe to find the solution, ex: FastLED/FastLED#507 😄 |
This worked perfectly, haven't gotten a single flicker after switching to core 1. For others that have the same issue, I moved my display loop to a new function and created a wrapper function to handle the C ffi. Snippets:
There may very well be better ways to go about it, but this works fine. I had to tune the stack size to get my code working, so that is somethign to keep in mind. |
In the past I had this code which didn't work even tho the commented line sounds familiar to ThreadSpawnConfiguration {
name: Some(b"LED-THREAD\0"),
stack_size: STACK_SIZE,
priority: 1,
pin_to_core: Some(Core::Core1), // <- Sounds familiar
..Default::default()
}
.set()?;
std::thread::spawn(|| -> anyhow::Result<()> {
// LED Code
}); |
I'm seeing the flicker with both a normal thread on core1 and This is with my task on core 1; I don't think it's a problem on this library, but I wonder why |
I've found what the issue is: With this, my 1280pix matrix is flicker-free |
I tried to do the same. But when using the core1 it still does it. It feels a bit less, but even when I send a request only every second, it sometimes still flickers. If I spam many requests, it flickers also very noticeable... So running the Ws2812Esp32Rmt on core 1 does not really seem to resolve this problem as expected... As I am not very experienced with rust on the esp, it took me some time to get it working in the extra thread. I call Ws2812Esp32Rmt::new from within the core1 thread. |
In my project it is working fine, check: https://github.com/DavidVentura/matrix-fire/blob/master/esp/src/main.rs#L24 the wifi settings must be done with affinity on core0 and the call to
this is because the rmt peripheral wil later just start a thread for interrupt handling with the global affinity state |
I just found out that it much better runs with release mode with these settings.
Now I can spam many requests and only get some flickers. Not zero but ok for now. However thanks for your code, I will try it how you do it now, since you do not use the low level |
Ok, I don't know why, but using the std threads does not work reliable for me. It always throws a stack overflow as soon as I do something inside the thread... (with the same stacksize configuration as I use with xTaskCreatePinnedToCore) Not exactly sure whats happening there... However using xTaskCreatePinnedToCore and your tipps regarding the global affinity I got it working more reliable now For me this is ok for now. About this lib: |
Same, I also get stack overflows when I refactor from xTaskCreatePinnedToCore to std threads, even if I specify a huge stack size. Anyone know why? |
@y34hbuddy You should set |
I've gathered the info from this issue so far and created a small project trying to make it work but I still get flickering when sending requests The program looks something like this fn main() -> anyhow::Result<()> {
esp_idf_svc::sys::link_patches();
esp_idf_svc::log::EspLogger::initialize_default();
let peripherals = Peripherals::take().unwrap();
let modem = peripherals.modem;
let led_pin = peripherals.pins.gpio13;
let channel = peripherals.rmt.channel0;
ThreadSpawnConfiguration {
pin_to_core: Some(Core::Core0),
priority: 1,
name: Some("SERVER\0".as_bytes()),
stack_size: 0x4000,
..Default::default()
}
.set()
.expect("Cannot set thread spawn config");
std::thread::spawn(move || -> anyhow::Result<()> {
let sysloop = EspSystemEventLoop::take()?;
let nvs = EspDefaultNvsPartition::take()?;
let mut wifi =
BlockingWifi::wrap(EspWifi::new(modem, sysloop.clone(), Some(nvs))?, sysloop)?;
// Connect to wifi with BlockingWifi
// Create http server with EspHttpServer
loop {
sleep(Duration::from_millis(10000));
}
});
ThreadSpawnConfiguration {
name: Some("PIXELS\0".as_bytes()),
stack_size: 0x4000,
pin_to_core: Some(Core::Core1),
priority: 24,
..Default::default()
}
.set()
.expect("Cannot set thread spawn config");
std::thread::spawn(|| -> anyhow::Result<()> {
let mut data = [RGB8::default(); 100];
data[0] = RGB8::new(10, 0, 0);
data[1] = RGB8::new(10, 0, 0);
data[2] = RGB8::new(10, 0, 0);
let mut led_driver = Ws2812Esp32Rmt::new(channel, led_pin).unwrap();
loop {
led_driver.write_nocopy(data.into_iter())?;
std::thread::sleep(Duration::from_millis(1000 / 60))
}
});
loop {
std::thread::sleep(Duration::from_secs(10))
}
} I'm unsure what I am doing wrong, I tested various pins again and it seems to not work at all and it always will flicker I guess the problems are interrupts but shouldn't they not trigger on the second core? And how can I disable them for a certain block of code, I know that I can I just couldn't find how |
So I encounter flickering of random colors on my led board. I already checked many different pins (to be exact 2,4,13,16,17,18) and all had the same problems.
A small video showing what I mean.
Video.Oct.4.mp4
Here's a demo of my code I use. You may need to adjust the led amount and what pin.
I tested it and it flickers when the wifi is started up.
The text was updated successfully, but these errors were encountered: