Sunday, June 14, 2020

Rebuilding the USB serial driver to allow for DMX (250000) baud

Rebuilding the USB serial driver to allow for DMX (250000) baud

I wanted to play with a new light and wanted to just use a standard USB serial device. In the past I'd just patched the driver, but that no longer appears possible. (This is a good thing, I was always surprised that used to be able to do this) This meant building the driver. This *should* be simple, but it wasn't. This outlines how to to rebuild the serial driver for Raspbian.

The sequence for building the driver should be simple:
1. Get the source for the driver
2. Get the kernel headers
3. Create a simple Makefile
4. Build
5. Serve

I mainly ran into issues getting the correct headers.

Get the source for the driver

uname -r will tell you the version of the kernel:
  $ uname -r
  4.9.35-v7+

Now you can pull in the source directly from github, updating the version number. Pull in the c file and the header:

  wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-4.9.y/drivers/usb/serial/pl2303.c
  wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-4.9.y/drivers/usb/serial/pl2303.h


Get the kernel headers (Raspbian)

apt install is used to pull in the kernel headers. 

  apt install raspberrypi-kernel-headers

For my installation, the headers getting pulled in didn't match the running kernel. The kernel version was actually quite far ahead. You should ensure that you're up-to-date first

  apt-get update
  apt-get upgrade
  init 6

or in my case:

  apt remove raspberrypi-kernel-headers
  apt-get update
  apt-get install --reinstall raspberrypi-bootloader raspberrypi-kernel
  init 6
Once rebooted:
  apt install raspberrypi-kernel-headers

Check that you have the correct headers. If you have the 'build' directory, then you should be good.

  ls -l /lib/modules/$(uname -r)/build

Create the Makefile

 I'm building pl2303.ko, so all my Makefile needs to contain is:

   obj-m   := pl2303.o

Yes - that's all.

Build

With the headers in place and the Makefile in place, this is all you should have to do to build:

  make -C /lib/modules/$(uname -r)/build M=$PWD modules

Serve

You may need to remove the current module:

  rmmod pl2303

Now you can install your new module:

 insmod pl2303.ko

250000 Baud


The reason for having to build a driver were to be able to set the Baud to 250000 for my DMX device. Linux still has preconceived notions about baud rate, and 250000 isn't one of them, so you'll not be able to easily set the speed you want. I have some existing code (dmx) that sets the baud rate to 500000 with the expectation that the driver will set it to the next closest speed. I used to patch the driver to make this closest (lower) speed to be 250000, but that doesn't work anymore.

       if (baud == 500000) baud=250000;

I added the above line into the driver code - if the baud requested is 500000, then set the baud to 250000. To put this in context:

        /*
         * Use direct method for supported baud rates, otherwise use divisors.
         */
        if (baud == 500000) baud=250000;
        baud_sup = pl2303_get_supported_baud_rate(baud);

        if (baud == baud_sup)
                baud = pl2303_encode_baud_rate_direct(buf, baud);
        else
                baud = pl2303_encode_baud_rate_divisor(buf, baud);

This means that if 500k baud is selected it will change the request to 250k. The 'if ' section (baud_sup) will fail and the baud rate will be set using pl2303_encode_baud_rate_divisor.

That's all.

REF: https://raspberrypi.stackexchange.com/questions/63879/installed-kernel-headers-and-uname-r-differ REF: https://www.youtube.com/watch?v=Zn8mEZXr6nE&list=PL2GL6HVUQAuksbptmKC7X4zruZlIl59is REF: https://www.raspberrypi.org/documentation/raspbian/updating.md







Sunday, May 18, 2014

DMX – The Complete Project.

DMX – The Complete Project.


This outlines the complete (or almost complete) steps for using a Raspberry Pi to control my garden lights. The outside lights use the DMX protocol, so as well as being able to generate different lighting moods; they can also really annoy the neighbors by turning my garden into a disco.

Figure 1: The obligatory picture of the control system

