WS8211 en WS8211 & QLC+ <span class="field field--name-title field--type-string field--label-hidden">WS8211 &amp; QLC+</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item">Why? <p>Not long ago, I purchased some <a href="">LED spots</a> from Thomann. Of course I wanted to control them somehow. Thus, I bought an <a href="">USB-to-DMX-interface and a fitting adapter cable</a>, too. And I started to learn, how to use <a href="">QLC+</a>.</p> <p><strong>QLC+</strong> is an Open Source software for stage lighting control using <a href="">DMX512</a> and <a href="">other protocols</a>.</p> <p>While playing with QLC+ I discovered a <a href="">video</a> shared by it's main developer. This video shows an LED matrix controlled using QLC+.</p> <p>And I thought: I want that too!</p> the LED display <p>I started looking for affordable LED stripes with individually controllable pixels. I found some on <a href="">eBay</a>; Basically, there are four different kinds of stripes around differing in the chips they deploy:</p> <ul><li>WS8201</li> <li>WS8211</li> <li>WS8212</li> <li>WS8212B</li> </ul><p>The WS8201 communicates using <a href="">SPI</a>. For that kind of stripe there is a <a href="">tutorial</a> how to drive it using a Raspberry Pi. That's likely to be the means of control the QLC+ developer Massimo Callegari used.</p> <p>I decided to buy three <a href="">stripes with WS8211</a> with a total length of 15 m because they are cheaper. Those 15 meters hold 900 LEDs. I planned to build a matrix with 75×12 pixels. The stripes arrived the day after, so I searched for an appropriate wooden board and sticked the stripes onto it.</p> Power supply <p>Although a single LED does not consume much energy, a total of 900 LEDs will: 900 × 60 mA will eat up a whole 18 amps, or 216 watts at 12 V. Therefore it is important to supply each of the 12 stripes individually and use a power supply with enough power. Fortunately, I had a spare server power unit and started to solder cables to the stripes: Because neighbouring stripes are pointing in opposite directions, I have same electrical poles next to each other such that I was able to connect them to a common cable:</p> <p><img src="/sites/default/files/2019-07/matrix-strom_0.png" alt="power supply" /></p> <p>As the server power unit is an ATX supply, one needs to connect the green (power) cable on the large multi-line plug with one of the black ones (ground) to turn it on.</p> <p>Connecting the data lines was easy. One just has to connect the middle poles on the ends thereby following the arrows along the stripes.</p> <p><img src="/sites/default/files/2019-07/IMG_0573.JPG" alt="data line connections" /></p> <p>In the images you can see, that on some stripes I also interconnected the power lines. I started to do this <em>before I thought of the power connections</em> and these connections at the ends of the stripes are not required.</p> Feeding the matrix with data <p>For a first proof of concept, I wanted to use an already present Raspberry Pi. A short <a href="">search in the webs</a> led me to a short python program, fitting my needs:</p> <p><a href=""><strong>WS2812 RGB LED Streifen per Raspberry Pi steuern</strong></a>¹.</p> <h2>Preparations</h2> <p>Following the instructions, I connected the ground (Pin 6) of my Raspberry to the minus pole of the LED stripes and Pin 12 (GPIO 18) to the data input connector of the very first stripe segment.</p> <p>Then I launched the following commands on the Raspberry:</p> <pre><code>sudo apt-get update sudo apt-get install gcc make build-essential python-dev git scons swig sudo echo "blacklist snd_bcm2835" &gt; /etc/modprobe.d/snd-blacklist.conf sudo nano /boot/config.txt </code></pre> <p>to alter the line <code>dtparam=audio=on</code> to <code>#dtparam=audio=on</code>.</p> <p>After a reboot:</p> <h2>Software installation</h2> <pre><code>git clone cd rpi_ws281x/ sudo scons cd python sudo python build sudo python install </code></pre> <h2>Test script to let python control the leds</h2> <p>As described in the instructions, I started an editor with <code>sudo nano examples/</code> and adjusted the line<br /><code>LED_COUNT = 16 # Number of LED pixels.</code> – I have some 900 pixels. Re-checked that the right pin is configured for the data line:<br /><code>LED_PIN = 18 # GPIO pin connected to the pixels (18 uses PWM!).</code></p> <p>And we are set to test the whole thing:</p> <pre><code>sudo PYTHONPATH=".:build/lib.linux-armv7l-2.7" python examples/ </code></pre> <p>And there was light! But something was odd:</p> <p>I noticed that I had missed something in the description of the led stripes. On the stripes I purchased, each chip controls three RGB LEDs, meaning my effective resolution was only 300 pixels! Damn!</p> <p>After a short moment of sadness I accepted that fact and re-adjusted the corresponding line in the script: <code>LED_COUNT = 300 # Number of LED pixels.</code> Done.</p> <h2>Control via QLC+</h2> <p>The original goal was to control the led matrix using QLC+. I already knew that this software was able to run on the Raspberry and to drive WS201 LEDs utilizing SPI protocol. Now I needed to find a solution to drive WS8211 stripes.</p> <p>I had different ideas in mind:</p> <ol><li>convert the SPI signals electronically. I found two circuits that seemed appropriate: <ol><li><a href="">SPI nach WS2811-Umsetzer mittels Standard-Logik</a></li> <li><a href="">WS2811 SPI Driver Using One Transistor And Passives</a><br /> I did not try to implement any of them, since I found another solution (below).</li> </ol></li> <li>convert the SPI signal with a micro controller<br /> I tried to use an Arduino in SPI slave mode to <a href="">receive the SPI data</a> and then drive the LEDs using <a href="">bit banging</a>. Unfortunately, I did not succeed: for a reason unknown to me, the Arduino always missed the first bit of each incoming packet. Moreover, the frequency of the SPI transmission is way to high for the Arduino controller.</li> <li>converting SPI by software<br /> I thought maybe it could be possible to provide a virtual SPI port to QLC+, grab the data passed to it and actually send them by bit banging. I have to admit, I have no clue how one could do this.</li> </ol><p>As mentioned, I did not master any of these ideas, but I found another solution:</p> <p>Without any problems, a python program on the raspberry can receive <a href="">ArtNet</a> packets and control the matrix with a modified version of the <strong>Strandtest.Py</strong> program!</p> <p><img src="/sites/default/files/2019-07/quellcode.png" alt="snippet of source code" /> The <a href="">resulting Python script</a> can be run easily:</p> <pre><code>cd ~ sudo PYTHONPATH="rpi_ws281x/python/build/lib.linux-armv7l-2.7/" python --brightness=255 -c </code></pre> <p>The path <code>rpi_ws281x/python/build/lib.linux-armv7l-2.7/</code> is to be replaced by the corresponding directory (see → Software installation). The script is tailored for my hardware setup: The LED matrix is divided into two universes, each with 150 LEDs, in QLC+. Those are adressed as ArtNet universes 0 and 1 in the local network. Thus, the script only recieves data from these universes and applies data from universe 0 to the LEDs with index 1 to 150 and universe 1 to LEDs 151 to 300, respectively.</p> <p>You will probably need to adjust the program for other setups!</p> Performance <p>For my first tests, I utilized a Raspberry Pi Model 1. With its single core, this device is rather slow. Too slow to process the commands from QLC+ in real time. I transferred the whole software to a Raspberry Pi 3 afterwards. And, well, it works!</p> <p>1) WS2811, WS2812 and WS2812B are compatible. They are different makeups of the same Controller type.</p></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">Stephan Richter</span></span> <span class="field field--name-created field--type-created field--label-hidden">Fri, 07/12/2019 - 23:26</span> <div><div class="juicebox-parent"> <div id="node--387--field-galerie--rss" class="juicebox-container"> <noscript> <!-- Image gallery content for non-javascript devices --> <p class="jb-image"> <img src="/sites/default/files/2019-07/IMG_0564.JPG" alt="" title="The assembled LED Matrix" typeof="foaf:Image" /> <br/> <span class="jb-title">The assembled LED Matrix</span><br/> <span class="jb-caption"></span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/IMG_0565.JPG" alt="Left for minus, right for plus pole" title="Cable strips for power supply" typeof="foaf:Image" /> <br/> <span class="jb-title">Cable strips for power supply</span><br/> <span class="jb-caption">Left for minus, right for plus pole</span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/matrix-strom_0.png" alt="Pairs of led stripes are supplied with a common cable pair" title="Power supply sheme" typeof="foaf:Image" /> <br/> <span class="jb-title">Power supply sheme</span><br/> <span class="jb-caption">Pairs of led stripes are supplied with a common cable pair</span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/IMG_0567.JPG" alt="" title="Connection to the stripes" typeof="foaf:Image" /> <br/> <span class="jb-title">Connection to the stripes</span><br/> <span class="jb-caption"></span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/IMG_0568.JPG" alt="Here the cables start to the individual stripes." title="Energy distribution" typeof="foaf:Image" /> <br/> <span class="jb-title">Energy distribution</span><br/> <span class="jb-caption">Here the cables start to the individual stripes.</span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/IMG_0569.JPG" alt="" title="The server power unit" typeof="foaf:Image" /> <br/> <span class="jb-title">The server power unit</span><br/> <span class="jb-caption"></span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/IMG_0570.JPG" alt="requires to connect the green line with one of the blacks." title="Powering on the power supply" typeof="foaf:Image" /> <br/> <span class="jb-title">Powering on the power supply</span><br/> <span class="jb-caption">requires to connect the green line with one of the blacks.</span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/IMG_0573.JPG" alt="are daisy-chained following the arrows." title="Data lines" typeof="foaf:Image" /> <br/> <span class="jb-title">Data lines</span><br/> <span class="jb-caption">are daisy-chained following the arrows.</span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/IMG_0575.JPG" alt="The cable top left (of which only the white and red line are used for ground and data,respectively) connects to the leds" title="The Raspi 3" typeof="foaf:Image" /> <br/> <span class="jb-title">The Raspi 3</span><br/> <span class="jb-caption">The cable top left (of which only the white and red line are used for ground and data,respectively) connects to the leds</span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/quellcode.png" alt="" title="Snippet of the source code" typeof="foaf:Image" /> <br/> <span class="jb-title">Snippet of the source code</span><br/> <span class="jb-caption"></span> </p> <p class="jb-image"> <img src="/sites/default/files/2019-07/ytshot.png" alt="Have a look at the video!" title="The matrix in action" typeof="foaf:Image" /> <br/> <span class="jb-title">The matrix in action</span><br/> <span class="jb-caption">Have a look at the video!</span> </p> </noscript> </div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">Blog tags</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/10" hreflang="de">LED</a></div> <div class="field__item"><a href="/taxonomy/term/11" hreflang="de">Raspberry</a></div> <div class="field__item"><a href="/taxonomy/term/12" hreflang="de">WS8201</a></div> <div class="field__item"><a href="/taxonomy/term/13" hreflang="de">WS8211</a></div> <div class="field__item"><a href="/taxonomy/term/14" hreflang="de">WS8212</a></div> <div class="field__item"><a href="/taxonomy/term/15" hreflang="de">WS8212B</a></div> <div class="field__item"><a href="/taxonomy/term/16" hreflang="de">SPI</a></div> </div> </div> <section class="field field--name-field-blog-comments field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=387&amp;2=field_blog_comments&amp;3=comment" token="rElTXKOZad2LIgiL4YNiWciG37EyZ_YpD0vIlPlD4zA"></drupal-render-placeholder> </section> Fri, 12 Jul 2019 08:16:57 +0000 Stephan Richter 387 at