Replies: 3 comments 25 replies
-
I think it's unrealistic for one ESP32 to control 800 pixels at 120Hz. Too much data per second. It's about 384kbytes/s. Driving the pixels with the UART blows up the memory use by about 3x, so this would require about 10Mbits/s on the serial port, but it is running at only 2.5megabaud. Put another way the bits on the WS2812B protocol take up 1.25µs so you can send max 800kbits/s. At 32 bits per pixel that's 25000 pixels/s maximum. So at 120Hz you are limited to a chain of max 208 pixels. In practice probably only 100 is realistic. |
Beta Was this translation helpful? Give feedback.
-
Nice project. One of my projects is to add ~50m of LED strips to my apartment, so I'm hopeful your project works (and if not that we can fix it). -- As Erik said, that's a lot of data. Streaming pixel values 120 times a second would be a lot of data. I guess you would only stream individual pixel values more rarely, and then adjust them (for example with the I looked into using the RMT and Pulse-counter together. In theory it should be possible to do this on a single pin, but I wasn't able to do it from Toit. As soon as I reuse the same pin in the pulse-counter and the RMT the other doesn't see the values anymore. (My guess is that the setup functions change the pin's direction to exclusive input/output). I then connected two pins (32 and 33) and emitted the RMT output on one and counted on the other, and that worked (as expected). I'm not sure it's a real win, though: the timing would, obviously, be extremely precise and there would be no software interaction, but the division/modulo operations shouldn't be that costly either. Compared to a primitive-invocation (crossing the Toit/C boundary) a division/modulo should still be cheaper. As such, you wouldn't win that much. That said, it might actually be faster. After all you would switch one primitive call (the one to the monotonic_us) with another (the one to get the pulse-counter's value), but would avoid the division/modulo. I'm not sure it's worth it. For controlling step motors, we probably want to use the actual MCPWM peripheral (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/mcpwm.html). I haven't looked at it yet, but I would expect that it has all the features that would be needed. |
Beta Was this translation helpful? Give feedback.
-
Hello Toit-ers,
I run a small studio that works on interactive sculptures and R&D services. I came across Toit recently and been pondering using it for a project which involves using several (8x) ESP32s on a wireless network, each controlling a RGBW strip (>800) leds. A Raspberry Pi acts as a server streaming out pixel values (extract scan lines from a GIF) for each strip 120 times a second. Effectively, the strips act like pixel lines on a screen and refresh at 120fps. Part of the project involves composing LED effects which happens to be ergonomic when working with HSV (I can make a separate feature-request issue about the
pixel_strip
package elsewhere) before dumping to the strip as RGB (by conversion). To aid with the composition, we currently use a primitive calledstep(time_interval, target_value)
which generates values between[0,target_value]
with an increment computed from thetime_interval
. For example, we would usestep(1000, 2)
to generate a square wave with a period of one second. Currently, this is done in software and involves expensive%
and/
operations. If you were to usestep(1000, 255)
this would generate a saw-tooth wave. When I looked at the plot of the values produced reminded me of how a timer's counter works. Usually, one is able to read the timer's counter values during its operation on an interrupt and do something with the count. In my case, I could use the count to scale, say, the brightness of an LED pixel or shift it's hue value by that amount to another pixel etc.I figured that the RMT and Pulse Counter peripherals could be used together to achieve this at hardware efficiency without any software arithmetic. I suppose at the high-level this is what I have in mind -
I could imagine this being useful for controlling stepper motors using the
STEP/DIR
interface but also applying acceleration profiles (fixed at compile-time or computed at run-time) potentially in an isolated task or process with CRITICAL priority. I suppose the question is how, if, this could be achieved with what's already available in the language and standard library? If it can't then any suggestions would be helpful. If things like the one I mentioned about the stepper motor could be done, I'm considering switching shop from C++ to Toit entirely. We already made the switch from Teensy to ESP32 a while ago, although something likeTeensyAudio
remains a welcome addition to the Toit ecosystem, a discussion for another day.Thanks,
CA
Beta Was this translation helpful? Give feedback.
All reactions