Figure 1 shows the inside of the control box. (I have a control box because my wife really, really, doesn’t like wires – so I have to hide away as much as I can). I’m using a RS485 USB device (around $10, using the Prolific PL2303 chipset), which you can see crammed in the bottom right corner, to control the DMX devices. I’m using the PiFace to turn on/off power to the lights. (I’m also using it to control some LEDs on the front of the control box, but the cables are not connected in the above picture). The big yellow thing on the right shows that I live in America, where twisting wires together is considered a sound connection. I’m using a nano wifi device (the blue light on the left). Also, I had to use a right-angle USB extension (which turned out to be left-angle) to attach the RS485 device, as the box wasn’t long enough. (I could have used a shorter SD card, but I don’t know if they exist)


The above is the basic schematic for the installation. The Raspberry Pi (Blue) is used to drive the RS485 with the DMX protocol. The green box represents the RS485 device, that drives the twisted pair cable that communicates to the lights. At the end of the twisted pair is the terminating resistor of questionable value (see below). The PiFace (Yellow) is used to turn on power to the lights. It also used to drive some of the status LEDs on the front of the control box, but that’s not shown in the schematic. The power supply is a notebook power supply. These tend to provide a lot of power in a small device and are somewhat more consumer friendly than the more industrial power supplies. (Plus, the one i used has a usb port, so I can power the Pi from that.)

Figure 2:  One of these lights

Figure 2 shows one of the lights. I should have put some sort of scale on this, as they’re “Rather Large”. They’re about 12” across. I wanted to light up my trees, so these are 15W RGB lights. Pretty powerful. The lights have four wires (Which in my case, were very well labelled). Two 24V and two DMX, labeled D+ and D-.

Wire turned out to be one of the most expensive parts of the project. I used 200’ of 16 gauge wire for the 24V DC and 200’ of twisted pair cable. I was going to make my own twisted pair, which I’d done during prototyping (using a post and a drill) but I found a reel that was relatively inexpensive. What I should have done was used Ethernet Cat5e cable – not because I needed 4 twisted pairs, but because it’s sooooo much cheaper than just one twisted pair, plus it probably is more durable when buried in the ground, plus, having underground Cat5e in your garden much cooler than, say, owning a Ferrari.

Figure 3: RS485

Figure 3 shows the RS485 device I used. The DMX protocol uses RS485 for the hardware/signaling side of the protocol. On top of that is a relatively simple protocol that uses BREAKs to signal the start of a packet followed by the data. I had to patch the PL2303 driver to support the DMX 250,000 baud rate and write a utility to generate the DMX packets. [Link]  I was waiting for my lights, so I ended up buying a $25 RGB DMX light off Amazon that I could play with. This was quite entertaining, and my daughter was quite amazed to find out that when you mix Red, Green and Blue light you get White. I created a web page so that I could control the lights and then added network support, so that standard DMX software could talk to the Raspberry Pi and control the lights. So far I’ve tested Vixen Lights 3 on my PC and AuroraDMX on my Andriod.

Installing the lights took about a day and a half. Most of the time was spent trenching and burying the cables. I have a ‘Black&Decker’ trencher and edger, so I used that for making the trench. It draws more of a line than actual trenching. I ended up sitting on a kid’s camping chair using paint stirring sticks to push the cables into place, but it worked. The nice thing is that the trencher didn’t get down deep enough to splice pipes or any other cables. The bad news is I don’t know if I’ll be able to aerate my lawn again.


I tested out the installation twice before burying the cable. Once in the house, where I was running into issues and ended up taking 100’ of twisted pair cable and had it going through an assortment of rooms in the house and once in the yard/garden, where I had it laid in position. DMX calls out for a 120 ohm terminating resistor on/after the last device. This is to stop the signal bouncing back. When you have a short run and a few devices, you’ll not need this, but once you get a long line of cable, it becomes an issue. When I did the test runs, I needed a larger resistor, around 150 ohms. Luckily I had these to hand. Once I buried the cables, this no longer worked. The lights I have go into an automatic mode when they’re not getting any commands, so it was pretty obvious that something was wrong.  Initially I thought that it was a loose cable and had the annoying experience of finding and fixing the loose cable only find out that it wasn’t the real issue. I ended up trying an assortment of resistors in different configurations until something worked. In my case, two 150 ohm resistors in parallel, so 75 ohms. Next time I think I’ll invest in a variable resistor/rheostat/potentiometer and use that to find out the correct resistance, and then connect up the right amount of resistance.

The reason for the 120 ohm resistor is based on the impedance of the cable. Obviously there’s some dark magic at hand that I don’t quite understand. maybe cables are like people, they put up less resistance when buried underground.


With the cable trenched, I installed the lights. I dug holes just slightly larger than the lights and filled it in with dry concrete. (I had to redo the lights a few weeks later, as while the lights had plenty of bedding, they didn’t have a whole lot of encasement on the side, so I dug a wider hole and filled that in with dry concrete. The rain took care of the rest). I was initially going to use a garden type control box for each junction, but in the end use some underground spicing devices, some electrical tape spray and wrapped it up in plastic – this appears to be working, but I’ll have to see how long they last.

With the lights installed and the testing complete, it was time to drill a hole in the side of the house and fish the cables through to the control box. I used the PiFace to control the power to the lights. The positive wire is connected to the “common” connection on relay#2 and the line to the lights is connected to the “open” side of the relay. (The side that’s not connected to common by default, you can see the lose screws in the picture above).  Note that the PiFace spec calls out 20 volts or 5 amps max, I’m 24v at about 3 amps, so I think I’m OK. (you can see in the picture above that the relays can cope with more. I assume the limitation is based in the traces on the PCB) It appears that all the PiFace documentation points you to perl.  I use the gpio utility, which can be slightly odd (“gpio –p write 200 1” sets the top relay on, but you need to use “gpio –p read 209” to read the current state of the relay).

The nitty-gritty inside the Raspberry Pi is difficult to take a picture of, so here’s a written version. I’ve modified /etc/rc.local to run the utilities that I need when the system boots up.

/usr/local/sbin/dmx -e &
/root/lights/lights.sh >/var/log/lights.log &

The /usr/local/sbin/dmx is the utility I created to talk the DMX protocol to the RS485 device. I’ve documented this in a separate blog/blogs. [link]. The ‘-e’ option enables E1.31 unicast network support.
The “lights.sh” is a shell script that is split into three parts. The first part calculates the amount of seconds until sunset and sleeps until sunset (garden lights being a more nocturnal activity). The second part turns the lights on and generates a random set of values for the lights. The third part shuts the lights down when it gets late.

Figure 4: Unimpressive Web Frontend

The webpage controls the power to the lights as well as the lights themselves. It’s quite unimpressive as I wanted to use the “slide” type (for reasons that currently escape me – I think to avoid huge wads of java script ). There’s some java script, mainly communicating to PHP scripts on the server that do the actual control of the lights and turning the relay on/off.  Really I should have a front end where you just select the color of the light you want (well, that’s what my wife wants).

Figure 5: Vixen pumping up my lights

As well as certain “staged” or set scenes for lights, you may want to pump up the jam/jelly. Figure 5 shows my take on the middle bridge(?) on “Hello”. I’m no expert on any DMX mixing/lighting software. I tend to learn how to use software by banging my head against it for a while and then giving up and reading the manual. In the case of DMXcontol and FreeStyler, they both look great but I didn’t make it over the first hurdle. I then took a look at Vixen.


Vixen appears to be the choice of people who want to overdo it on Christmas lights. I liked it because it kind of fit in with how I imagined DMX software would work. It has a timeline and you can plonk different effects on each light and it has a nice “Preview” that works. It also support “E1.31 Output Controller”, which is a pretty generic way of talking to lights over the network, so I updated the DMX utility to understand E1.31 and was able to make my lights sing and dance. (Link to setting up Vixen for use with theDMX utility). I’ve banged my head against it for a while, but I’ve not resorted to reading the manual...yet.


Figure 6: The finished control box. Power Supply on top.














Sunday, April 20, 2014

Interfacing Vixen 3.0.10 to the Raspberry Pi DMX utility.





 Interfacing Vixen 3.0.10 to the Raspberry Pi DMX utility.


This article covers getting Vixen 3.0.10 [BETA] working with the DMX utility. Vixen supports E1.31, which is a standard network protocol for talking to DMX devices. Using E1.31 we can have Vixen running on a different system than the Raspberry Pi. This way the Raspberry can act as a DMX server, while any system can send packets to it.

I’m not a Vixen expert. The below details the steps I took to get Vixen to talk to the DMX Utility. The setup is Vixen running on a PC running Windows (I’ve tried with both 8 and 7) and the DMX utility running on a Raspberry Pi. (The Pi is running Raspian 3.10 (wheezy)) I’m using the wireless network on the Pi. (Which doesn’t appear to have any latency issues when receiving UDP packets – which is what the E1.31 spec calls out).

The DMX utility needs to be started with the --e131 and/or the --e131m option. (see the “start here” link)


On vixen, select the “Setup Display option in the “System Configuration” box.








Next we’ll add our “Elements” (Lights). The lights I’m using are LED RGB each consuming 3 channels, one each for Red, Green and Blue. I select “Single Item” and then press the green button. (The “+” one).







I name my elements L1 through the L5 (I’ve a small installation). Let’s start off with L1.





We need to configure the Color Handling, so we select “Color Handling” from the drop down and click the “Configure” (cog) icon.








Select “They can be any color”. Once you click “OK”.












You should see the amount of Patch Points go up to 3.









Once all 5 elements have been configured, you should have this on the left hand side of the screen. (Five RGB Lights/elements – each using 3 channels.)


Now we need to set up the controller and link the lights to channels on the controller. On the right hand side of the screen we select “E1.31 Output Controller” from the dropdown list and click the green button. We can name our controller anything. I’ve named it “DmxPi”. We really on need 3x5=15 channels, but I’ve created 20 output count, as that’s what the DMX utility defaults to.







 Now we select each element from the left and a group (using the Ctrl-Key) of outputs on the left and “patch” the elements together by pressing the “Patch Elements to Controller” button. You need to patch L1 to #1, #2 and #3 and L2 to #4, #5 and #6, etc…




We need to configure the controller for Universe, where it starts and how big it is. Press the “Configure” cog on the bottom right of the screen. You will see the “Setup Form”. If you’re using Unicast (using the - - e131 option on the DMX utility) then you need to set the destination as the IP of your Raspberry Pi. This is a two-step process. First, right click on the destination dropdown, a box asking for the IP will immediately appear. Type in the IP address of your Pi and click “OK”. Next, select the Unicast option from the Destination dropdown. (Which will now be populated). If you’re using multicast (using the –e131m option on the DMX utility) then select the Multicast network that your Pi is on. (ie, wireless, or Local Area if you’re hooked in to the lan). Select the universe that you’re in. One is probably the best default. If you set it to something else, then use the –universe option on the DMX utility to ensure that both ends match). Set the size of the universe to 20 (again, I’m only using 15 channels). Don’t forget to check “Act” to activate the address. I set the Max Repeat and Max Suppress count to 3, so that there’s not a lot of noise on the network, but during debug/set up, you may want to leave these are zero. Click OK and then OK on the Setup Display page, and now you can start a “New Sequence”. (Read the Vixen docs on what to do here)














Thursday, April 17, 2014

DMX - Connecting your DMX device.


Connecting your DMX device.


Most DMX devices have an “XLR” type connector, some have RJ45, but they’ll all have a D+ and a D- pin. (Note that this doesn’t mean the same as positive(+) and negative(-) voltage, it’s to do with the “differential”, in this case, if the voltage on D+ is higher than the voltage on D-, that’s a logical 1, if D- is higher than D+ it’s a logical 0.)

For a three pin XLR, pin 2 is the D+ while pin 3 is D-. We don’t need to worry about ground for transmitting data.


               

 







