Skip to content
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

Expose blocking param of WS2812's update to micropython #1052

Open
tboby opened this issue Jan 19, 2025 · 1 comment
Open

Expose blocking param of WS2812's update to micropython #1052

tboby opened this issue Jan 19, 2025 · 1 comment

Comments

@tboby
Copy link

tboby commented Jan 19, 2025

I'm using the update() binding added for #236, in a loop running at my target frametime.

I'd like to get started on the next frame immediately after submitting the previous, but currently I believe it blocks until it's finished writing.

I don't understand the threading/processing model in rp2350/2040, so this might not make any sense as a request, but my hope is that if the background repeating timer seems to be able to run without blocking python when it triggers, then perhaps update(blocking=False) might work as well.

For context, on my Plasma 2350W, with 300 LEDs configured, my (probably flawed) profiling says:

  • 5ms minimum per frame if using start() only
  • 16ms minimum per frame if set to RGBW, using update()
  • 13ms minimum per frame if set to RGB, using update()

That's very close to my napkin calculation of the write time: 1.25us * 32 bits (RGBW) * 300 LEDs = 12ms, or 9ms for RGB.

@Gadgetoid
Copy link
Member

Typical caveats apply - ie: if you update the pixel buffer while it's being copied you may get tearing - but the builds here include a set_blocking() method to turn off blocking, and an is_busy() method to check if the DMA is still running: #1053

If you're using start() then you only have to call it once, it creates a timer that kicks off the DMA transfer at a predefined frequency and should add zero time (or at least no measurable impact) to your main loop.

I'm not sure if non-blocking updates are needed when we have start(), but I think they better support MicroPython's async model and at least give you a chance to avoid tearing.

As an aside you can probably now call start() and then spin on is_busy() to use the built-in timer without tearing. Regardless of which method you use, is_busy() will always just return the DMA status.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants