OpenLightingProject / ola

The Open Lighting Architecture - The Travel Adaptor for the Lighting Industry
https://www.openlighting.org/ola/
Other
644 stars 204 forks source link

Use Raspi's GPIO pins as secondary UART #1188

Open FloEdelmann opened 7 years ago

FloEdelmann commented 7 years ago

With the pigpio library, it is possible to use a GPIO pin on the Raspberry Pi as a bit-banged UART input/output. With this, we should be able to send and maybe also receive DMX data additional to the onboard hardware UART that does not support receiving (because it has no break detection).

But it is quite resource-intensive, so maybe it needs too much computing power to run alongside OLA and the other plugins.

FloEdelmann commented 7 years ago

I experimented a bit with this in the last weeks (actually, I am currently writing my Bachelor's Thesis about this – expect a PR in the next couple days 😉) and as it seems, at least bit-banged GPIO receive is too unreliable at 250kbit/s.

However, as described in the link above, sending should work fine, so this issue is still relevant.

kripton commented 6 years ago

Hi, I've been working on this lately: https://github.com/kripton/ola_to_rpi_multi I've been able to send three universes with about 20% CPU usage on a non-overclocked RaspberryPi 3. I couldn't test with real fixtures simply due to the lack thereof but the signal looks good on the scope. I might implement this as an OLA plugin instead of a client but it might be a bit difficult since all ports managed by the plugin need to have a common code path. I'll check on that later.

Oh, another thing that keeps this from being a good plugin: the PiGPIO library ususally needs root permissions which doesn't mix well with OLA not running as root. Maybe permissions can be changed to make pigpio work as non-root but needs investigation.

peternewman commented 6 years ago

I might implement this as an OLA plugin instead of a client but it might be a bit difficult since all ports managed by the plugin need to have a common code path. I'll check on that later.

Look at say the SPI plugin (or the FTDI plugin's thread), I think you should be able to have one output thread which the ports just update the DMX data for.

Oh, another thing that keeps this from being a good plugin: the PiGPIO library ususally needs root permissions which doesn't mix well with OLA not running as root. Maybe permissions can be changed to make pigpio work as non-root but needs investigation.

That's likely to be the bigger stumbling block.

FloEdelmann commented 6 years ago

The solution to the root problem may be using pigpiod:

pigpiod is a utility which launches the pigpio library as a daemon.

Once launched the pigpio library runs in the background accepting commands from the pipe and socket interfaces.

The pigpiod utility requires sudo privileges to launch the library but thereafter the pipe and socket commands may be issued by normal users.

That would require users to have pigpiod in their startup script or start it manually before running OLA and then just checking if it is running. Additionally, the build process should check for pigpiod existence and toggle build activation of the plugin accordingly.

kripton commented 6 years ago

As @FloEdelmann mentioned, using pigpiod was the solution to the permission problem. Thanks! Daemon running as root, OLA client running as ordinary user works perfectly. Implemented in https://github.com/kripton/ola_to_rpi_multi/pull/4 I've also modified my previous "triggerHelper" to an "driver enable" output and with using pigpiod (and 3 universes) my scope measures a frequency of 37Hz (= DMX update rate). Not bad :)

peternewman commented 6 years ago

Excellent @kripton , we'll look forward to a PR :smile: .

For bonus points, you could also add pigpiod support to the existing GPIO plugin, which would remove most of the issue raised in #1385 .

kripton commented 6 years ago

Ok, started working on this. WiP is here: https://github.com/kripton/ola/tree/pigpio though not much to see there, yet ;) I've got a good plan in my head to manage devices and ports :+1: let's see if I can implement it that way

About the GPIO-plugin: I agree that using the pigpiod is a very good approach to solving any permission issues. Do you think it's a good approach tackling that after the DMX output via pigpiod has been done or before?

So basically we need to make sure:

The former is quite easy via configure.ac (done in https://github.com/kripton/ola/commit/3f5453de184daa136d252ecc8510e69e9ae6d5c0). The latter is a bit more complex and I thought to have one pigpiod-enabled Pi as one "OLA device" and have them configured via plugin config options. Of course, one "OLA device" can have multiple OLA ports (= GPIO pins). The capabilities depend on the hardware model running the pigpiod and can theoretically be discovered dynamically at run time.

All that is why I'd first like to implement the DMX sending, getting experience with plugin writing and checking if the plan in my head is feasible in a sandbox. I'd like to avoid touching the GPIO-plugin code before.

peternewman commented 6 years ago

Hi @kripton ,

Are you just thinking the pigpio plugin will be for GPO DMX, and keep the existing plugin for all GPO on/off?

Will the network stuff work to stream DMX via GPO too?

You probably want to go down the PImpl route or similar for the existing GPO plugin: http://en.cppreference.com/w/cpp/language/pimpl

So I guess it's just a case of how well that overlaps with GPO DMX, or whether they're mostly both significantly different in terms of control that there's no benefit in merging GPO DMX and GPO.

kripton commented 6 years ago

Yes, I'd plan the "new" pigpio plugin to do "only" DMX output via GPIOs and keep the existing GPIO-plugin for GPIO on/off depending on threshold configured. Those two applications of the GPIOs is a different use case (the one is a DMX master, the other one a DMX slave but who do I tell this ;)). I'd (later) extend the GPIO-plugin to optionally use pigpiod (if detected running and/or configured) as an optional code path to avoid breaking installations using the currently used approach.

Yes, the DMX outputting code should work network-transparent as well. So you could have OLA on one machine (= not on the Pis) and the plugin uses connections to multiple pigpiod instances running on different Pis. Not yet tested but will do later this evening. The DMX frame rate might be a bit lower due to network latencies but I'll report as soon as I know ;)

I'll also have a look at pimpl, never used that until now. Looks a bit like Interface classes to me on the first glance.

kripton commented 6 years ago

Short update: When using OLA (with 4 universes) + ola_to_rpi_multi on one machine (my laptop) and only pigpiod on the Pi, the DMX frame rate jitters between 21Hz and 26Hz. Both devices are connected via 100Mbit-Ethernet through a switch and I see about 1.5 to 2MByte/s of network traffic (again: 4 DMX universes ;)). So, yes it is possible to run OLA only on one machine and have only pigpiod on the Pis but the performance is worse and the network traffic is way less efficient that using ArtNet or sACN.

Update for the update: The amount of network traffic per Pi will stay constant, no matter how many universes are configured.

peternewman commented 6 years ago

Okay, so it's probably not worth offering PiGPIOd over the network then as an option, which rather makes sense, as you say, and similar to our RPC stuff, using sACN/Art-Net or another procotol designed for DMX over IP is a far more sensible way to transport the data over the network.

FloEdelmann commented 5 years ago

@kripton Just stumbled across this PR again. Are there any news regarding progress on the new plugin?

kripton commented 5 years ago

Hi, @FloEdelmann. Status of the PR itself: stalled. What I got working back then was that automake was able to detect if the pigpio library and headers are existing. The actual plugin code is not yet done. Status of the DMX sending code: In the meantime (last two weeks), I was able to design and build 10x dual opto-isolated RS-485 driver boards. With those, I was able to send 8 universes in parallel using OLA (sACN -> old, using the https://github.com/kripton/ola_to_rpi_multi code as an external OLA client, not a plugin). So the functionality is verified. There seem to be some issues on the RPi 3B regarding bit timing when HDMI is plugged in during boot. Makes all LED fixtures flicker and needs more investigation.

So, in general I am still (now more than less) interested in finishing the code, it just didn't happen yet. Due to me being abroad currently, don't expect any progress in the next 3 weeks.

FloEdelmann commented 5 years ago

@kripton No need to rush this :wink:

I was just curious if you're still working on this :)

kripton commented 4 years ago

Update: End of August, we connected one RPi 1 and one RPi 3 with each 4 DMX universes out to a "real stage" for testing. Glitches happened, Lamps were very briefly flickering (= 1 invalid DMX frame in between), seems to be IRQ related (GPIO output is briefly interrupted which corrupts the frame). Now I have a RPi 4 to test here. However, focussing on ironing out build issues first (#1620 and #1621). Then (and with more Automake experience), I'll focus on pigpio-integration again :+1:

kripton commented 3 years ago

Update on sending DMX via the RPi GPIOs: I'm no longer sure if that's a viable solution. It works in theory but in practice, lots of invalid DMX frames are being sent (that make my LED lights flicker) due to Jitter and incorrect timing. The root cause has not really be named, but I assume it is because the DMA is not able to deliver the data fast enough to the "GPIO part" because the internal bus of the Broadcom-Chip is blocked by other parts with higher priority. This might not have been much of a problem with older Pis/firmware/kernel versions but I was not able to make it work reliably. Some discussion can be found here: https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=269035

Since we have the Pico board for $4 featuring the RP2040, I will focus on that instead. And as I've written to the mailing list, sending 16 universes is working fine.