For my generic RS485 dongle, the connectors are unhelpfully labeled “A” and “B”. A is D+ and B is D-. To connect the RS485 dongle to the DMX device you’ll need to use a twisted pair cable. This isn’t a special cable, you can make your own (I did). If you wrap a standard wire around a post/door knob/whatever, you can then stick the loose ends in a drill, pull the cable tight and drill-baby-drill your own twisted pair cable. (drill slowly, too fast and you’ll end up not twisting the cable evenly). 


Not a very good diagram – but you get the idea – I hope. Alternatively, buy some twisted pair or use CAT5e (Ethernet).

For our set up, we connect “A” to pin 2 and “B” to pin 3. Hopefully whatever DMX device you’ve bought has enough documentation to let you know which pins/cables to connect.

If you’re connecting multiple devices, then you’ll use twisted pair between them all, and you’ll be connected daisy chaining them all. (ie, pin2 to pin2 and pin3 to pin3 on each device).


The DMX spec calls out for a 120 ohm terminating resistor. If you’re connecting to one device over a short length, then you’ll probably not need the terminating resistor. I’d advise getting a collection of resistors in the 100 ohm range, as I’ve found that a lot of issues can be solved by using a terminating resistor. You put the resistor between pins 2 and 3 in the last device in the link.

DMX on the Raspberry Pi - Start Here.


DMX on a Raspberry Pi

When you get a Raspberry Pi, you want to do something cool, unique and very Pi-ish. This project has some of that. You can use much of the project on any Linux system, but I do make use of the PiFace for turning power on/off and the project allows you to create a very low cost DMX controller.
DMX LED Light
Firstly, what is DMX? DMX is used for controlling lights in stage and concert productions, it’s also used for controlling lots of other things, in my case the, the lights in my back garden/yard. These are DMX LED lights that you can buy online and I’m sure from all good lighting stores. (Although I don’t know of any).


My Trees rocking out to Enya. They don't know any better.

DMX uses RS485 for its hardware/signaling. Most people are familiar with RS232, a serial communication relying essentially on three wires (TX, RX and GND). RS485 uses a single twisted pair (two wires wrapped around each other) that is great for a one-to-many communication.  On top of the RS485 is the DMX data protocol which provides up to 512 bytes of information per packet. Each packet is made up of a start sequence (a BREAK followed by sending a ZERO byte) and then one or more bytes of information called “channels”. Each channel controls a “dimmer” – that can have a value from 0 (off) to 255 (fully on). Typically a DMX device will consume a number of channels. For example my lights have red, green and blue LEDs so consume three channels, one for each color.

To get DMX running on a Raspberry Pi, you’ll need a RS485 device. A USB-to-RS485 device runs about $10. This example uses a generic converter which contains the “Widely-supported” Prolific PL2303.
My USB adapter is so generic; it’s probably covered by your healthcare plan.

Note that the driver and utility are based on the 3.10 version of rapsbian (wheezy).

cat /proc/version

Linux version 3.10.25+ (dc4@dc4-arm-01) (gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08) ) #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014

The Modified USB Serial Driver.

The modified driver is needed to support the DMX baud rate. It’s the standard USB-PL2303 driver with one BAUD rate change to support 250,000 Baud. For details on modifying your driver (if you don’t want/can’t use the pre-built driver, read this.)

The DMX utility.

The DMX utility talks to the serial port (/dev/ttyUSB0 by default) sending DMX packets out to whoever will listen. (Hopefully some DMX lights)

To see all the options, use

                dmx –h 

This will show the following:


DMX User Space Driver version n.n

--break, user standard BREAK

--mab=n set MARK after BREAK value (microseconds)

--mbs=n, set delay between channels (microseconds)

--mbb=n, set delay after packet (microseconds)

--init=n, starting value for channels, deafult is zero

--channels=n, set the count of channels to transmit,default is 20

--starttype=n, value for first byte sent

--device=<device>, serial device to use, default is /dev/ttyUSB0

--e131, enable unicast e1.31 network support

--e131m, enable multicast e1.31 network support


--universe, multicast universe, default is one

--help, show help

Here’s a review of the options:

BREAK, this tells DMX to use standard “Linux sized” breaks. The start of each DMX packet has a BREAK. The standard Linux BREAK is much longer than required, so there’s some jiggery-pokery to get around this. If you’re having problems talking to your DMX lights, you may want to enable ‘break’ to use the standard BREAK.

MAB, “MARK after BREAK”, how much to delay between the BREAK at the start of the packet and sending the first bytes. The default is 12 microseconds, which is what the spec says.

MBS, “MARK between slices/bytes”, how much to delay after each byte is sent. The default is zero, which means that it’ll send a complete stream of bytes. If you specify a value, then there’s a delay after each byte has been sent.

MBB, “MARK before BREAK”, how much to delay between each packet. The default is zero, but DMX does ensure that the previous packet has been sent before starting a new packet.

INIT, the initial starting value for the DMX channels. The default is zero, which means everything should start OFF. If you want to have everything starting on – and startling everyone, then use 255.

CHANNELS, how many channels to send. The DMX protocol allows up to 512. If you don’t have that many devices you should limit this. DMX defaults to 20. Note that the fewer channels that are sent the more packets that can be sent each second.

STARTTYPE, the first byte in the packet is typically a zero. Some devices can key off other start types. You’ll probably want to leave this at zero unless you know what you’re doing.

DEVICE, this points to the serial device to use. This defaults to /dev/ttyUSB0, which is the usual name assigned to the USB serial (RS485) device. If you have a few serial USB devices, the name may change.

E131, enable unicast (sending to a specific IP) support. The DMX utility will receive E1.31 network packets and send to the DMX devices.

E131m, enable multicast support. The DMX utility will receive E1.31 network packets and send to the DMX devices.

UNIVERSE, this selects the universe that multicast will listen to. The default is one.

Note that dmx is (to some extent) a user space driver, to make it operate in a similar way to a driver, it uses names pipes to get/send information.  (Ultimately, I’d like to make it a driver, but for now it’s easier to work it (and build it) as a utility.

Installation.

Download the driver here:

Download the DMX utility here:

(coming soon, once I clean it up, Download source here)

First, install the driver. We need to uninstall the current driver (If loaded), make a backup, copy the new driver into place and install the new driver. As stated above, the driver is based on the 3.10 version of rapsbian (wheezy). The current driver on your system will be here:

                /lib/modules/3.10.25+/kernel/drivers/usb/serial

The steps:


1.       Make sure you’re super user
a.       sudo  su

2.       Get to driver land
a.       cd  /lib/modules/3.10.25+/kernel/drivers/usb/serial

3.       If you have the USB-RS485 device installed, remove the driver.
a.       rmmod  pl2303

4.       back up the current driver
a.       cp  pl2303.ko  pl2303.ko.works

5.       copy the downloaded driver into place
a.       cp  /<download location> /pl2303.ko   .

6.       load the module

a.       insmod  pl2303.ko

7.       Create the named pipes and set some viable permissions.
a.       mkdir  /var/dmx
b.      mkfifo  /var/dmx/dmxin
c.       mkfifo  /var/dmx/dmxout
d.      chmod  777 /var/dmx/dmxin

8.       copy the utility into place
a.       cp  /<download location>/dmx   /usr/local/sbin

9.       Launch DMX in background with the defaults
a.       dmx &

Now DMX should be happily running away, you should be able to talk to it by sending “commands” to /var/dmx/dmxin. The basic command is channel#:Value. Channel is from 1 to 512 and Value is 0 to 255.

                 Set channel 1 to 50:

                                 echo  1:50  >/var/dmx/dmxin

                set channels 3,4 & 7 to 40

                                echo  4:40 4:40 7:40  >/var/dmx/dmxin

                 get the current values for all the channels

                                echo 0:1  >/var/dmx/dmxin
                                cat  </var/dmx/dmxout

                Instruct dmx to exit:

                                echo  0:0  >/var/dmx/dmxin