<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Photons, Electrons, and Dirt &#187; Lighting</title>
	<atom:link href="https://bikerglen.com/blog/category/lighting/feed/" rel="self" type="application/rss+xml" />
	<link>https://bikerglen.com/blog</link>
	<description>A blog by Glen Akins</description>
	<lastBuildDate>Sat, 22 Aug 2026 16:30:53 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Build a DMX FeatherWing to Control Lights with a Feather M0</title>
		<link>https://bikerglen.com/blog/dmx-featherwing-light-controller/</link>
		<comments>https://bikerglen.com/blog/dmx-featherwing-light-controller/#comments</comments>
		<pubDate>Tue, 25 Feb 2020 01:59:40 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[DMX / Art-Net]]></category>
		<category><![CDATA[Ethernet]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[Power over Ethernet (PoE)]]></category>
		<category><![CDATA[SAMD21]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=2296</guid>
		<description><![CDATA[This project uses an Adafruit Feather M0 board to control a group of RGB lights using the DMX-512 protocol. We'll build a DMX-512 FeatherWing and connect it to the Feather M0 and a Particle Ethernet FeatherWing. Finally, we'll develop a web-based GUI to select different RGB lighting effects and control the lights. <a href="https://bikerglen.com/blog/dmx-featherwing-light-controller/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_2383" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/cover-photo-one.jpg"><img class="size-large wp-image-2383" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/cover-photo-one-1024x682.jpg" alt="Playing around with the DMX FeatherWing, a Particle Ethernew FeatherWing, an Adafruit Feather M0 Basic Proto, the official Nanoleaf DMX interface, and a Nanoleaf Aurora tile." width="640" height="426" /></a><p class="wp-caption-text">Playing around with the DMX FeatherWing, a Particle Ethernet FeatherWing, an Adafruit Feather M0 Basic Proto, the official Nanoleaf DMX interface, and a Nanoleaf Aurora tile. The GUI on the iPad tells the Feather M0 which light program to run. The program output is sent via DMX-512 to the Nanoleaf setup.</p></div>
<p>This project uses an Adafruit Feather M0 Basic Proto board to control a group of Color Kinetics or other RGB light fixtures using the DMX-512 protocol. We&#8217;ll build a DMX-512 interface FeatherWing then connect it to the Feather M0 using a Particle Ethernet FeatherWing. Once the hardware is built and assembled, we&#8217;ll write software with a web-based GUI to generate RGB lighting effects and control the attached RGB lights using the DMX protocol. By modifying the software on the Feather M0, different effects can be generated and added to the web-based GUI.</p>
<p><span id="more-2296"></span></p>
<h2>Required Materials</h2>
<p>The materials required for this project are:</p>
<ul>
<li>DMX FeatherWing board and parts. We&#8217;ll discuss ordering the board, the required parts, and the assembly in the next section.</li>
<li><a href="https://www.adafruit.com/product/2772">Adafruit Feather M0 Basic Proto</a></li>
<li><a href="https://www.adafruit.com/product/4003">Particle Ethernet FeatherWing</a></li>
<li><a href="https://store.particle.io/products/power-over-ethernet-module">Particle Ethernet FeatherWing PoE Adapter</a> (optional). Note: The PoE adapter has been discontinued. If you want to make your own version, the Eagle design files are available <a href="https://github.com/particle-iot/ethernet-wing/tree/master/eagle/PoE-adapter-v0.2">here</a> but the header sockets on the module <a href="https://community.particle.io/t/ethernet-featherwing-power-over-ethernet-poe/45130/9">need to be moved</a> to align with the headers on the Ethernet FeatherWing board.</li>
</ul>
<h2>The DMX FeatherWing</h2>
<div id="attachment_2377" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-2.jpg"><img class="wp-image-2377 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-2-1024x682.jpg" alt="dmx-featherwing-2" width="640" height="426" /></a><p class="wp-caption-text">The assembled DMX FeatherWing board. I fixed the location of the DIR silkscreen label in the Eagle design files and on the board order link at OSH Park.</p></div>
<p>The photo above shows the assembled DMX FeatherWing. The next few sections are dedicated to describing and building the DMX FeatherWing hardware.</p>
<h3>Circuit Design and Schematic</h3>
<div id="attachment_2319" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-schematic1.png"><img class="size-large wp-image-2319" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-schematic1-1024x764.png" alt="DMX-512 FeatherWing schematic." width="640" height="478" /></a><p class="wp-caption-text">DMX-512 FeatherWing schematic.</p></div>
<p>To make sure everything conformed to the FeatherWing form factor, I started with the Eagle design for the <a href="https://github.com/adafruit/Adafruit-Power-Relay-FeatherWing-PCB">Adafruit Power Relay FeatherWing</a>. I deleted everything from the schematic and board except for the FeatherWing symbol and dimension lines. The FeatherWing symbol includes the board outline layer and the holes for the 0.1&#8243; pitch, 0.025&#8243; square post headers that connect the FeatherWing to other boards. I saved this as a new file then started my design.</p>
<p>U1 is a Ti 3.3V differential transceiver. Its transmit data input is connected to the Feather&#8217;s transmit data output pin. Its receive data output is connected to the Feather&#8217;s receive data input. The direction line is connected to a GPIO pin. I only plan on transmitting data so I could have tied the direction pin high to permanently enable the transmitter and disable the receiver but connecting it to a GPIO allows me to control the direction in software and could be useful for future projects.</p>
<p>J1 is a plastic RJ-45 8P8C jack. It&#8217;s wired to connect to <a href="https://www.docs.colorkinetics.com/support/appnotes/notes/rj45_to_rj45.pdf">Philips Color Kinetics&#8217; lights and controllers</a>. Other DMX lights with RJ-45 jacks may use different pin outs. Typically pins 1 and 2 are swapped or the shield is on a different pin on these lights. R1 is the 120 ohm termination resistor required at the transmitter by the DMX specification. Another 120 ohm termination resistor should be placed at the last fixture in the chain of fixtures.</p>
<p>The rest of the parts are for decoupling, EMC compatibility, and ESD protection. C1 is a decoupling capacitor to filter voltage transients on the supply to the differential transceiver. C2 grounds high frequency noise on the shield line while preventing a DC current loop between the board and any connected light fixtures. This should help with EMC compatibility but still provide isolation between the hardware at either end of the DMX cable.</p>
<p>D1 and D2 provide additional ESD protection beyond the ESD protection built into the differential receiver. Their function is described in the TI application note <a href="http://Protecting RS-485 Interfaces Against Lethal Electrical Transients">Protecting RS-485 Interfaces Against Lethal Electrical Transients</a>.</p>
<h3>Board Design</h3>
<div id="attachment_2330" style="width: 887px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-board1.png"><img class="size-full wp-image-2330" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-board1.png" alt="DMX-512 FeatherWing board design." width="877" height="662" /></a><p class="wp-caption-text">DMX-512 FeatherWing board design.</p></div>
<p>Components were placed on the board to minimize the length of the signal traces. The differential data lines between J1 and U1 contain a small loop to equalize their lengths. The termination resistor and ESD components connect straight from these pins to the pins on the differential transceiver. C1 is located as close as possible to U1&#8217;s 3.3 V supply line. The direction, transmit data, and receive data lines are routed to the FeatherWing headers.</p>
<div id="attachment_2331" style="width: 1011px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-render-top1.png"><img class="size-full wp-image-2331" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-render-top1.png" alt="DMX-512 FeatherWing top side board render." width="1001" height="451" /></a><p class="wp-caption-text">DMX-512 FeatherWing top side board render.</p></div>
<div id="attachment_2332" style="width: 1011px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-render-bottom1.png"><img class="size-full wp-image-2332" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-featherwing-render-bottom1.png" alt="DMX-512 FeatherWing bottom side board render." width="1001" height="451" /></a><p class="wp-caption-text">DMX-512 FeatherWing bottom side board render.</p></div>
<p>Once the board design was done, I uploaded the Gerber files to OSH Park and checked the renders to make sure everything looked OK. Once I was happy, I ordered the boards from OSH Park.</p>
<h3>Ordering Boards</h3>
<p>If you wish to use the board exactly as designed, you can order a blank board from OSH Park <a href="https://oshpark.com/shared_projects/xnTMPyYn">here</a>. If not, you can download the Eagle <a href="https://github.com/bikerglen/atsamd21-poe-dmx-controller/tree/master/boards/dmx-featherwing">design files</a> from Github, make your desired modifications, create Gerbers, and order boards from your favorite PCB manufacturer. My top and bottom silkscreens are located on layers 121 and 122 respectively so you may need to alter your CAM processor script to output these layers to the silkscreen Gerber files.</p>
<h3>Bill of Materials</h3>
<p>The bill of materials is available in the Github repository as an <a href="https://github.com/bikerglen/atsamd21-poe-dmx-controller/blob/master/boards/dmx-featherwing/dmx-feather-wing-v1-bom.xlsx">Excel spreadsheet</a>. It&#8217;s also reproduced below for your convenience. All the parts are available from Digi-Key.</p>
<table border="0" width="1005" cellspacing="0" cellpadding="0">
<colgroup>
<col style="mso-width-source: userset; mso-width-alt: 2218; width: 47pt;" width="62" />
<col style="mso-width-source: userset; mso-width-alt: 4266; width: 90pt;" width="120" />
<col style="mso-width-source: userset; mso-width-alt: 10865; width: 229pt;" width="306" />
<col style="mso-width-source: userset; mso-width-alt: 5660; width: 119pt;" width="159" />
<col style="mso-width-source: userset; mso-width-alt: 6172; width: 130pt;" width="174" />
<col style="mso-width-source: userset; mso-width-alt: 6542; width: 138pt;" width="184" /> </colgroup>
<tbody>
<tr style="height: 14.4pt;">
<td style="height: 14.4pt; width: 47pt;" width="62" height="19">Qty</td>
<td style="width: 90pt;" width="120">Parts</td>
<td style="width: 229pt;" width="306">Description</td>
<td style="width: 119pt;" width="159">Mfr</td>
<td style="width: 130pt;" width="174">Mfr Part #</td>
<td style="width: 138pt;" width="184">Digi-Key Part #</td>
</tr>
<tr style="height: 14.4pt;">
<td class="xl66" style="height: 14.4pt;" height="19">1</td>
<td>C1</td>
<td>CAP CER 0.1UF 10V X7R 0805</td>
<td>Kemet</td>
<td>C0805C104K8RACTU</td>
<td>399-7999-1-ND</td>
</tr>
<tr style="height: 14.4pt;">
<td class="xl66" style="height: 14.4pt;" height="19">1</td>
<td>C2</td>
<td>CAP CER 1000pF 2KV 10% X7R SMD 1206</td>
<td>Johanson Dielectrics</td>
<td>202R18W102KV4E</td>
<td>709-1036-1-ND</td>
</tr>
<tr style="height: 14.4pt;">
<td class="xl66" style="height: 14.4pt;" height="19">1</td>
<td>D1</td>
<td>TVS DIODE 12V 29.5V SOD323</td>
<td>Bourns Inc.</td>
<td>CDSOD323-T12SC</td>
<td>CDSOD323-T12SCCT-ND</td>
</tr>
<tr style="height: 14.4pt;">
<td class="xl66" style="height: 14.4pt;" height="19">1</td>
<td>D2</td>
<td>TVS DIODE 7V/12V 14V/26V SOT23-3</td>
<td>Bourns Inc.</td>
<td>CDSOT23-SM712</td>
<td>CDSOT23-SM712CT-ND</td>
</tr>
<tr style="height: 14.4pt;">
<td class="xl66" style="height: 14.4pt;" height="19">1</td>
<td>J1</td>
<td>CONN MOD JACK 8P8C R/A UNSHLD</td>
<td>TE Connectivity</td>
<td>5520251-4</td>
<td>A31407-ND</td>
</tr>
<tr style="height: 14.4pt;">
<td class="xl66" style="height: 14.4pt;" height="19">1</td>
<td>R1</td>
<td>RES SMD 120 OHM 5% 1/8W 0805</td>
<td>Panasonic</td>
<td>ERJ-6GEYJ121V</td>
<td>P120ACT-ND</td>
</tr>
<tr style="height: 14.4pt;">
<td class="xl66" style="height: 14.4pt;" height="19">1</td>
<td>U1</td>
<td>IC TRANSCEIVER HALF 1/1 8SOIC</td>
<td>Texas Instruments</td>
<td>SN65HVD11DR</td>
<td>296-31717-1-ND</td>
</tr>
<tr style="height: 14.4pt;">
<td class="xl66" style="height: 14.4pt;" height="19">1</td>
<td class="xl67"><span style="mso-spacerun: yes;"> </span>&#8212;</td>
<td class="xl68">CONN HEADER VERT 50POS 2.54MM</td>
<td class="xl68">Samtec Inc.</td>
<td class="xl68">TSW-150-07-G-S</td>
<td class="xl68">SAM1029-50-ND</td>
</tr>
</tbody>
</table>
<h3>DMX FeatherWing Assembly</h3>
<p>To assemble the board, solder all the surface mount components first starting with U1. Once the surface mount components are soldered, solder the headers to the bottom of the board. It can be helpful to place the headers in a breadboard to hold them in place while soldering them to the DMX FeatherWing. This technique is described in detail on Adafruit&#8217;s website <a href="https://learn.adafruit.com/adafruit-feather-m0-adalogger/assembly#soldering-in-plain-headers-3-7">here</a>. Finally, insert the RJ-45 connector into the top of the board, flip the board over, and solder the connector in place.</p>
<h2>Assemble the Board Stack</h2>
<div id="attachment_2374" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/assembled-board-stack-no-poe1.jpg"><img class="size-large wp-image-2374" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/assembled-board-stack-no-poe1-1024x682.jpg" alt="The assembled stack of boards. Do not connect the PoE module at this time." width="640" height="426" /></a><p class="wp-caption-text">The assembled stack of boards. Do not connect the PoE module at this time.</p></div>
<p>Once the DMX FeatherWing is assembled, it&#8217;s time to connect all three boards together. Holding the Particle Ethernet FeatherWing board with the Ethernet circuitry on my left, I placed the Adafruit Feather M0 Basic Proto in the middle of the board and the DMX FeatherWing on the right of the board. If you have the optional PoE module, do NOT install it at this time!</p>
<p>We&#8217;re going to be using the USB cable to power the stack of boards and download software to the ATSAMD21. Powering the boards from both the PoE supply and the USB cable can result in damage to your boards and/or your computer. Never use both the PoE module and the USB cable at the same time.</p>
<h2>Install Software Environment and Libraries</h2>
<p>This project uses the Arduino integrated development environment for the Adafruit Feather M0 Basic Proto. Follow the instructions <a href="https://learn.adafruit.com/adafruit-feather-m0-basic-proto/setup">on the Feather M0 Basic Proto tutorial page</a> to install the Arduino IDE and additional boards manager URL. Once those are installed, install the libraries required for the Feather M0 boards and the ATSAMD21 as instructed on the <a href="https://learn.adafruit.com/adafruit-feather-m0-basic-proto/using-with-arduino-ide">next page of the same tutorial</a>.</p>
<p>This project also uses the Arduino Ethernet and Timer libraries. Follow <a href="https://learn.adafruit.com/adafruit-wiz5500-wiznet-ethernet-featherwing/usage#install-ethernet-library-4-3">these instructions</a> to install the Ethernet library. After installing the Ethernet library, install the Arduino Timer library. It&#8217;s the same process as for the Ethernet library except search for the arduino-timer library by Michael Contreras v2.0.1. Once you&#8217;ve found it in the GUI, install the library and perform one last restart of the Arduino IDE.</p>
<h2>Test the Software Installation</h2>
<p>I recommend testing the software installation by building and running the WebServer example for the Ethernet library. In the Arduino IDE, click Tools -&gt; Board -&gt; Adafruit Feather M0. Once the board is selected, click on File -&gt; Examples -&gt; Ethernet -&gt; WebServer to open a new window with the example WebServer project. Be sure to pick Ethernet and not Ethernet2.</p>
<p>Now select File -&gt; Save As to save a copy of the WebServer example in your Arduino projects directory. Find the IPAddress ip (&#8230;) line and change the IP address to a valid static IP address for your network. Finally uncomment the line Ethernet.init(10) to pick the correct chip select for the combination of the Particle Ethernet FeatherWing and Adafruit Feather M0 Basic Proto boards.</p>
<div id="attachment_2380" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/debugging-code-setup.jpg"><img class="size-large wp-image-2380" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/debugging-code-setup-1024x682.jpg" alt="The boards set up to download and test the code." width="640" height="426" /></a><p class="wp-caption-text">The boards set up to download and test the code.</p></div>
<p>Connect the RJ-45 Ethernet jack to an Ethernet switch on the same network as your computer. Make sure the optional PoE module is NOT installed then connect the micro USB connector on the Feather M0 board to a free USB port on the computer.</p>
<p>Go to Tools -&gt; Port and select the COM port connected to the Feather M0. Now launch the serial monitor by selecting Tools -&gt; Serial Monitor. Finally build the example and download the code to the board by selecting Sketch -&gt; Upload in the Arduino IDE.</p>
<p>If everything is successful, you should see something similar to the following in the serial monitor window:</p>
<div id="attachment_2342" style="width: 1013px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/serial-monitor-1.png"><img class="size-full wp-image-2342" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/serial-monitor-1.png" alt="Build and download success!" width="1003" height="591" /></a><p class="wp-caption-text">Build and download success!</p></div>
<p>Use your favorite web browser to navigate to the specified IP address. You may need to prepend http:// to the IP address for some browsers. You should get something similar to the following:</p>
<div id="attachment_2343" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/web-browser-1.png"><img class="size-large wp-image-2343" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/web-browser-1-1024x696.png" alt="Web server test successful!" width="640" height="435" /></a><p class="wp-caption-text">Web server test successful!</p></div>
<p>And the serial monitor will update with some debugging info every time the browser is refreshed:</p>
<div id="attachment_2344" style="width: 1013px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/serial-monitor-2.png"><img class="size-full wp-image-2344" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/serial-monitor-2.png" alt="The serial monitor after sending a web page to the web browser." width="1003" height="591" /></a><p class="wp-caption-text">The serial monitor after sending a web page to the web browser.</p></div>
<p>At this point, the test is successful and it&#8217;s time to try to control some lights with the real software.</p>
<h2>Connect Some RGB DMX Lights</h2>
<div id="attachment_2375" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-light-channel-one.jpg"><img class="size-large wp-image-2375" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/dmx-light-channel-one-1024x682.jpg" alt="An inexpensive light like this one with an RJ-45 to XLR 3-pin adapter cable makes a good fixture for testing the hardware and software." width="640" height="426" /></a><p class="wp-caption-text">An inexpensive light like this one with a homemade RJ-45 to XLR 3-pin adapter cable makes a good fixture for testing the hardware and software.</p></div>
<p>Connect some RGB DMX lights to the DMX FeatherWing&#8217;s RJ-45 jack. The software in its default configuration controls 24 RGB lights using DMX channels 1 to 72. Make sure your connected lights are in this range and the red channels start with 1, 4, 7, etc.</p>
<h2>Download and Run the DMX Controller Software</h2>
<h3>Download the DMX Controller Source Code from Github</h3>
<p>My latest DMX controller software can be downloaded from Github <a href="https://github.com/bikerglen/atsamd21-poe-dmx-controller/tree/master/sw/dmx-controller">here</a>. Download these files into a new folder. This folder must be named dmx-controller and must be inside the Arduino projects folder. This is a constraint of the Arduino IDE.</p>
<h3>Set the IP Address</h3>
<p>Just like for the example WebServer project, the IP address must be set to a valid static IP address for your network. Find the IPAddress ip (&#8230;) line in the dmx-controller.ino file and set it to a suitable IP address.</p>
<h3>Build and Download the Code to the Feather M0</h3>
<p>If the serial monitor window is not already open, open it again by selecting Tools -&gt; Serial Monitor. Now build and download the code by selecting Sketch -&gt; Upload.</p>
<h3>Using the Web Interface</h3>
<p>Enter the IP address from above into your favorite web browser and you should get the following web page:</p>
<div id="attachment_2346" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/web-browser-2.png"><img class="size-large wp-image-2346" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/web-browser-2-1024x696.png" alt="Opening page of the web-based GUI for controlling the attached lights." width="640" height="435" /></a><p class="wp-caption-text">Opening page of the web-based GUI for controlling the attached lights.</p></div>
<p>Now click the Fixed Color tab. The web page will update to display this screen:</p>
<div id="attachment_2347" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/web-browser-3.png"><img class="size-large wp-image-2347" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/web-browser-3-1024x696.png" alt="Fixed color tab." width="640" height="435" /></a><p class="wp-caption-text">Fixed color tab.</p></div>
<p>Clicking on a color should change the color of the connected lights to the selected color. Once this is working, experiment with some of the other tabs and settings.</p>
<div id="attachment_2367" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/red-wall-wash.jpg"><img class="size-large wp-image-2367" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/red-wall-wash-683x1024.jpg" alt="My living room wall washed in red light using the fixed color mode on the controller." width="640" height="960" /></a><p class="wp-caption-text">My living room wall washed in red light using the fixed color mode on the controller.</p></div>
<p>Congratulations if you&#8217;ve made it this far! At this point the project works. The following sections are for those who wish to dive deeper into the controller&#8217;s functionality or modify the software or hardware.</p>
<h2>Software Details</h2>
<h3>Sending DMX Data with the ATSAMD21</h3>
<p>To send DMX-512 data with the ATSAMD21 microcontroller, I used the <a href="https://github.com/claudeheintz/LXSAMD21DMX">LXSAMD21MDX library</a> by Claude Heintz as a starting point. Unfortunately, this library sends DMX data continuously so as soon as a packet is done being sent, it immediately starts sending the next packet.</p>
<p>This causes a problem because there&#8217;s no way to guarantee that I won&#8217;t update the RGB values for a light in the middle of those values being sent. For example, if I were updating the RGB values for a light and the library sent the new red and new green values before I could update the blue value, this could cause a light to flash a wrong color for a brief instant.</p>
<p>Next I tried stopping the DMX transmission using the stop function in the library. Calling this function completely disabled the serial port and, as a result, the transmit data line was no longer driven. This caused a very long low / break signal to be transmitted between packets which is against the DMX-512 specification that requires the line to be held in the high / mark state between packets.</p>
<div id="attachment_2356" style="width: 810px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/scope_0.png"><img class="size-full wp-image-2356" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/scope_0.png" alt="Screen capture from my scope showing DMX packets being transmitted at 50 Hz. The transmit data line is held high between packets which is the idle state for the serial interface." width="800" height="632" /></a><p class="wp-caption-text">Screen capture from my scope. The yellow trace shows DMX packets being transmitted at 50 Hz (20 ms between the start of each packet). The transmit data line is held high between packets which is the idle state for the serial interface. The green trace was connected to a GPIO that was set upon entry to the SERCOM2 interrupt handler and cleared upon exit.</p></div>
<p>I decided to rewrite the DMX library and to use a double buffering scheme. The light levels are calculated and stored in an effects buffer. When it&#8217;s time to send a packet, the light levels are copied from the effects buffer to a transmit data buffer. The library is then called to transmit a single DMX packet using the values in the transmit data buffer.</p>
<p>While the DMX packet is being sent, the effects generation code is called to generate the next set of light levels and store them in the effects data buffer. This happens at a 50 Hz rate and completely prevents partially modified data from being sent to the lights. I used a scope to verify the packet rate, the DMX-512 break period, and the bit rate on the interface.</p>
<div id="attachment_2357" style="width: 810px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/scope_3.png"><img class="wp-image-2357 size-full" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/scope_3.png" alt="blah blah blah" width="800" height="632" /></a><p class="wp-caption-text">The DMX packet starts with a break of 100 us (yellow trace). This is much longer than a normal 250,000 bps break character. The scope was set to trigger on a negative pulse with a pulse width greater than 80.0 us. The green trace was connected to a GPIO that was set upon entry to the SERCOM2 interrupt handler and cleared upon exit.</p></div>
<p>While I was prototyping the project, I left the microcontroller&#8217;s receive data pin unconnected. This resulted in the microcontroller receiving errored characters and generating both receive character and error interrupts. Since I wasn&#8217;t expecting or handling these interrupts, this resulted in the microcontroller being stuck in the interrupt handler.</p>
<p>I traced the cause of this behavior to the begin method in the Arduino Uart class which enables the receive character and error interrupts. I disabled these interrupts by adding the following code immediately after calling the Uart class&#8217;s begin method and everything started working:</p>
<pre>     SERCOM2-&gt;USART.INTENCLR.reg = SERCOM_USART_INTENCLR_RXC | 
                                 SERCOM_USART_INTENCLR_ERROR;</pre>
<p>This likely isn&#8217;t an issue with the real hardware because the receive data pin is not left floating. I&#8217;m not using the receive portion of the USART, however, so I might as well disable the interrupts to avoid any chance of them causing problems in the future. I could probably even disable the USART&#8217;s receiver altogether if I wanted.</p>
<h3>Modifying the Built-In Effects or Adding New Effects</h3>
<p>Adding a new effect to the code requires defining a new mode, adding some HTML to display the options for the mode, parsing the HTTP request to get the options for the mode, and adding code to run the mode.</p>
<h4>effects.ino</h4>
<p>The effects.ino file contains code to run the effects and change options associated with each effect. This file requires several additions to create a new mode.</p>
<ol>
<li>The enum at the very top of the effects.ino file defines the available modes. To add a mode, add another definition to this enum.</li>
<li>Scroll down the file a bit and look for the global variables starting with the effects_ prefix. Add any variables to store options associated with the new mode here.</li>
<li>Inside the effects_Init function, add code to initialize the options associated with the new mode to reasonable default values.</li>
<li>Inside the effects_Run function, add another case statement to the switch block to call a new function to generate the mode&#8217;s effects.</li>
<li>Under the EFFECTS GENERATORS heading, add a new function to generate the effect. This function should be named the same as the function added in step 4 above. This function will be called once every 20 ms and should use the effects_ global variables added in step 2 to calculate the next step in the effect. The RGB values should then be written to the effects_data array. This array contains DMX_SLOTS values which corresponds to DMX_SLOTS / 3 RGB lighting fixtures.</li>
<li>Under the COMMANDS FROM UI heading, add any functions that will be called by the HTTP request parsing code to modify the effects_ global variables.</li>
</ol>
<h4>dmx-controller.ino</h4>
<p>The dmx-controller.ino file contains the code to parse the HTTP GET request from the web browser. The HTTP GET request is parsed by the ParseRequest function.</p>
<ol>
<li>Add any new key value pairs to the long if-else block about half way through this code.</li>
<li>Add code to call the functions defined in step 6 in the previous section to modify the effects_ global variables under the Set Parameters comment.</li>
</ol>
<h4>html.ino</h4>
<p>The html.ino file contains C/C++ code that emits HTML to the web browser to permit the user to change the mode and configure any options associated with the mode. The function SendHtmlPage is the function that is called to emit the HTML.</p>
<ol>
<li>Add an additional call to the Tab function with the mode number and name in SendHtmlPage. This creates an additional tab pane for the options for the new mode.</li>
<li>Add a case statement to the switch block in SendHtmlPage with a call to a function to generate the HTML that fills the options tab for the new mode.</li>
<li>Add the function called in step 2 above to generate the HTML to the bottom of the file.</li>
</ol>
<h4> style.ino</h4>
<p>If you need additional CSS style code, add C code to generate it in the style.ino file.</p>
<h4>samd21dmx.cpp and samd21dmx.h</h4>
<p>These files send the DMX packets. If you have more than 24 RGB lights or need more than 72 DMX channels, adjust the DMX_SLOTS define in samd21dmx.h.</p>
<h2>Next Steps</h2>
<p>Here are some ideas for future enhancements to the project.</p>
<h3>Use PoE</h3>
<div id="attachment_2379" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/ethernet-poe-dmx-no-usb.jpg"><img class="size-large wp-image-2379" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/ethernet-poe-dmx-no-usb-1024x683.jpg" alt="Once the software is debugged, the USB cable can be disconnected and the boards powered using the optional PoE module." width="640" height="427" /></a><p class="wp-caption-text">Once the software is debugged, the USB cable can be disconnected and the boards powered using the optional PoE module.</p></div>
<p>If you have the PoE module for the Particle Ethernet FeatherWing, now would be a good time to try it out. Disconnect both the USB cable and Ethernet cable from the stack of boards. Install the PoE module then connect the Ethernet cable. Do not connect the USB cable.</p>
<p>After a brief handshake with the Ethernet switch the board should power up and function just like when it was powered using the USB connection to the computer. Just remember never to connect the Feather M0 to a computer using the USB cable while the PoE module is installed.</p>
<h3>Add Art-Net Receive</h3>
<p>This functionality is left as an exercise to the reader. Since this project has both Ethernet and DMX, it would be possible to re-purpose the project as an Art-Net to DMX converter. In my proposed implementation, the board would send its own internally generated DMX data and packets until it received an Art-Net packet. Each time an Art-Net packet was received, it would output the levels in the Art-Net packet over DMX. After a timeout of around 30 to 60 seconds, the controller would revert back to sending its own DMX data and packets.</p>
<h3>Custom Board and Enclosure Design</h3>
<div id="attachment_2363" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/poe-dmx-controller-v1b-v6-2.png"><img class="size-large wp-image-2363" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/poe-dmx-controller-v1b-v6-2-1024x819.png" alt="Render of the board design which integrates all three boards ." width="640" height="512" /></a><p class="wp-caption-text">Render of the board design which integrates the functionality of all three boards used in this project.</p></div>
<p>My personal next step for this project is to build a board that encompasses all the functionality of the three board stack and make it small enough to fit in a Hammond Manufacturing 1455C801 50 mm x 80 mm extruded aluminum enclosure. The render above shows an almost final version of the proposed circuit board. The renders below show the finished enclosure with the board mounted inside.</p>
<div id="attachment_2364" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/1.png"><img class="size-large wp-image-2364" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/1-1024x819.png" alt="Board mounted inside Hammond Manufacturing 1455C801 extruded aluminum enclosure." width="640" height="512" /></a><p class="wp-caption-text">Board mounted inside Hammond Manufacturing 1455C801 extruded aluminum enclosure.</p></div>
<div id="attachment_2365" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/2.png"><img class="size-large wp-image-2365" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/2-1024x819.png" alt="Board mounted inside Hammond Manufacturing 1455C801 extruded aluminum enclosure." width="640" height="512" /></a><p class="wp-caption-text">Board mounted inside Hammond Manufacturing 1455C801 extruded aluminum enclosure.</p></div>
<h2>Questions or Comments</h2>
<p>If you have any questions or comments about this project, I can be reached on <a href="https://twitter.com/bikerglen">Twitter</a>. In the meantime, stay tuned for updates on the integrated version of this project.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/dmx-featherwing-light-controller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PoE-Powered RGB LED Floodlight</title>
		<link>https://bikerglen.com/blog/poe-powered-led-floodlight/</link>
		<comments>https://bikerglen.com/blog/poe-powered-led-floodlight/#comments</comments>
		<pubDate>Sun, 02 Feb 2020 18:38:05 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[DMX / Art-Net]]></category>
		<category><![CDATA[Ethernet]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>
		<category><![CDATA[Power over Ethernet (PoE)]]></category>
		<category><![CDATA[RGB LED]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=2169</guid>
		<description><![CDATA[This project uses a Silvertel 802.3at Ag5300 PoE+ module with a built-in isolated 24 V DC/DC converter to power  a 10 W ColorKinetics ColorBurst 4 RGB LED floodlight. The Ethernet cable and light plug into a small power / control board and PoE+ powers the floodlight and Art-Net UDP packets control the light.  <a href="https://bikerglen.com/blog/poe-powered-led-floodlight/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_1977" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/IMG_20191217_224903-2000.jpg"><img class="size-large wp-image-1977" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/IMG_20191217_224903-2000-1024x682.jpg" alt="Philip Color Kinetics ColorBurst 4 10 watt RGB LED flood light controlled and powered over the network." width="640" height="426" /></a><p class="wp-caption-text">Philip Color Kinetics ColorBurst 4 10 watt RGB LED flood light controlled and powered over the network.</p></div>
<p>Time for another PoE project! This project uses a Silvertel 802.3at Ag5300 PoE+ module with a built-in isolated 24 V DC/DC converter to power  a 10 W ColorKinetics ColorBurst 4 RGB LED floodlight. The Ethernet cable and light plug into a small power / control board and PoE+ powers the floodlight and Art-Net UDP packets control the light. If this were a real product, the power / control board would be integrated into the fixture and the Ethernet cable would then plug directly into the back of the light.</p>
<p><span id="more-2169"></span></p>
<h2>The Silvertel Ag5300 PoE+ Module</h2>
<div id="attachment_2229" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/silvertel-module.jpg"><img class="size-large wp-image-2229" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/silvertel-module-1024x683.jpg" alt="Silvertel Ag5324 PoE PD module with integrated isolated 24 V DC/DC converter." width="640" height="427" /></a><p class="wp-caption-text">Silvertel Ag5324 PoE PD module with integrated isolated 24 V DC/DC converter.</p></div>
<p>My previous PoE projects <a href="https://bikerglen.com/blog/ethernet-powered-pixels/">here</a> and <a href="https://bikerglen.com/blog/poe-vfd-tube-clock/">here</a> used a discrete Texas Instruments TPS2378 PoE+ classification IC and a Molex Ethernet jack with integrated magnetics and PoE+ classification circuitry. The TI TPS2378 is the lowest cost solution. The downside is it requires quite a other components to operate. The Molex jack is the highest cost solution but requires very few external components to operate.</p>
<div id="attachment_2224" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/three-solutions.png"><img class="size-large wp-image-2224" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/three-solutions-1024x792.png" alt="Three different isolated PoE PD designs. The top left design uses a Molex Ethernet jack with integrated magnetics and PoE PD classification circuitry." width="640" height="495" /></a><p class="wp-caption-text">Three different isolated PoE PD designs. The top left design uses a Molex Ethernet jack with integrated magnetics and PoE PD classification circuitry. The bottom design uses an Ethernet jack, separate magnetics, and a TI PoE PD classification IC. The top right design, which is the design used in this project, uses an Ethernet jack, separate magnetics, and a Silvertel PoE module. The Silvertel module lies somewhere in the middle in terms of complexity. In the two more complicated designs, the transformer and Bob Smith termination network could be replaced with an Ethernet jack with integrated magnetics.</p></div>
<p>The Silvertel module sits somewhere in the middle of these other two solutions. It still requires a jack, magnetics, two bridge rectifiers, and a transient suppressor like the discrete TI solution, but, unlike the TI and Molex solutions, it includes an isolated 12 V or 24 V DC/DC converter. The integrated DC/DC converter can be a big cost savings and help to reduce the overall parts count.</p>
<h2>The Plan</h2>
<p>I have a box of Color Kinetics ColorBurst 4 lights sitting in my basement. These lights run from 24 volts, draw a maximum of 10 watts, and use a funky 24 volt version of the DMX-512 protocol. I tore down a larger <a href="https://bikerglen.com/blog/color-kinetics-colorburst-6-teardown/">ColorBurst 6 fixture a few years ago</a> which is very similar in design and operation to the ColorBurst 4.</p>
<div id="attachment_2232" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/pds-150e-cb4-setup.jpg"><img class="size-large wp-image-2232" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/pds-150e-cb4-setup-1024x682.jpg" alt="A Color Kinetics PDS-150e power data supply next to a single ColorBurst 4 fixture." width="640" height="426" /></a><p class="wp-caption-text">A Color Kinetics PDS-150e power data supply next to a single ColorBurst 4 fixture.</p></div>
<p>These lights are normally powered and controlled using a Color Kinetics power data supply like the PDS-150e shown in the photograph above. The PDS-150e contains a 24 volt, 150 watt DC power supply powered from the AC mains and a microprocessor that can control the lights using a Color Kinetics proprietary Ethernet-based protocol or DMX-512. This power data supply can power and control up to 12 ColorBurst 4 lights.</p>
<div id="attachment_2217" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/01/giant-neopixels.jpg"><img class="size-large wp-image-2217" src="https://bikerglen.com/wp/wp-content/uploads/2020/01/giant-neopixels-1024x576.jpg" alt="With enough of these fixtures in a row, they're almost like giant Neopixels!" width="640" height="360" /></a><p class="wp-caption-text">With enough of these fixtures in a row, they&#8217;re almost like giant Neopixels!</p></div>
<p>For this project, I&#8217;m going to replace the PDS-150e with a small power / control board that can directly power and control a single 10 watt ColorBurst 4 fixture from any 802.3at / PoE+ capable switch and an industry-standard Art-Net controller sitting anywhere on the network. I&#8217;ll use Synthe-FX&#8217;s Luminair 3 software running on an iPad Mini to send Art-Net packets to the board and control the light.</p>
<p>A Silvertel PoE module will handle the 802.3at classification and supply a regulated and isolated 24 volts for powering the fixture. A PIC18F67J60 will handle the data side of the project by accepting Art-Net packets and converting them to a serial DMX-512 stream to control the light. Finally, the project will use a line driver to step up the inverted 3.3 volt DMX-512 serial bitstream to a 24 volt version that is compatible with the fixture.</p>
<h2>The Schematic</h2>
<div id="attachment_2220" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/giant-pixpoe-schematic-page-1.png"><img class="size-large wp-image-2220" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/giant-pixpoe-schematic-page-1-1024x681.png" alt="Schematic page one." width="640" height="426" /></a><p class="wp-caption-text">Schematic page one.</p></div>
<p>Page one of the schematic is shown above. It&#8217;s basically the same as page one of the schematic for the Ethernet-powered pixels project except the Texas Instrument PoE classification IC and the Cui 5 volt DC/DC converter have been replaced by the Silvertel Ag5324 PoE module.</p>
<div id="attachment_2221" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/giant-pixpoe-schematic-page-2.png"><img class="size-large wp-image-2221" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/giant-pixpoe-schematic-page-2-1024x681.png" alt="Schematic page two." width="640" height="426" /></a><p class="wp-caption-text">Schematic page two.</p></div>
<p>Page two of the schematic is shown above. It&#8217;s basically the same as page two of the schematic for the Ethernet-powered pixels project except the WS2812 5 volt level shifter and ESD protection circuitry has been removed. In its place is a circuit reverse engineered from a Color Kinetics PDS-60 24 volt power supply to drive the 24 volt inverted DMX protocol to the ColorBurst 4 fixture from the microcontrollers&#8217; 3.3 volt output.</p>
<p>If you have questions about the parts used on this project, I highly recommend reviewing the <a href="https://bikerglen.com/blog/ethernet-powered-pixels/">Ethernet-powered pixels project</a>. It goes in-depth on the selection of parts used for that project, most of which are also used on this project.</p>
<h2>The Board Layout</h2>
<div id="attachment_2222" style="width: 949px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2020/02/giant-pixpoe-board-layout.png"><img class="size-full wp-image-2222" src="https://bikerglen.com/wp/wp-content/uploads/2020/02/giant-pixpoe-board-layout.png" alt="Finished board layout." width="939" height="562" /></a><p class="wp-caption-text">Finished board layout.</p></div>
<p>After finishing the schematic, I designed the circuit board. I attempted to place the components a bit closer together on this project versus the Ethernet-powered pixels project.</p>
<p>A primary concern while designing this board was to maintain at least 50 to 60 mils separation between the PoE power circuitry and the microcontroller circuitry. I don&#8217;t have the equipment to test whether this board layout successfully passes the 802.3 isolation requirements but with this separation, it at least stands a chance.</p>
<p>I ordered the boards from OSH Park and put together a bill-of-materials with their corresponding Digi-Key part numbers. Once I received notification that the boards had shipped from OSH Park, I ordered the parts from Digi-Key. This way I&#8217;d get the boards and the parts around the same time.</p>
<h2>Power Supply Bring Up</h2>
<div id="attachment_1971" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/more-poe-adventures.jpg"><img class="size-large wp-image-1971" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/more-poe-adventures-1024x575.jpg" alt="blah, blah, blah" width="640" height="359" /></a><p class="wp-caption-text">The PoE-powered RGB LED floodlight controller with the PoE and power supply circuitry populated.</p></div>
<p>After receiving the boards back from OSH Park, I brought up the PoE and power supply circuitry first. Since I learned on the Ethernet-powered pixels project not to put an LED across the rectified power from the Ethernet transformer, this board came up immediately. I used a DMM to verify the output of the Silvertel PoE module was 24 volts and I verified the board showed up as an unknown 802.3at / PoE+ device on my switch port.</p>
<h2>Microcontroller Bring Up</h2>
<div id="attachment_1960" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/GiantPixPoE-Top-2000.jpg"><img class="wp-image-1960 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/GiantPixPoE-Top-2000-1024x682.jpg" alt="circuit board with ethernet jack, magnetics, power supply, micrcontroller, and line driver stuffed." width="640" height="426" /></a><p class="wp-caption-text">The fully populated PoE-powered RGB LED floodlight controller board.</p></div>
<p>My parts order for the rest of the board arrived a bit late but I had enough parts on hand to populate the 3.3 volt power supply and the PIC18F67J60 microcontroller. I did not have the parts for the Ethernet signals or the 25 MHz oscillator so the Ethernet bring up would have to wait for later.</p>
<p>I created a new XC8 project in MPLAB X IDE that used the internal oscillator on the PIC to blink the four LEDs slowly in succession. This was enough software to verify the microcontroller could be programmed and debugged. I downloaded the software and the lights blinked exactly as expected.</p>
<p>Once the rest of the parts arrived, I populated the remainder of the board including the Ethernet circuitry, the SiTime MEMS 25 MHz oscillator, the EUI-48 serial EEPROM, and the 3.3 volt inverted serial to 24 volt inverted serial driver.</p>
<p>To verify the Ethernet circuitry worked, I downloaded the build of the software for the Ethernet-powered pixels project to this board. This build could not control the ColorBurst 4 LED floodlight but it would attempt to get an IP address using DHCP from my router which was enough functionality to verify the Ethernet circuitry functioned correctly.</p>
<p>When I plugged the board into my switch, the board powered up and received an IP address from my router. I noted that a new MAC address had appeared on my network and this MAC address was the same MAC address as the one programmed in the EUI-48. The Ethernet circuitry works!</p>
<p>The next step was to clone the software for the Ethernet-powered pixels project to a new project and modify the Art-Net UDP receive routine to send the first three channels of level data to the ColorBurst 4 fixture as DMX data. I wrote the quick DMX send routine shown below then downloaded the code to the board.</p>
<pre>        INTERRUPT_GlobalInterruptDisable();
        INTERRUPT_PeripheralInterruptDisable();
        
        // send break
        TRISCbits.TRISC6 = 0;
        LATCbits.LATC6 = 0;
        RCSTA1bits.SPEN = 0;

        __delay_us (88);

        // send mark after break
        RCSTA1bits.SPEN = 1;

        __delay_us (8);
        
        // send 0x00 followed by three art-net data bytes
        EUSART1_Write (0x00);
        EUSART1_Write (giantR);
        EUSART1_Write (giantG);
        EUSART1_Write (giantB);
        
        INTERRUPT_GlobalInterruptEnable();
        INTERRUPT_PeripheralInterruptEnable();</pre>
<p>I used an oscilloscope to verify the serial data ranged from 0 to 24 volts and the baud rate was correct. After that, I connected the ColorBurst 4 fixture to the board. The light powered up but did not respond to the levels set on my Art-Net controller. Using the scope I could see DMX packets being sent to the light with transmitted levels corresponding to the levels set by the Art-Net controller but the light did not respond.</p>
<p>Finally, I looked at the DMX-512 spec again. It requires two stop bits. The PIC18F67J60 doesn&#8217;t support two stop bits but it does support a 9-bit data transmission mode. I enabled the mode and set the 9th bit to always be a &#8216;1&#8217;. That generates a signal identical to a signal with two stop bits.</p>
<pre>        // enable 9 bit mode
        TXSTA1bits.TX9 = 1;
        TXSTA1bits.TX9D = 1;</pre>
<p>I downloaded the code to the board again and this time, success! The ColorBurst 4 responded as I varied the level sliders on my Art-Net controller software.</p>
<h2>Putting It All Together</h2>
<div id="attachment_1974" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/IMG_20191217_224700-2000.jpg"><img class="size-large wp-image-1974" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/IMG_20191217_224700-2000-1024x682.jpg" alt="blah, blah, blah" width="640" height="426" /></a><p class="wp-caption-text">The RGB LED floodlight being powered and controlled over the network. I&#8217;m using Luminair 3 by Synthe-FX on an iPad mini to send the Art-Net packets and control the LED fixture.</p></div>
<p>This project was successful. I could use software running on my iPad Mini to control the brightness and color of the light emitted by the ColorBurst 4 LED fixture and the fixture was powered using 802.3at PoE+ from my Ethernet switch.</p>
<p>A possible future iteration of this project might be to build my own RGB LED fixture, integrate the PoE+ power supply and Art-Net control circuitry in to the fixture, and design an enclosure to hold and cool everything. The enclosure would need to have a means for aiming it and securing it in position, a transparent or frosted window for the light, and an Ethernet jack on the back or bottom for powering and controlling the light.</p>
<div id="attachment_332" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_0824_2560.jpg"><img class="size-large wp-image-332" src="https://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_0824_2560-1024x683.jpg" alt="Color Kinetics C200 RGB LED track fixtures hacked to be usable without the track." width="640" height="427" /></a><p class="wp-caption-text">Color Kinetics C200 RGB LED track fixtures hacked to be usable without the track.</p></div>
<p>Another thought would be to replace the control board in one of the older style Color Kinetics C-200 fixtures shown above with a board of my own design that includes PoE and controller functionality then cut a new rear panel for the light with just an opening for an Ethernet jack on it. This could be tricky depending on the amount of space available in the fixture.</p>
<h2>Design Files</h2>
<p>The design files for this project are on <a href="https://github.com/bikerglen/poe-ckcb4-floodlight">Github</a>. You can reach me about any missing files or other questions on Twitter <a href="https://twitter.com/bikerglen">@bikerglen</a>.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/poe-powered-led-floodlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>It&#8217;s an Ethernet-Powered Christmas Tree!</title>
		<link>https://bikerglen.com/blog/ethernet-powered-pixels/</link>
		<comments>https://bikerglen.com/blog/ethernet-powered-pixels/#comments</comments>
		<pubDate>Sun, 29 Dec 2019 20:45:21 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[DMX / Art-Net]]></category>
		<category><![CDATA[Ethernet]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>
		<category><![CDATA[Power over Ethernet (PoE)]]></category>
		<category><![CDATA[RGB LED]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=1979</guid>
		<description><![CDATA[The lighted tree in the video above gets both the power and data for its RGB LED pixels using a single Ethernet cable. Power for the pixels is supplied from an Ethernet switch using the 802.3at PoE+ standard. Data for &#8230; <a href="https://bikerglen.com/blog/ethernet-powered-pixels/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><iframe src="https://www.youtube.com/embed/0Oo144LTxu4" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe><br />
The lighted tree in the video above gets both the power and data for its RGB LED pixels using a single Ethernet cable. Power for the pixels is supplied from an Ethernet switch using the 802.3at PoE+ standard. Data for the pixels comes from software running on a PC that generates Art-Net packets at 40 Hz. Each Art-Net packet contains the RGB levels for all the pixels on the tree. Let&#8217;s take a closer look at the technical details and how this tree came into existence.</p>
<p><span id="more-1979"></span></p>
<h2>Motivation</h2>
<div id="attachment_1997" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/goalz.jpg"><img class="size-large wp-image-1997" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/goalz-1024x682.jpg" alt="Philips Color Kinetics iColor Flex LMX setup with the AC power data supply, proprietary leader cable, and 50 pixels." width="640" height="426" /></a><p class="wp-caption-text">Philips Color Kinetics iColor Flex LMX setup with the AC power data supply, proprietary leader cable, and 50 pixels.</p></div>
<p>A few weeks ago, I wrote a post where I <a href="https://bikerglen.com/blog/reverse-engineering-the-icolor-flex-protocol/">reversed engineered</a> some Philips Color Kinetics iColor Flex RGB LED string lights. These lights require an AC power data supply that supplies 24 volts to power the pixels and transforms DMX or UDP packets of pixel data into the protocol used by the pixels. In addition to the power supply, the pixels require a proprietary leader cable to connect them to the power supply.</p>
<p>In a typical setup, you have to run AC mains power and Ethernet data to the power supply then run the leader cable to the pixels. To avoid having a large stack of power data supplies in larger setups, Color Kinetics makes a rack mount power supply that can power up to eight strings of lights. This rack mount power supply still requires a leader cable for each string of lights.</p>
<p>I&#8217;ve been wanting to build an 802.3af/at/bt Power over Ethernet design for a few years now and have always come up short on ideas and then it hit me, what if the Ethernet cable could connect closer to the pixels in the photo above? With a small box of electronics between the Ethernet cable and the connector on the end of the pixels, the pixels could receive both power and data from the Ethernet switch. No more AC mains wiring and no more proprietary leader cables.</p>
<h2>802.3af/at/bt Power over Ethernet</h2>
<p>Many Power over Ethernet schemes involve connecting the spare pairs in an Ethernet cable to an always-on 12 VDC or 24 VDC power supply. At the other end of the Ethernet wiring, the spare pairs are connected to a DC/DC converter that generates the voltages required by the device. This is fraught with problems and is not real Power over Ethernet!</p>
<p>802.3af/at/bt Power over Ethernet only supplies power to a device once a device detection and classification process completes. This process is a hardware handshake between the power sourcing equipment (PSE) and the powered device (PD). During the handshake, the PSE communicates its power sourcing capabilities to the PD and the PD communicates its power requirements to the PSE. If the PSE is capable of supplying the amount of power required by the PD, power is connected to the PD.</p>
<p>While the PD is powered, the PSE continuously monitors the current draw of the PD. If the current draw drops too low for too long, the PSE assumes the PD was disconnected and shuts down power to the PD. This process ensures power is only supplied to standards-compliant devices and only while those devices are connected.</p>
<p>In addition to the hardware handshake, Power over Ethernet can use Link Layer Discovery Protocol (LLDP) to communicate a PD&#8217;s power requirement to the PSE with greater resolution than permitted by the hardware handshake. For example, a device could complete the handshake indicating it is an 802.3at PoE+ compliant device but use LLDP to tell the connected switch it only requires 20 watts instead of the maximum 25.5 watts. This can potentially reduce the number of Ethernet switches required in large installations if the switches do not need to assume every device will always consume its maximum power.</p>
<table class="wikitable">
<tbody>
<tr>
<th>Property</th>
<th>802.3af <span class="nowrap">(802.3at Type 1)</span> &#8220;PoE&#8221;</th>
<th><span class="nowrap">802.3at Type 2</span> &#8220;PoE+&#8221;</th>
<th><span class="nowrap">802.3bt Type 3</span> &#8220;4PPoE&#8221;</th>
<th><span class="nowrap">802.3bt Type 4</span></th>
</tr>
<tr>
<td>Power available at PD<sup id="cite_ref-25" class="reference"><a href="https://en.wikipedia.org/wiki/Power_over_Ethernet#cite_note-25">[note 1]</a></sup></td>
<td><span class="nowrap">12.95 W</span></td>
<td><span class="nowrap">25.50 W</span></td>
<td><span class="nowrap">51 W</span></td>
<td><span class="nowrap">71 W</span></td>
</tr>
<tr>
<td>Maximum power delivered by PSE</td>
<td><span class="nowrap">15.40 W</span></td>
<td><span class="nowrap">30.0 W</span></td>
<td><span class="nowrap">60 W</span></td>
<td><span class="nowrap">100 W</span></td>
</tr>
<tr>
<td>Voltage range (at PSE)</td>
<td><span class="nowrap">44.0–57.0 V</span></td>
<td><span class="nowrap">50.0–57.0 V</span></td>
<td><span class="nowrap">50.0–57.0 V</span></td>
<td><span class="nowrap">52.0–57.0 V</span></td>
</tr>
<tr>
<td>Voltage range (at PD)</td>
<td><span class="nowrap">37.0–57.0 V</span></td>
<td><span class="nowrap">42.5–57.0 V</span></td>
<td><span class="nowrap">42.5–57.0 V</span></td>
<td><span class="nowrap">41.1–57.0 V</span></td>
</tr>
<tr>
<td>Maximum current I<sub>max</sub></td>
<td><span class="nowrap">350 mA</span></td>
<td><span class="nowrap">600 mA</span></td>
<td><span class="nowrap">600 mA</span> per pair</td>
<td><span class="nowrap">960 mA</span> per pair</td>
</tr>
</tbody>
</table>
<p>The table above is copied from the <a href="https://en.wikipedia.org/wiki/Power_over_Ethernet">Wikipedia page</a> on Power over Ethernet. It shows the 4 main types of Power over Ethernet and the amount of power each is capable of delivering to a PD. Also shown are the voltages a PD will see at its Ethernet jack based on the voltage supplied by the PSE, the maximum current draw of the PD, and the maximum resistance in 100 meters of Cat 3 (Type 1) or Cat 5 (Type 2 to 4) Ethernet cabling.</p>
<p>Type 1 and Type 2 PoE can use either the 10/100 Mbps data pairs or the 10/100 Mbps spare pairs for supplying power. It&#8217;s up to the switch to decide which set of pairs so the powered device must support using either set. Type 3 and Type 4 PoE use all four pairs for supplying power. All four PoE types work with all speeds of Ethernet, 10/100 Mbps as well as 1/2.5/5/10 Gbps.</p>
<p>For more information on Power over Ethernet, I highly recommend the Power over Ethernet <a href="https://en.wikipedia.org/wiki/Power_over_Ethernet">Wikipedia page</a>, section 7.4.1 of the Texas Instruments TPS2378 IEEE 802.3at PoE+ Interface <a href="http://www.ti.com/lit/ds/symlink/tps2378.pdf">data sheet</a> (PDF), and the Silicon Labs Si3404/06x <a href="https://www.silabs.com/documents/public/application-notes/an1130-si3404-06x-dg.pdf">PoE-PD Controller Design Guide</a> (PDF).</p>
<h2>Feasibility and Scaling Back Ambitions</h2>
<div id="attachment_2002" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/box1-v4.png"><img class="size-large wp-image-2002" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/box1-v4-1024x819.png" alt="Artist's depiction of two Ethernet to iColor Flex PoE power data supplies." width="640" height="512" /></a><p class="wp-caption-text">Artist&#8217;s depiction of two Ethernet to iColor Flex PoE power data supplies.</p></div>
<p>Getting back to my design, I pictured a small box with a waterproof Ethernet connector on one end and an Amphenol LTW waterproof connector for the pixels on the other end like the boxes in the artist&#8217;s rendering above. Inside the box would be 802.3af/at/bt classification circuitry, a power supply capable of delivering 62 watts at 24 volts, a microcontroller with Ethernet, and an FPGA to generate the Chromasic protocol data for the lights.</p>
<p>Referring to the chart of PoE capabilities in the previous section on standards-compliant Power over Ethernet, supplying 62 watts to the iColor Flex lights would require using 802.3bt Type 4 PoE and having an efficiency exceeding 87%. I felt this was certainly technically feasible but a bit too ambitious for my first PoE design. I also do not have an 802.3bt capable Ethernet switch yet. Time to scale back my ambitions a bit.</p>
<p>The next thought was to scale back to using iColor Flex MX pixels that require 22.5 watts at 7.5 volts. This could be powered using 802.3at PoE which is capable of delivering 25.5 watts to the powered device. This would require being over 88% efficient and I&#8217;d have to design a 7.5 volt wide input range buck converter too. I still felt this was a bit too ambitious.</p>
<div id="attachment_2006" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixels.jpg"><img class="size-large wp-image-2006" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixels-1024x666.jpg" alt="A string of 50 RGB pixels on the left and a strip of 60 RGB pixles on the right." width="640" height="416" /></a><p class="wp-caption-text">A string of 50 RGB pixels on the left and a strip of 60 RGB pixels on the right.</p></div>
<p>The next step down in power consumption and complexity were the ubiquitous WS2812 RGB LEDs. Adafruit sells these in <a href="https://www.adafruit.com/product/1138?length=1">one meter strips of 60 RGB LEDs</a> and Light-O-Rama sells these as <a href="http://store.lightorama.com/50sqpi5vbl.html">five meter strings of 50 RGB pixels</a>. Both of these consume 60 mA per bulb at 5 volts which is 0.3 watt per LED. A strip of 60 Neopixels consumes 18 watts maximum. The string of 50 from Light-O-Rama consumes 15 watts maximum.</p>
<p>15 and 18 watts easily falls within the 25.5 watt maximum for <span class="nowrap">802.3at</span> PoE+. In addition, the WS2812 LEDs have significantly relaxed timing requirements compared to the iColor Flex LEDs. This allows the pixels to be controlled in software and eliminates the requirement for an FPGA to drive the pixels. Finally, the pixels run from 5 VDC. Since 5 VDC isolated switching DC/DC converter modules are common, I will not need to design a custom power supply as part of the project.</p>
<p>Over the course of a few hours, I talked myself down from building an 802.3bt 62 watt PD with an FPGA in a waterproof enclosure to building a much simpler proof-of-concept that uses 802.3at PoE+ for power and controls up to 60 WS2812 pixels in software. WS2812 pixels will be a great starting point for a project that can both power and control a string or strip of lights over Ethernet.</p>
<h2>Electrical Isolation</h2>
<p>The 802.3af/at/bt PoE standards require electrical isolation between the power interface and all user-accessible conductors including the frame ground. In a large commercial building, there could be 100 meters of Ethernet cable between the switch and the powered device with the result that the grounds at each end of the Ethernet cable have a large voltage difference between them. Without isolation, current would flow over the Ethernet cable which is both a safety issue and an electrical noise issue.</p>
<p>A lot of designs like PoE-enabled network cameras, Wi-Fi access points with internal antennas, and ceiling troffer LED lights have no user accessible conductors and therefore can use a non-isolated design. In this case, the enclosure and the lack of user-accessible conductors acts as the isolation required by the standard.</p>
<p>Other designs like Wi-Fi access points with external antenna connectors or building access controls with connections for locks and card readers require an isolated design. My design is going to have a connector for the WS2812 pixels so technically it requires an isolated design.</p>
<p>For both isolated and non-isolated designs, the 802.3 Ethernet standards require a transformer between the Ethernet jack and the Ethernet PHY. For isolated PoE designs, isolation is also required in the board layout, in the feedback loop in the power supply circuit, and in any status indicators between the PoE classification circuitry and the microcontroller. Isolated designs are therefore more complicated and more expensive than non-isolated designs.</p>
<p>Isolated designs do have an advantage during development and testing though. Programmers, debuggers, logic analyzers, oscilloscopes, and other test equipment can be connected to the isolated portions of the design without risk to the user or equipment. With a non-isolated design (or to debug the power interface side of an isolated design), you might need a battery-powered laptop to connect the debugger to the microcontroller, high-voltage differential probes for an oscilloscope, or a handheld oscilloscope with isolated input channels.</p>
<h2>Design Requirements</h2>
<p>Taking into account the selected pixels and the need for an isolated PoE design, here&#8217;s the basic list of requirements for my design:</p>
<ul>
<li>Use standards-compliant 802.3at PoE+ classification circuitry.</li>
<li>Use less than 25.5 watts total power to stay within the 802.3at PoE+ power envelope.</li>
<li>Use an isolated power supply design capable of supplying 20 watts at 5 volts. 15 to 18 watts will be available for the WS2812 pixels. Two watts will be available for the support circuitry including the microcontroller.</li>
<li>Use transformers, optocouplers, and appropriate trace spacing to maintain isolation between the power interface circuitry and the remainder of the device.</li>
<li>Use an Ethernet-capable microcontroller to reduce parts count and design complexity.</li>
<li>Use easy to hand-solder SMD packages with no inaccessible pins, leads, or pads. One of these days, I&#8217;ll have to learn to solder/reflow DFN/QFN packages with exposed thermal pads, but I&#8217;m not there yet.</li>
</ul>
<h2>Selecting the PoE Controller</h2>
<div id="attachment_2057" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-pd-devices.jpg"><img class="size-large wp-image-2057" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-pd-devices-1024x684.jpg" alt="A bunch of different PoE+ PD components including two Molex PD jacks, two TI TPS2378 ICs, a TI TPS2378 evaluation board, and a Silvertel PoE+ PD 24 VDC module." width="640" height="428" /></a><p class="wp-caption-text">A bunch of different PoE+ PD components including two Molex PD jacks, two TI TPS2378 ICs, a TI TPS2378 evaluation board, and a Silvertel PoE+ PD 24 VDC module.</p></div>
<p>The 802.3af PoE standard was ratified in 2003 and the 802.3at PoE+ standard was ratified in 2009. The relative age of the standards means there&#8217;s tons of great PoE/PoE+ silicon and modules on the market.</p>
<p><a href="http://www.ti.com/power-management/power-over-ethernet-poe/overview.html">Texas Instruments</a>, <a href="https://www.analog.com/en/products/monitor-control-protection/power-over-ethernet-poe-interface-controllers/poe-powered-device.html#">Analog Devices</a>, <a href="https://www.microsemi.com/product-directory/power-over-ethernet/847-poe-pd-front-end-w-pwm-controller">Microchip Technology</a>, and <a href="https://www.silabs.com/power-over-ethernet/powered-devices">Silicon Labs</a> all make PoE PD controller silicon. All these chips handle classification. Many of these chips include integrated transistor switches to control power to the user&#8217;s circuitry. Some of these chips even include switch mode power supply controllers to step down the incoming voltage to the user&#8217;s required voltage.</p>
<p>Silvertel makes complete <a href="https://silvertel.com/poe-power-over-ethernet-html/">PoE modules</a> capable of delivering from 13W to 99W to a PD. These modules handle classification, isolation, and include a DC/DC converter to step the input voltage down to a more usable 12 or 24 volts. Molex even makes <a href="https://www.molex.com/molex/products/datasheet.jsp;jsessionid=05oiS64RT1IkXnHXuryno-eThRG8f2tOemOF-xbW.molex0?part=active/0857913020_MODULAR_JACKS_PLUG.xml">Ethernet jacks</a> with integrated magnetics and PoE/PoE+ classification circuitry. These jacks use the Microchip / Microsemi <span class=""><a href="https://www.microsemi.com/product-directory/poe-pd-front-end-w-pwm-controller/4783-pd70200">PD70200</a></span> controller.</p>
<div id="attachment_2024" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-pd-controller-circuit.png"><img class="size-large wp-image-2024" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-pd-controller-circuit-1024x227.png" alt="802.3at PoE+ powered device controller and classification circuit." width="640" height="142" /></a><p class="wp-caption-text">802.3at PoE+ powered device controller and classification circuit.</p></div>
<p>After reading datasheets for what felt like weeks, I settled on the TI TPS2378 802.3at PoE+ PD controller. It performs PoE+ detection and classification, includes an internal pass MOSFET with inrush current limiting, comes in a relatively easy to solder SOIC-8 package with an exposed thermal pad, and requires minimum external components.</p>
<p>The schematic above shows the basic circuit. Bridge rectifiers BR1 and BR2 rectify the voltage from the Ethernet jack since the input voltage is of unknown polarity. C1, L1, and L2 are an EMI/EMC filter. Zener diode D1 provides transient protection. C2 provides the minimum load capacitance required by the PoE specifications. R1 and R2 set the detection current and classification current respectively.</p>
<div id="attachment_2040" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/tps2378-startup.png"><img class="wp-image-2040 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/tps2378-startup-1024x775.png" alt="tps2378-startup" width="640" height="484" /></a><p class="wp-caption-text">TI TPS2378 startup sequence from the datasheet.</p></div>
<p>Figure 19 from section 7.4.3 of the TPS2378 datasheet (reproduced above) shows the detection, classification, inrush current limiting, and startup sequence. When the input voltage is between 1.4 and 10.9 volts, the TPS2378 generates a detection signature. Once the PSE sees the detection signature, the PSE supplies a voltage between 10.9 and 22 volts. This is the classification phase and the TPS2378 generates a classification current between 36 and 44 mA to indicate it is a 802.3at PoE+ Type 2 / Class 4 device. For 802.3at this step is performed twice with a mandatory return to the detection current between each classification pulse.</p>
<p>Once classification is complete, the PSE supplies full power to the PD and the TPS2378 turns on the internal pass MOSFET but in an inrush current limiting mode. This limits the input current to about 140 mA and allows the bulk capacitors in the downstream power supply circuit to charge. Once the current through the pass MOSFET drops below 125 mA, inrush current limiting is turned off, the converter disable pin is de-asserted, and the user&#8217;s circuitry can run.</p>
<p>If 802.3at/PoE+ classification was successful, the T2P pin will be asserted and the user&#8217;s circuitry can run at full power. If 802.3at/PoE+ classification was not successful, the T2P pin will be de-asserted and the user&#8217;s circuitry must stay within the 802.3af PoE power envelope.</p>
<h2>Selecting the Power Supplies</h2>
<div id="attachment_2026" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-power-supply-circuits.png"><img class="size-large wp-image-2026" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-power-supply-circuits-1024x568.png" alt="Isolated wide-input range to 5 VDC switching power supply module (top) and 3.3 VDC non-isolated switching power supply module (bottom)." width="640" height="355" /></a><p class="wp-caption-text">Isolated wide-input range to 5 VDC switching power supply module (top) and 3.3 VDC non-isolated switching power supply module (bottom).</p></div>
<p>The next step was to select an isolated DC/DC converter that has an input range of 37 to 57 VDC, a 5 VDC output, and a 20 watt power rating. The CUI PDQE20-Q48-S5-D meets these specifications. It has a nominal input voltage of 48 volts but works with a range from 18 to 75 volts. It is rated for 20 watts, is isolated, and has an efficiency of 90%. It comes in a 1&#8243; by 1&#8243; form factor module. The converter requires a 100 uF input capacitor and a 100 uF output capacitor for stable operation. It also has an active-low disable input that can be connected directly to the TPS2378&#8217;s CDB pin to keep the converter disabled until the bulk input capacitor is charged.</p>
<p>The microcontroller requires 3.3 VDC at about 250 mA. to operate. This is supplied by a CUI V7803-500 non-isolated switching regulator. It has an input range from 4.75 to 28 VDC and is connected to the output of the 5 VDC isolated converter. It requires a few capacitors to operate as well. I included a few LEDs to indicate the 5 VDC and 3.3 VDC power supplies are operational.</p>
<h2>Selecting the Ethernet Microcontroller</h2>
<div id="attachment_2028" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/minimal-ethernet-circuit.png"><img class="size-large wp-image-2028" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/minimal-ethernet-circuit-1024x771.png" alt="PIC18F67J60 minimal Ethernet circuit." width="640" height="482" /></a><p class="wp-caption-text">PIC18F67J60 minimal Ethernet circuit. Pay particular attention to Note 4 for Power over Ethernet applications.</p></div>
<p>The next step was to select a microcontroller to receive Art-Net UDP packets of pixel data and output the pixel data to the WS2812 LEDs. Most Ethernet microcontrollers only include Ethernet MAC functionality and require an external Ethernet PHY. The Microchip PIC18F67J60 microcontroller includes both an internal Ethernet MAC and PHY. This reduces the parts count and board area needed by the design.</p>
<p>The basic schematic from the data sheet is shown in the schematic above. I added some ESD protection circuitry as shown in the Microchip Ethernet of Everything <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/40001930A.pdf">reference design</a> (PDF). The PIC18F67J60 is limited to 10 Mbps Ethernet but sixty 24-bit WS2812 pixels updated at 40 Hz only require 57,600 bits per second of data to operate.</p>
<h2>Other Circuitry of Note</h2>
<p>Here&#8217;s a brief examination of some of the other circuitry in the design.</p>
<h3>Optically Isolated AT Classification Indicator</h3>
<div id="attachment_2044" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-t2p-isolation.png"><img class="size-large wp-image-2044" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-t2p-isolation-1024x401.png" alt="T2P flag isolation circuitry." width="640" height="251" /></a><p class="wp-caption-text">T2P flag isolation circuitry.</p></div>
<p>The TPS2378 asserts T2P low if 802.3at/PoE+ classification is successful. An optoisolator is used to isolate this signal and make it available to the microcontroller. When ISO_T2P is asserted low indicating the PD can draw up to 25.5 watts of power, the microcontroller can enable the WS2812 pixels.</p>
<h3>3.3 VDC to 5 VDC Level Translator for WS2812 LEDs</h3>
<div id="attachment_2045" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-ws2812-driver.png"><img class="size-large wp-image-2045" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-ws2812-driver-1024x485.png" alt="The 3.3 VDC to 5 VDC level translator and transient protection circuitry used to drive the WS2812 LEDs." width="640" height="303" /></a><p class="wp-caption-text">The 3.3 VDC to 5 VDC level translator and transient protection circuitry used to drive the WS2812 LEDs.</p></div>
<p>The microcontroller has 3.3 VDC outputs but the WS2812 LEDs have inputs referenced to 5 VDC. These generally work ok from 3.3 VDC but I added a Texas Instruments Little Logic single gate buffer to translate the 3.3 VDC output from the microcontroller up to 5 VDC. The resistor and diode array protect the microcontroller and buffer from transients on the WS2812 data line.</p>
<h3>SiTime MEMS Oscillator</h3>
<p>I&#8217;m using a <a href="https://www.sitime.com/products/automotive-high-temp-oscillators/sit2024">SiTime MEMS oscillator</a> to generate the 25 MHz clock for the microcontroller. This oscillator comes in a small but still easy-to-solder SOT23-5 package. Digi-Key programs them to the purchaser&#8217;s needed frequency on demand or you can buy a stock of blank parts and use the SiTime programmer to program them as needed.</p>
<h3>Globally Unique MAC Address</h3>
<p>Purchasing a block of MAC addresses for maker projects is not feasible. Instead I&#8217;m using a <a href="https://www.microchip.com/design-centers/memory/serial-eeprom/mac-address-and-unique-id-eeproms">Microchip EUI-48 serial EEPROM</a> that contains a pre-provisioned, globally-unique, and write-protected MAC address. The alternative for devices that will not be used outside your local network is to use a locally administered address from one of the <a href="https://serverfault.com/questions/40712/what-range-of-mac-addresses-can-i-safely-use-for-my-virtual-machines">locally administered address pools</a>.</p>
<h2>Finished Schematic</h2>
<p>Here is the finished schematic. It&#8217;s two pages. Page 1:</p>
<div id="attachment_2048" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-schematic-page-1.png"><img class="size-large wp-image-2048" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-schematic-page-1-1024x682.png" alt="Finished schematic, page one." width="640" height="426" /></a><p class="wp-caption-text">Finished schematic, page one.</p></div>
<p>Page 2:</p>
<div id="attachment_2049" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-schematic-page-2.png"><img class="size-large wp-image-2049" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-schematic-page-2-1024x682.png" alt="Finished schematic, page two." width="640" height="426" /></a><p class="wp-caption-text">Finished schematic, page two.</p></div>
<h2>Finished Board</h2>
<div id="attachment_2050" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-board.png"><img class="size-large wp-image-2050" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-board-1024x607.png" alt="The finished board." width="640" height="379" /></a><p class="wp-caption-text">The finished board.</p></div>
<p>The image above shows the finished board. The thick dashed line shows the 56 mil space required to isolate the power interface circuitry on the left of the line from the user circuitry on the right of the line. The only components crossing the line are a filter capacitor rated for 2000 volts, the Ethernet magnetics, the T2P optocoupler, and the isolated DC/DC converter. All these parts provide DC isolation between the two halves of the board.</p>
<p>The next step was to upload the boards to <a href="https://oshpark.com/">OSH Park</a>, check the renders, and order the boards.</p>
<div id="attachment_2052" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-top.png"><img class="size-large wp-image-2052" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-top-1024x569.png" alt="OSH Park render of the top of the board." width="640" height="356" /></a><p class="wp-caption-text">OSH Park render of the top of the board.</p></div>
<p>The image above is an OSH Park render of the top of the board.</p>
<div id="attachment_2053" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-bottom.png"><img class="size-large wp-image-2053" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/pixpoe-bottom-1024x569.png" alt="OSH Park render of the bottom of the board." width="640" height="356" /></a><p class="wp-caption-text">OSH Park render of the bottom of the board.</p></div>
<p>The image above is an OSH Park render of the bottom of the board.</p>
<h2>Future Board Revisions</h2>
<p>While these boards were being manufactured, a helpful Twitter user pointed out some revisions I could make to improve the EMI/EMC performance and some other minor changes to the board. Here&#8217;s the list of changes for future board versions:</p>
<ul>
<li>Change PIC18 ground traces to vias to 9 mil width.</li>
<li>Change all other ground traces to vias to 20 mil width.</li>
<li>Change the 3.3 V bridges between 3.3 V fills to 20 mil width.</li>
<li>Change PIC18 pin 10 (VDDCORE) and 9 (GND) traces to 9 mil width.</li>
<li>Move PIC18 pin 9 (GND) via to far side of capacitor. Make the trace 20 mil wide.</li>
<li>Change TD_CT / filtered 3.3 V traces to 8 mil width between caps and PIC18.</li>
<li>Changed 5V trace to a pour / fill.</li>
<li>Increase separation of VPPIN to RTN to 25 mil per section 7.3.9 of TPS2378 data sheet.</li>
<li>More vias on thermal pad.</li>
<li>Use schottky diodes instead of bridge rectifiers for greater efficiency.</li>
<li>Investigate routing 3.3 V power on top layer and adding a ground fill / pour on the top layer stitched to the bottom layer.</li>
<li>Use jack with integrated magnetics or integrated magnetics and PD circuitry.</li>
<li>Improve isolation / spacing between power interface circuitry and frame ground.</li>
</ul>
<h2>Software Development</h2>
<div id="attachment_2055" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/olimex-pic-web.jpg"><img class="size-large wp-image-2055" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/olimex-pic-web-1024x684.jpg" alt="The Olimex PIC-WEB board I used for software development while waiting for my boards." width="640" height="428" /></a><p class="wp-caption-text">The Olimex PIC-WEB board I used for software development while waiting for my boards.</p></div>
<p>While the boards were being manufactured, I started software development using an <a href="https://www.olimex.com/Products/PIC/Development/PIC-WEB/">Olimex PIC WEB development board</a>. The Ethernet hardware and software on this board is functionally identical to the Ethernet hardware and software on my board so it was a good platform to use for software development until my boards were available.</p>
<h3>Microchip Code Configurator</h3>
<p>I created a new PIC18F67J60 project in the MPLAB X IDE then used the Microchip Code Configurator (MCC) to generate the basic timer, EUSART, and TCP/IP Ethernet code for the project.</p>
<p>In the system tab, I enabled TMR1 interrupts, assigned the EUSART1 TX1 and RX1 pins, and configured an external 25 MHz clock on the primary OSC pins. In the libraries tab, I added the TCP/IP Lite library and enabled the UDP, DHCP, IPV4, ICMP, and ARP protocols. In the MAC tab, I selected ETHxxJ6x since I&#8217;m using the Ethernet MAC built into the device. I also configured a locally administered MAC address until I had an opportunity to enable the EUI-48 serial EEPROM. I added the TMR1 and EUSART1 peripherals then enabled the TMR1 interrupt to occur every 40 ms and the callback function to be called once per second. The EUSART was configured for 9600 bps and STDIO was redirected to USART. I clicked the generate tab to generate the initial code base.</p>
<p>Once the code was generated, I opened up main.c, removed the comments to enable interrupts, and added a call to Network_Manage () inside the while loop inside the main function. I built the project and downloaded it to the PIC-WEB board. It started running and eventually grabbed an IP address from my DHCP server. At this point I could ping the board but that&#8217;s about it.</p>
<h3>Adding Art-Net UDP Receive</h3>
<p>Next I added code to receive Art-Net packets over the network to the project. I created a udp_rx_artnet.h file with the following code:</p>
<pre>#ifndef _UDP_RX_ARTNET_H
#define _UDP_RX_ARTNET_H

void UdpRxArtNetInit (void);
void UdpRxArtNetRecv (int16_t length);

#endif    //_UDP_DEMO_H</pre>
<p>Then I created a udp_rx_artnet.c file with the following code:</p>
<pre>#include &lt;stdint.h&gt;
#include "udp_rx_artnet.h"
#include "ws2812b.h"
#include "mcc_generated_files/TCPIPLibrary/udpv4.h"
#include "mcc_generated_files/TCPIPLibrary/tcpip_config.h"
#include "mcc_generated_files/pin_manager.h"


void UdpRxArtNetInit (void)
{
    // nothing to do here
}


void UdpRxArtNetRecv (int16_t length)
{
    uint8_t i;
    uint8_t leds;
    uint8_t r, g, b;
    
    if (length &gt;= 18) {
        for (i = 0; i &lt; 18; i++) {
            UDP_Read8 ();
        }
        
        length = length - 18;
        if (length &gt; NUM_CHANS) {
            length = NUM_CHANS;
        }
        leds = length / 3;
        length = 3 * leds;
        
        for (i = 0; i &lt; length; i+=3) {
            r = UDP_Read8 ();
            g = UDP_Read8 ();
            b = UDP_Read8 ();
            ledData[i+0] = gamma8[g];
            ledData[i+1] = gamma8[r];
            ledData[i+2] = gamma8[b];
            
        }
        
        for (; i &lt; 150; i++) {
            ledData[i] = 0;
        }
        
        WS2812b_Write ();
        printf ("+");
        LATEbits.LATE4 = ~LATEbits.LATE4;
    }
}</pre>
<p>It&#8217;s not the world&#8217;s most robust Art-Net receive code but it&#8217;ll work for proof of concept purposes. Next I added the UdpRxArtNetRecv function to the UDP callback table in MCC_Generated_Files/TCPIPLibrary/udpv4_port_handler_table.c:</p>
<pre>const udp_handler_t UDP_CallBackTable[] = \
{    
    {68, DHCP_Handler},     
    {0x1936, UdpRxArtNetRecv},
};</pre>
<p>Then inside main.c I added a call to UdpRxArtNetInit () to initialize the Art-Net receiver. I rebuilt the project and downloaded the code. (The first version of the code called printf&#8217;s to display the first few bytes of received RGB data rather than calling WS2812b_Write as shown in the listing above.) I then used my PC to generate Art-Net packets with 60 LEDs (180 channels) of data and send those to the PIC-WEB board. The printf&#8217;s showed the sent levels and it was time to move on to controlling the pixels.</p>
<h3>Controlling the Pixels</h3>
<p>In the past, I&#8217;ve used an FPGA to generate perfect WS2812 LED pixel timing. I did not use an FPGA on this project and instead used software to bit bang the protocol to the LEDs. Fortunately, the LEDs are quite tolerant to deviations from the timing specified in the data sheet and I had no issues controlling them.</p>
<p>The ws2812b.h header file:</p>
<pre>#ifndef WS2812B_H
#define    WS2812B_H

#ifdef    __cplusplus
extern "C" {
#endif

#define NUM_LEDS 60
#define NUM_CHANS (3*NUM_LEDS)
    
#define WS2812b_LAT LATBbits.LB2
#define WS2812b_TRIS TRISBbits.TRISB2

void WS2812b_Init (void);
void WS2812b_Write (void);

extern uint8_t ledData[NUM_CHANS];
extern const uint8_t gamma8[256];

#ifdef    __cplusplus
}
#endif

#endif    /* WS2812B_H */</pre>
<p>The ws2812b.c source file:</p>
<pre>#include &lt;stdint.h&gt;
#include "mcc_generated_files/mcc.h"
#include "ws2812b.h"


const uint8_t gamma8[] = {
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
    1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,
    2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,
    5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,  9,  9, 10,
   10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
   17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
   25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
   37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
   51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
   69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
   90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
  115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
  144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
  177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
  215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };

uint8_t ledData[NUM_CHANS];


void WS2812b_Init (void)
{
    WS2812b_LAT = 0;
    WS2812b_TRIS = 0;
}


void WS2812b_Write (void)
{
    uint8_t i, j, a;
    
    INTERRUPT_GlobalInterruptDisable();
    INTERRUPT_PeripheralInterruptDisable();

    for (i = 0; i &lt; NUM_CHANS; i++) {
        a = ledData[i];

        // 7
        if (a &amp; 0x80) {
            WS2812b_LAT = 1;
            NOP();
            NOP();
            NOP();
            NOP();
        } else {
            WS2812b_LAT = 1;
            NOP();
        }
        WS2812b_LAT = 0;

        // 6
        if (a &amp; 0x40) {
            WS2812b_LAT = 1;
            NOP();
            NOP();
            NOP();
            NOP();
        } else {
            WS2812b_LAT = 1;
            NOP();
        }
        WS2812b_LAT = 0;

        // 5
        if (a &amp; 0x20) {
            WS2812b_LAT = 1;
            NOP();
            NOP();
            NOP();
            NOP();
        } else {
            WS2812b_LAT = 1;
            NOP();
        }
        WS2812b_LAT = 0;

        // 4
        if (a &amp; 0x10) {
            WS2812b_LAT = 1;
            NOP();
            NOP();
            NOP();
            NOP();
        } else {
            WS2812b_LAT = 1;
            NOP();
        }
        WS2812b_LAT = 0;

        // 3
        if (a &amp; 0x08) {
            WS2812b_LAT = 1;
            NOP();
            NOP();
            NOP();
            NOP();
        } else {
            WS2812b_LAT = 1;
            NOP();
        }
        WS2812b_LAT = 0;

        // 2
        if (a &amp; 0x04) {
            WS2812b_LAT = 1;
            NOP();
            NOP();
            NOP();
            NOP();
        } else {
            WS2812b_LAT = 1;
            NOP();
        }
        WS2812b_LAT = 0;

        // 1
        if (a &amp; 0x02) {
            WS2812b_LAT = 1;
            NOP();
            NOP();
            NOP();
            NOP();
        } else {
            WS2812b_LAT = 1;
            NOP();
        }
        WS2812b_LAT = 0;

        // 0
        if (a &amp; 0x01) {
            WS2812b_LAT = 1;
            NOP();
            NOP();
            NOP();
            NOP();
        } else {
            WS2812b_LAT = 1;
            NOP();
        }
        WS2812b_LAT = 0;
    }

    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
}</pre>
<p>I placed the call to WS2812b_Write inside the Art-Net UDP receive function and a call to WS2812b_Init inside my main function. The lights did not work quite right on the first try. This code required an oscilloscope and a few tries to get the timing good enough to reliably control the LEDs. Eventually though, I could reliably control the LED colors and brightness from Art-Net UDP packets sent from either my PC or my iPad.</p>
<h3>Serial EEPROM and MAC Address</h3>
<p>The PIC-WEB board does not have an EUI-48 serial EEPROM so I had to use a locally administered MAC address for the initial software development. Once I got my boards back, I wrote some SPI code to read the MAC address from the serial EEPROM and use this address instead of the MAC address configured in the MCC generated header file.</p>
<p>spi1.h:</p>
<pre>#ifndef SPI1_H
#define    SPI1_H

#ifdef    __cplusplus
extern "C" {
#endif

void spi1_Init (void);
uint8_t spi1_ExchangeByte (uint8_t in);

#ifdef    __cplusplus
}
#endif

#endif    /* SPI1_H */</pre>
<p>spi1.c:</p>
<pre>#include &lt;xc.h&gt;
#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;
#include "spi1.h"

void spi1_Init (void)
{
    SSP1CON1bits.SSPEN1 = 0;

    TRISBbits.TRISB4 = 0; // e48 csb - output
    LATBbits.LATB4   = 1; // e48 csb - set to high / not asserted
    TRISCbits.TRISC3 = 0; // sck     - output
    TRISCbits.TRISC4 = 1; // miso    - input
    TRISCbits.TRISC5 = 0; // mosi    - output

    SSP1STATbits.CKE = 1;
    SSP1STATbits.SMP = 1;    
    SSP1CON1 = 0x02;
    SSP1CON2 = 0x00;
    SSP1CON1bits.SSPEN = 1;
}

uint8_t spi1_ExchangeByte (uint8_t data )
{
    SSP1BUF = data;
    while(!PIR1bits.SSP1IF);
    PIR1bits.SSP1IF = 0;
    return SSP1BUF;
}</pre>
<p>Finally the code to read the MAC address from the serial EEPROM.</p>
<p>mac_eeprom.h:</p>
<pre>#ifndef MAC_EEPROM_H
#define    MAC_EEPROM_H

#ifdef    __cplusplus
extern "C" {
#endif

#define MAC_ADDR_48                 0xFA
#define MAC_ADDR_64                 0xF8

/***************** 25AA02E48 Instruction Set Summary *********************/
#define MAC_EE_READ     0x03
#define MAC_EE_WRITE    0x02
#define MAC_EE_WRDI     0x04
#define MAC_EE_WREN     0x06
#define MAC_EE_RDSR     0x05
#define MAC_EE_WRSR     0x01

void e48_read_mac(uint8_t *mac);

#ifdef    __cplusplus
}
#endif

#endif    /* MAC_EEPROM_H */</pre>
<p>mac_eeprom.c:</p>
<pre>#include &lt;xc.h&gt;
#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;
#include "spi1.h"
#include "mac_eeprom.h"

// e48_Csb on RB4
// SCK on SCK1/RC3
// MISO on SDI1/RC4
// MOSI on SDO1/RC5

void e48_read_mac(uint8_t *mac)
{
    uint8_t i;
    
    // set cs low
    LATBbits.LATB4   = 0;
    
    spi1_ExchangeByte (MAC_EE_READ);
    spi1_ExchangeByte (MAC_ADDR_48);
    
    for (i = 0; i &lt; 6; i++) {
        mac[i] = spi1_ExchangeByte (0x00);
    }
    
    // set high low
    LATBbits.LATB4   = 1;
    
    // printf("macAddr:%.2X:%.2X:%.2X:%.2X:%.2X:%.2X \r\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
}</pre>
<p>That&#8217;s a brief summary of the code I have written for this project to date. Eventually, I will need to add LLDP to specify the power requirements of my board with a bit more granularity. A follow on project may require HTTP requests and NTP as well.</p>
<h2>Bring Up and Testing</h2>
<div id="attachment_1972" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-works.jpg"><img class="size-large wp-image-1972" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-works-1024x576.jpg" alt="Bringing up the PoE+ PD circuitry and power supplies." width="640" height="360" /></a><p class="wp-caption-text">Bringing up the PoE+ PD circuitry and power supplies.</p></div>
<p>Once the boards arrived, I mounted the components required for PoE+ classification and the power supplies to the board as shown in the photo above. Initially the PoE classification failed every time. The switch would try twice about every three seconds. Some LEDs on the board would light briefly but classification would fail and the power supplies would not be turned on.</p>
<p>Eventually I traced the problem to a resistor and an LED I put across the output of the bridge rectifiers to try to indicate when the switch was supplying power to the board. <strong>This does not work.</strong> The current consumed by the LED in parallel with the detection and classification currents is not within the specs required for the detection and classification currents.</p>
<p>I removed the resistor and LED then detection and classification completed successfully. The 802.3at / PoE+ T2P LED lit then the 5 VDC and 3.3 VDC power supply LEDs lit. I used a multimeter to measure the 5 VDC and 3.3 VDC outputs. They were in spec so I proceeded to mount the microcontroller and the rest of the components.</p>
<div id="attachment_2062" style="width: 866px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-alive.png"><img class="size-full wp-image-2062" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/poe-alive.png" alt="My switch indicating the board is receiving power and has a valid IP address. This was before I was using the EUI-48 serial EEPROM to configure a MAC address." width="856" height="353" /></a><p class="wp-caption-text">My switch indicating the board is receiving power and has a valid IP address. This was before I was using the EUI-48 serial EEPROM to configure a MAC address.</p></div>
<p>Once the rest of the components were mounted, I downloaded the software I developed using the Olimex PIC-WEB board to my board. Everything more or less worked perfectly! My network switch indicated the power advertised by the board, the power consumed by the board, and the IP address assigned to the board by the DHCP server.</p>
<p>There were some small tweaks to the software that came later like adding code to get a real MAC address from the serial EEPROM and adding code to turn LEDs on and off to indicate the status of the DHCP client and when an Art-Net packet was received.</p>
<div id="attachment_1973" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/IMG_20191207_120244-2000.jpg"><img class="size-large wp-image-1973" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/IMG_20191207_120244-2000-1024x682.jpg" alt="Completed board with a one meter strip of 60 WS2812 LEDs connected." width="640" height="426" /></a><p class="wp-caption-text">Completed board with a one meter strip of 60 WS2812 LEDs connected.</p></div>
<p>The photograph above shows the finished board driving a strip of 60 WS2812 LEDs. The power for the LEDs is delivered from an 802.3at / PoE+ capable network switch. The data for the LEDs comes from Art-Net packets generated by my PC.</p>
<div id="attachment_1962" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/PixPoE-Top-2000.jpg"><img class="size-large wp-image-1962" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/PixPoE-Top-2000-1024x682.jpg" alt="Photograph of the top of the completed board. " width="640" height="426" /></a><p class="wp-caption-text">Photograph of the top of the completed board.</p></div>
<p>Above is a close up photo of the top of the finished board.</p>
<div id="attachment_1961" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/PixPoE-Bottom-2000.jpg"><img class="size-large wp-image-1961" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/PixPoE-Bottom-2000-1024x682.jpg" alt="Photograph of the bottom of the completed board." width="640" height="426" /></a><p class="wp-caption-text">Photograph of the bottom of the completed board.</p></div>
<p>Above is a close up photo of the bottom of the finished board.</p>
<h2>Decorating the Tree</h2>
<div id="attachment_1963" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/LEDs.jpg"><img class="size-large wp-image-1963" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/LEDs-1024x682.jpg" alt="A circuit board in a (fake) pine tree." width="640" height="426" /></a><p class="wp-caption-text">A circuit board in a (fake) pine tree.</p></div>
<p>I initially used the one meter strip of sixty WS2812 pixels rather than the string of 50 pixels because the strip fit entirely on my desk and it was very easy to look and see if the pixels were displaying the patterns from my PC properly or not. Once the code was running properly, it was time to go bigger!</p>
<p>I grabbed the five meter string of 50 pixels and a cheap $20 fake tree from Michael&#8217;s and proceeded to string the lights on the tree. I stuffed the board in the tree then shot the quick video at the top of this post. I&#8217;m pretty sure the tree is not an ESD-safe location for the circuit board.</p>
<div id="attachment_2059" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/thumbnail.jpg"><img class="size-large wp-image-2059" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/thumbnail-1024x576.jpg" alt="The decorated tree." width="640" height="360" /></a><p class="wp-caption-text">The decorated tree.</p></div>
<p>Above is a thumbnail from the video showing the decorated tree in my home office.</p>
<h2>Future Power over Ethernet Projects</h2>
<div id="attachment_1977" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/IMG_20191217_224903-2000.jpg"><img class="size-large wp-image-1977" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/IMG_20191217_224903-2000-1024x682.jpg" alt="Philip Color Kinetics ColorBurst 4 10 watt RGB LED flood light controlled and powered over the network." width="640" height="426" /></a><p class="wp-caption-text">Philip Color Kinetics ColorBurst 4 10 watt RGB LED flood light controlled and powered over the network.</p></div>
<p>I have two more Power over Ethernet projects in progress. The first one is almost complete. It uses a Silvertel 24 volt isolated PoE+ module to power a Philips Color Kinetics ColorBurst 4 10-watt RGB LED flood light. Control data for the light comes from Synthe-Fx&#8217;s Luminair 3 software running on an iPad.</p>
<div id="attachment_2066" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/12/clock-2-v11-cropped-jpg.jpg"><img class="size-large wp-image-2066" src="https://bikerglen.com/wp/wp-content/uploads/2019/12/clock-2-v11-cropped-jpg-1024x683.jpg" alt="Rear view of the PoE-powered VFD tube clock enclosure." width="640" height="427" /></a><p class="wp-caption-text">Rear view of the PoE-powered VFD tube clock enclosure.</p></div>
<p>The second project is an IV-12 VFD tube display that gets both power and time or other data for display over the network. This second project uses one of the Molex Ethernet jacks with integrated magnetics and 802.3at PoE+ classification circuitry. This project is in progress. I&#8217;ve ordered the aluminum panels for the enclosure shown above but am waiting on my VFD tubes to arrive before ordering the circuit boards for the project.</p>
<h2>Design Files</h2>
<p>Design files for this project are in the <a href="https://github.com/bikerglen/pixpoe">PixPoE repository</a> in my github account. If anything&#8217;s missing or you have a question about something, you can find me on Twitter @bikerglen.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/ethernet-powered-pixels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reverse Engineering the iColor Flex Protocol</title>
		<link>https://bikerglen.com/blog/reverse-engineering-the-icolor-flex-protocol/</link>
		<comments>https://bikerglen.com/blog/reverse-engineering-the-icolor-flex-protocol/#comments</comments>
		<pubDate>Sun, 17 Nov 2019 02:10:08 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[RGB LED]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=1705</guid>
		<description><![CDATA[Back in the early 2000&#8217;s&#8211;at least a decade before there were Neopixels or WS2812b LEDs&#8211;Color Kinetics introduced flexible color changing LED string lights. Each string contained fifty RGB color changing nodes. Each node contained an RGB LED and a custom &#8230; <a href="https://bikerglen.com/blog/reverse-engineering-the-icolor-flex-protocol/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_1803" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/house.jpg"><img class="size-large wp-image-1803" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/house-1024x576.jpg" alt="Hanging a bunch of iColor Flex LMX string lights on the house for Halloween." width="640" height="360" /></a><p class="wp-caption-text">Hanging a bunch of iColor Flex LMX string lights on the house for Halloween. These are quite visible even though it&#8217;s still daylight out!</p></div>
<p>Back in the early 2000&#8217;s&#8211;at least a decade before there were Neopixels or WS2812b LEDs&#8211;Color Kinetics introduced flexible color changing LED string lights. Each string contained fifty RGB color changing nodes. Each node contained an RGB LED and a custom ASIC. The nodes were strung along at either 4&#8243; or 12&#8243; spacing along a three conductor cable. The cable connected back to a power data supply that powered the nodes and translated the light level data from either DMX-512 or Ethernet UDP packets into the proprietary protocol used by the nodes. Today we&#8217;re going to reverse engineer that proprietary protocol.</p>
<p><span id="more-1705"></span></p>
<h2>Branding</h2>
<p>Color Kinetics is big into branding and trademarks. They call their RGB LED string lights iColor Flex, the ASIC inside each node is a Chromasic, and the protocol they use to communicate is called the Chromasic protocol. The biggest differentiators between all the different products are the color of light emitted, RGB or white, and the diameter of the node, 15 mm or 35 mm.</p>
<h3>iColor Flex SL</h3>
<div id="attachment_1792" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/icolor-flex-sl.jpg"><img class="size-large wp-image-1792" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/icolor-flex-sl-1024x684.jpg" alt="Three iColor Flex SL nodes." width="640" height="428" /></a><p class="wp-caption-text">Three iColor Flex SL nodes.</p></div>
<p>The original iColor Flex product was iColor Flex SL. Each node was a dot about 15 mm in diameter and contained a single RGB LED. These were available in eight different configurations by selecting from among the following options:</p>
<ul>
<li>Black wire and nodes or white wire and nodes.</li>
<li>Nodes spaced at 4&#8243; or 12&#8243;.</li>
<li>Dome or cone diffuser.</li>
<li>Clear or translucent diffuser.</li>
</ul>
<p>The iColor Flex SL product ran from 7.5 V and was advertised as capable of producing 68 billion color combinations. Each node used three channels for control: one for red, one for green, and one for blue. A twenty foot leader cable extended from the first node in the string and plugged directly into a power data supply. The power supply connector was permanently attached to the leader cable.</p>
<h3>iColor Flex SLX</h3>
<p>The second product was iColor Flex SLX. Each node was a dot about 35 mm in diameter and contained three RGB LEDs. These were available in eight different configuration too except the choices for the shape of the diffuser were now dome or flat. These ran from 12 V, used three control channels, and came with an attached twenty feet leader cable that plugged directly into a power data supply.</p>
<h3>iColor Flex MX, LMX, MX gen2, and LMX gen2</h3>
<div id="attachment_1799" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/icolor-flex-lmx-nodes.jpg"><img class="size-large wp-image-1799" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/icolor-flex-lmx-nodes-1024x684.jpg" alt="iColor Flex LMX nodes." width="640" height="428" /></a><p class="wp-caption-text">iColor Flex LMX nodes.</p></div>
<p>As RGB LEDs continued to get brighter, Color Kinetics refreshed their product line. The small nodes became iColor Flex MX and MX gen2. The large nodes became iColor Flex LMX and LMX gen2. In addition the large nodes now contained six RGB LEDs instead of three and ran from 24 V instead of 12 V.</p>
<p>Another big change introduced with these products was a detachable leader cable that could be shortened to fit the user&#8217;s application. The string of nodes now shipped with a short three foot pigtail that plugged into a leader cable that connected back to the power supply through a dongle. We&#8217;ll cover the dongle and leader cable in detail in a following section.</p>
<h3>Fixed and Variable Color Temperature White Strings</h3>
<div id="attachment_1800" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/ew-flex-nodes.jpg"><img class="size-large wp-image-1800" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/ew-flex-nodes-1024x684.jpg" alt="eW Flex SLX nodes." width="640" height="428" /></a><p class="wp-caption-text">eW Flex SLX nodes.</p></div>
<p>Color Kinetics also makes their string lights in fixed and variable color temperature white light versions. The fixed color temperature versions are branded as eW Flex or Essential White Flex. These contain one or five white LEDs and are available in a variety of fixed color temperatures. Each node requires three control channels. The first channel controls the brightness of the node. The second and third channels are unused.</p>
<p>The variable color temperature versions are branded as iW Flex or intelliWhite Flex. These contain both 2700 K and 6500 K LEDs and require three control channels per node. The first channel controls the 2700 K LEDs and the second channel controls the 6500 K LEDs. The third channel is unused. These products are capable of producing any color temperature between 2700 K and 6500 K by varying the levels of the different color temperature LEDs.</p>
<p>Like their RGB counterparts, these products went through several product generations too. Some examples:</p>
<ul>
<li>eW Flex SLX, 24V, fixed color temperature, direct connection to power supply</li>
<li>eW Flex Micro, 7.5V, fixed color temperature, direct connection to power supply</li>
<li>eW Flex Compact, 24V, fixed color temperature, leader cable required to connect to power supply</li>
<li>iW Flex Compact, 24V, variable color temperature, leader cable required to connect to power supply</li>
</ul>
<p>As a side note, the eW Flex Compact lights are used on the Bay Bridge in San Francisco.</p>
<h3>Even Newer Products</h3>
<p>They also have some newer products branded FlexElite. It&#8217;s likely they use a different ASIC and protocol since many of these products have four channels instead of three channels of LEDs. I don&#8217;t have any of these products so we&#8217;ll have to skip reverse engineering them for now.</p>
<h2>The Typical iColor Flex Setup</h2>
<div id="attachment_1746" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/ckca-setups.png"><img class="size-large wp-image-1746" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/ckca-setups-1024x589.png" alt="The two different of iColor Flex setups. These are distinguished by having an integrated leader cable or a separate dongle and leader cable." width="640" height="368" /></a><p class="wp-caption-text">The two different iColor Flex setups. These are distinguished by having an integrated leader cable or a separate dongle and leader cable.</p></div>
<p>In a typical iColor Flex setup, a controller connects to a power data supply over a DMX-512 or wired Ethernet network and the power data supply connects to the lights via a leader cable. The power data supply injects DC power into the string of lights and translates the DMX-512 or Ethernet packets from the controller into the proprietary packet format used by the nodes.</p>
<p>In early versions of the lights, the leader cable was directly connected to the first node in the string and was typically twenty feet long. In the later versions, the power supply connects to the lights using a dongle and a leader cable that connects to a short pigtail from the first node in the string. The change was made to support non-outdoor power supplies, to allow for a longer leader cable, and to allow the leader cable to be cut to shorter lengths in the field.</p>
<h3>The Older Setup: Controller, Power Supply, and Lights</h3>
<div id="attachment_1790" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/icolor-flex-sl-setup.jpg"><img class="size-large wp-image-1790" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/icolor-flex-sl-setup-1024x682.jpg" alt="An iColor Flex SL setup. DMX data feeds into power data supply then power data supply connects to nodes using an integrated twenty foot leader cable." width="640" height="426" /></a><p class="wp-caption-text">An iColor Flex SL setup. DMX data from a controller (not pictured) feeds into the power data supply then the power data supply connects to nodes using an integrated twenty foot leader cable.</p></div>
<p>On the older iColor Flex light strings, the lights connected directly to the power data supply via an integrated leader cable. The stock leader cable was twenty feet long but could be ordered shorter for custom products. The leader cable has a four-pin AMP connector that plugs directly into the power data supply. The AMP connector is very similar to the Molex connectors used on PC power supplies but is not the same and the two are not interchangeable.</p>
<div id="attachment_1787" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/outdoor-pds60ca-early.jpg"><img class="size-large wp-image-1787" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/outdoor-pds60ca-early-1024x684.jpg" alt="A first generation outdoor rated power data supply with a string of lights with " width="640" height="428" /></a><p class="wp-caption-text">A string of lights with a permanently attached twenty foot leader cable connected directly to a first generation outdoor rated power data supply. The four-pin power data connector is not removable so the waterproof cable bushing comes preinstalled on the leader cable.</p></div>
<p>The only power supplies available at the time were versions designed for outdoor use. Since the four-pin AMP connector on the leader cable could not be removed and re-installed in the field, the leader cable came with a waterproof strain relief preinstalled. The end user would mount the power data supply and lights, feed the end of the leader cable into the power data supply, mount the strain relief on the power-data supply, then plug in the 4-pin amp connector. Any excess cable would have to be bundled up, hidden, and stored near the supply or lights.</p>
<h3>The Newer Setup: Controller, Power Supply, Dongle, Cable, and Lights</h3>
<div id="attachment_1795" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/icolor-flex-lmx-setup.jpg"><img class="size-large wp-image-1795" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/icolor-flex-lmx-setup-1024x682.jpg" alt="A complete iColor Flex LMX setup minus the controller. Ethernet data feeds into the power data supply. The power data supply is then connected to the nodes using a dongle and leader cable." width="640" height="426" /></a><p class="wp-caption-text">A complete iColor Flex LMX setup minus the controller. Ethernet data feeds into the power data supply. The power data supply is then connected to the nodes using a dongle and leader cable.</p></div>
<p>On the newer iColor Flex light strings, the lights connect to the power data supply via a dongle and detachable leader cable. The dongle plugs into the power supply, one end of the leader cable screws into a terminal block inside the dongle, and the other end of the dongle connects to a short pigtail from the first node in the string using three-pin Amphenol LTW circular connectors.</p>
<div id="attachment_1797" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/indoor-supply-with-leader-cable.jpg"><img class="size-large wp-image-1797" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/indoor-supply-with-leader-cable-1024x684.jpg" alt="A newer indoor supply with a dongle, leader cable, and a few iColor Flex LMX nodes." width="640" height="428" /></a><p class="wp-caption-text">A newer indoor supply with a dongle, leader cable, and a few iColor Flex LMX nodes.</p></div>
<p>This change has several advantages. First, the user can order a stock leader cable, remove the dongle, shorten the leader cable, and then reconnect the dongle. This allows custom leader cable lengths to be cut in the field. Second, leader cables could be made longer while maintaining their signal integrity. Third, the installation of a waterproof strain relief could be performed in the field: detach the dongle, thread the strain relief on to the leader cable, then re-attach the dongle. If the installation is indoors, the use of the waterproof strain relief can be skipped. If the installation is outdoors, the dongle is small enough to fit two of them inside the outdoor power data supplies.</p>
<h2>Goals for Our Reverse Engineering</h2>
<p>Our goal is to figure out the pin out of each connector and the protocol used at each point between the power supply and first node on the string. This includes at the four-pin AMP connector on the power data supply, the screw terminal block inside the dongle, and at the three-pin Amphenol LTW circular connector at the lights. Let&#8217;s start by looking for any publicly available information about the power supplies, protocol, and lights.</p>
<h2>What Public Information Is Available?</h2>
<p>A good reverse engineering effort starts with surveying what information is publicly available. In the case of the iColor Flex LED strings, there&#8217;s a data sheet and a patent.</p>
<h3>Data Sheet</h3>
<div id="attachment_1809" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/datasheet.png"><img class="size-large wp-image-1809" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/datasheet-1024x885.png" alt="The block diagram from the Chromasic data sheet." width="640" height="553" /></a><p class="wp-caption-text">The block diagram from the Chromasic data sheet.</p></div>
<p>Color Kinetics has a <a href="https://www.docs.colorkinetics.com/support/datasheets/Chromasic1.pdf">mostly useless data sheet</a> on their Chromasic chip posted on their website. The block diagram excerpted above is interesting just to see what is inside the chip. The most important information here is that the resolution of the chip and most likely the protocol is &#8220;12 bit PWM&#8221; with &#8220;64 billion additive RGB colors.&#8221; This implies we&#8217;re looking for 3 words of 12 bits in the protocol.</p>
<h3>Patents</h3>
<div id="attachment_1805" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/patents.jpg"><img class="size-large wp-image-1805" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/patents-1024x684.jpg" alt="A tag listing two of Color Kinetics patents. These patents are both expired and the link is now dead too." width="640" height="428" /></a><p class="wp-caption-text">A tag listing two of Color Kinetics patents. These patents are both expired and the link is now dead too.</p></div>
<p>Color Kinetics likes patents and were quite litigious in their early days. The lawsuits slowed down after their acquisition by Philips and many of their early patents have expired or are expiring soon. But patents aren&#8217;t just for litigation&#8211;patents are supposed to describe inventions such that a person having ordinary skill in the art can reproduce those inventions, right?</p>
<p>Two patent numbers are listed on the tags on each string. These are not the patents we&#8217;re interested in though. These are patents on using PWM to dim LEDs and mix colors and have both expired. The patent we&#8217;re interested in is <a href="https://patents.google.com/patent/US7598684B2"><em>US Patent 7,598,684, Methods and apparatus for controlling devices in a networked lighting system</em></a>. This patent covers &#8220;a plurality of LED-based lighting systems are arranged as computer controllable &#8216;light strings.'&#8221; This patent doesn&#8217;t expire until August 8, 2021.</p>
<h4>Encoding</h4>
<div id="attachment_1806" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/figure-10b.png"><img class="size-large wp-image-1806" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/figure-10b-795x1024.png" alt="Figure 10B in the patent is used to describe encoding zeros and ones on the wire and recovering those values in the LED node." width="640" height="824" /></a><p class="wp-caption-text">Figure 10B in the patent is used to describe encoding zeros and ones on the wire and recovering those values in the LED node.</p></div>
<p>The first of two big pieces of information in the patent is how bits are encoded. The patent includes a Figure 10B which shows a block diagram of the circuitry used to decode bits at the input of the node and re-encode new bits at the output of the node. The text that accompanies the figure describes a bit encoding scheme where the location of the falling edge between two rising edges determines the value of the bit. If the falling edge occurs before 1/2 the period, the bit is a zero. If the falling edge occurs after 1/2 the period, the bit is a one. The patent then goes on to describe a method using a counter to decode this encoding back to zeros and ones.</p>
<h4>Self-Addressing</h4>
<div id="attachment_1807" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/figure-11.png"><img class="size-large wp-image-1807" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/figure-11-795x1024.png" alt="Figure 11 from the patent" width="640" height="824" /></a><p class="wp-caption-text">Figure 11 in the patent described the self-addressing scheme including detecting start codes and replacing &#8220;used&#8221; levels with start codes to forward to the next node.</p></div>
<p>The second of two big pieces of information in the patent is how the nodes are addressed. The text describing the addressing scheme is accompanied by a Figure 11. Basically the node looks for a start code then grabs the next three channels of data and uses those to set its levels. Rather than forward those three channels of data to the next node, it replaces those three channels of data with three start codes. The next node in the string will now see four start codes then grab three levels of data replacing the grabbed data with additional start codes. This continues until the last node on the string.</p>
<h2>Power Supply and Power Supply Connector Pin Out</h2>
<div id="attachment_1759" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/ckca-pds-pinout.png"><img class="wp-image-1759 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/ckca-pds-pinout-1024x627.png" alt="ckca pds pinout" width="640" height="392" /></a><p class="wp-caption-text">7.5 V and 24 V power data supply 4-pin power/data connector pin out.</p></div>
<p>The next step in reverse engineering the protocol was to figure out the pin out of the four-pin connectors on the power supplies. The string lights only use three of the four pins on the four-pin plug. I used a DMM and measured across the various permutations of these three pins on a 24 V power supply until I found a pair of pins that matched the supply voltage. The third pin should then be the data pin. I measured the voltage and it was about 2.35 V which is well within the electrical limits of my scope and its probes.</p>
<div id="attachment_1815" style="width: 810px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/scope_0.png"><img class="size-full wp-image-1815" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/scope_0.png" alt="The data output at the output of the power data supply." width="800" height="632" /></a><p class="wp-caption-text">The data output at the output of the power data supply.</p></div>
<p>The next step was to use an oscilloscope to observe the signal on the third pin. The signal had a low voltage of 0 V, a high voltage of 5 V, and a frequency of 454.5 kHz measured rising edge to rising edge. The observed square wave signal alternated between two distinct duty cycles. The first duty cycle was high for 0.6 us then low for 1.6 us. The second duty cycle was high for 1.6 us then low for 0.6 us. These findings were good news because both the frequency and the waveforms are similar to those described in the patent.</p>
<div id="attachment_1785" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/connectors.jpg"><img class="size-large wp-image-1785" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/connectors-1024x684.jpg" alt="On the left is a string of lights requiring 24 V. On the right is a string of lights requiring 7.5 V. Notice the pin out differences between the two." width="640" height="428" /></a><p class="wp-caption-text">On the left is a string of lights requiring 24 V. On the right is a string of lights requiring 7.5 V. Notice the pin out differences between the two.</p></div>
<p>The next catch was that the 7.5 V string lights and the 24 V string lights use a different set of three of the four pins. A bit more probing with the DMM discovered that both strings of lights used the same data and ground pin but the 7.5 V lights used a different third pin than the 24 V lights. I probed the 7.5 V power supply and quickly discovered that the two power supplies place their output voltages on different pins presumably to stop end users from accidentally applying 24 V to a 7.5 V light string.</p>
<p>The last step was to discover the manufacturer and part number for the connectors used on the power supply and the string of lights. They looked like Molex connectors but observing the connectors under a microscope revealed an AMP logo and pin numbers embossed in the plastic. I used a set of calipers to take some measurements of the connectors and browsed the Digi-Key and TE Connectivity websites until I found the matching connectors. The connectors and their part numbers for making your own power supplies, cables, and adapters are:</p>
<table>
<tbody>
<tr>
<th>Description</th>
<th>Manufacturer</th>
<th>Part #</th>
</tr>
<tr>
<td>Board-mount connector</td>
<td>TE Connectivity</td>
<td>1-770174-0</td>
</tr>
<tr>
<td>Right-angle board-mount connector</td>
<td>TE Connectivity</td>
<td>1-770968-0</td>
</tr>
<tr>
<td>Free-hanging plug</td>
<td>TE Connectivity</td>
<td>172167-1</td>
</tr>
<tr>
<td>Crimp contacts for 18-22 AWG wire</td>
<td>TE Connectivity</td>
<td>794831-1</td>
</tr>
</tbody>
</table>
<p>I couldn&#8217;t justify a ratcheting crimping tool to crimp wires on to the contacts so I&#8217;m using a Molex #63811-1000 non-ratcheting hand crimp tool to crimp the contacts onto wires when making my own cables.</p>
<h2>The Dongle</h2>
<div id="attachment_1783" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/dongle-front.jpg"><img class="size-large wp-image-1783" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/dongle-front-1024x682.jpg" alt="The dongle doesn't look very complicated." width="640" height="426" /></a><p class="wp-caption-text">The dongle doesn&#8217;t look very complicated.</p></div>
<p>The next step was to figure out what the dongle and the huge lump at the end of the leader cable do. The dongle has a three-inch pigtail terminated in an AMP four-pin connector that plugs into a power data supply. The other end of the dongle has four-position screw terminal block that connects to the leader cable. The user can remove the cable from the dongle, cut it to length, install a waterproof bushing for outdoor use, then reconnect the cable to the dongle.</p>
<p>Taking a dongle apart, it looks simple enough. V+, V+, GND, and DATA solder pads on the input side, a bunch of coils, and RED, BLUE, BLUE/WHITE, BLK labels on the screw terminals on the output side. The V+ and V+ solder pads on the input side have a trace connecting them together so that the dongle gets power regardless of whether it is attached to a 7.5 V or 24 V power data supply. Looking at the leader cable though, the four conductors are two different gauges. The red and black wires are heavier gauge then the blue and blue/white wires. Furthermore, the blue and blue/white wires are twisted together into a pair. Something more must be going on.</p>
<div id="attachment_1782" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/dongle-rear.jpg"><img class="size-large wp-image-1782" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/dongle-rear-1024x684.jpg" alt="OMG. There's a ton of stuff going on inside the dongle." width="640" height="428" /></a><p class="wp-caption-text">OMG. There&#8217;s a ton of stuff going on inside the dongle.</p></div>
<p>Indeed, removing the board completely from the plastic enclosure and looking at the back reveals quite a few chips and passives. There&#8217;s a what&#8217;s most likely a comparator, a small power supply, and most importantly for us, a MAX485 RS-485/RS-422 transceiver. While examining the circuit board traces around the MAX485, I made a few observations. First the MAX485&#8217;s receiver is hard-wired to be disabled. Second, the MAX485&#8217;s transmitter is hard-wired to be enabled. Lastly, the MAX485&#8217;s output is directly connected to the blue and blue/white screw terminals.</p>
<div id="attachment_1817" style="width: 810px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/scope_4.png"><img class="size-full wp-image-1817" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/scope_4.png" alt="Differential data output at the output of the dongle." width="800" height="632" /></a><p class="wp-caption-text">Differential data output at the output of the dongle.</p></div>
<p>My conclusion is that the dongle converts the single-ended signal from the power data supply into a differential signal to transmit through the leader cable and to the lights. Differential signalling allows the use of leader cables up to about 100 feet versus the old single-ended lights that had a maximum leader cable length of up to about 20 feet. Viewing the dongle&#8217;s data input and outputs on a scope confirms this is the case.</p>
<p>The screw terminal labeled RED is the DC voltage from the power supply. The BLUE terminal is the inverted data output. The BLUE/WHT terminal is the non-inverting data output. Finally, the BLACK terminal is ground.</p>
<h2>The Other End of the Leader Cable</h2>
<div id="attachment_1780" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/leader-cable-lump.jpg"><img class="size-large wp-image-1780" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/leader-cable-lump-1024x684.jpg" alt="The lump in the far end of the leader cable that connects to the light strings." width="640" height="428" /></a><p class="wp-caption-text">The lump in the far end of the leader cable that connects to the light strings.</p></div>
<p>The other end of the leader cable has a huge lump with an Amphenol LTW three-pin circular connector that connects to the light string. This end of the cable is pretty well sealed so I didn&#8217;t take it apart. This end of the cable converts the differential signal back into a single-ended signal to drive the lights.</p>
<div id="attachment_1770" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/ckca-leader-pinout.png"><img class="size-large wp-image-1770" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/ckca-leader-pinout-1024x643.png" alt="Leader cable pin out." width="640" height="402" /></a><p class="wp-caption-text">Leader cable pin out.</p></div>
<p>I used a DMM and scope to determine the pin out of the connector. The connectors on the light strings are stamped LTW. I used this fact along with a set of measurements to find the connector manufacturer and part numbers for making my own cables.</p>
<table>
<tbody>
<tr>
<th>Description</th>
<th>Manufacturer</th>
<th>Part #</th>
</tr>
<tr>
<td>Board-mount receptacle, sockets</td>
<td>Amphenol LTW</td>
<td>BD-03PMFS-LC7001</td>
</tr>
<tr>
<td>Inline receptacle, sockets</td>
<td>Amphenol LTW</td>
<td>BD-03BMFA-LL7001</td>
</tr>
<tr>
<td>Inline plug, pins</td>
<td>Amphenol LTW</td>
<td>BD-03BFMA-LL7001</td>
</tr>
</tbody>
</table>
<h2>Digging into the Protocol</h2>
<p>Time to dig into the protocol and see how to control the lights. We already used a scope to derive the voltage levels and timing of the protocol. Now it was time to capture lots of data with varying light levels to derive how the levels are communicated to the lights. From the patent, we&#8217;re looking for a start code followed by light levels. From their marketing communications, we&#8217;re looking for RGB levels with 68 billion possible different colors. This translate to 36 bits or three words of 12 bits.</p>
<div id="attachment_1778" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/probing_nodes.jpg"><img class="size-large wp-image-1778" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/probing_nodes-1024x682.jpg" alt="Using a small USB logic analyzer to capture data into and out of the the first node in the light string." width="640" height="426" /></a><p class="wp-caption-text">Using a small USB logic analyzer to capture data into and out of the the first node in the light string.</p></div>
<p>This step involved a lot of tedious work sending different color patterns to different numbers of nodes and observing the output of the power data supply with a small logic analyzer. I used two channels of the logic analyzer. The first channel was connected between the power data supply and the first node on the string of lights. The second channel was connected between the first and second node on the string of lights.</p>
<p>After performing a capture with the logic analyzer, I saved the captured data to a file then wrote some C code to parse the timing of the rising and falling edges into zeros and ones based on whether or not the falling edge occurred before (zero) or after (one) half the time between two successive rising edges. There were two possibilities here. I guessed correctly.</p>
<p>After many, many captures the protocol became apparent. Here&#8217;s a snip of a data capture between an older outdoor-rated power data supply and the first node with the first node set to red with a bit of blue and the second node set to yellow:</p>
<pre>111111111111100000000
101111111111100000001000000000000000000010011000000000000000
101111111111100000001010100001111000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000</pre>
<p>I noticed a start code of 13 ones followed by 8 zeros followed by data that varied based on the light levels. This pattern occurred at 25 ms interval which matched the update rate set in my controller software.</p>
<p>Immediately following this start code were 20 bit words. Each word began with a one, had 12 varying bits, then ended with 7 zero bits. From varying the levels and performing many captures I observed the light levels varied between 0 and 4094, were ordered red -&gt; green -&gt; blue, and were sent least-significant bit first. A light level of 4095 would be identical to a start code so the maximum light level is 4094 instead of 4095.</p>
<p>The data between the first node and second node was identical to the data between the power supply and the first node except the start code was now a 20 bit word and the RGB levels of the first node&#8217;s data had been replaced with start codes:</p>
<pre>11111111111110000000
111111111111100000001111111111111000000011111111111110000000
101111111111100000001010100001111000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000010000000000000000000
100000000000000000001000000000000000000000000000000000000000

</pre>
<p>There were some additional wrinkles in the protocol. About six nodes of zero data are sent after the number of nodes configured in the software. These seem to be required to pump the last few nodes of data out to the end of the strings for some reason. With the newer power data supplies, the blue channel is sent as a 21 bit word instead of a 20 bit word. The newer power data supplies also send a start code followed by a few zero bits when the line is idle versus the older power data supplies that just send zero bits all the time.</p>
<h2>The Protocol</h2>
<p>Here&#8217;s my final observation of the protocol:</p>
<ol>
<li>Send zero bits when the line is idle. Optionally: send start codes followed by a small number of zero bits. When ready to send data, revert to sending zero bits for a few hundred bits.</li>
<li>When node data is ready to send:
<ol>
<li>Send the 21 bit start code &#8216;b1_111111111111_00000000</li>
<li>Send the first node&#8217;s 20 bit red value &#8216;b1_rrrrrrrrrrrr_0000000</li>
<li>Send the first node&#8217;s 20 bit green value &#8216;b1_gggggggggggg_0000000</li>
<li>Send the first node&#8217;s 21 bit blue value &#8216;b1_bbbbbbbbbbbb_00000000</li>
<li>Repeat steps B through D for the remaining nodes</li>
</ol>
</li>
<li>When node data is done being sent, send six nodes of zero level data:
<ol>
<li>Send 20 bit red zero value &#8216;b1_000000000000_0000000</li>
<li>Send 20 bit green zero value &#8216;b1_000000000000_0000000</li>
<li>Send 21 bit blue zero value &#8216;b1_000000000000_00000000</li>
<li>Repeat steps A through C six times</li>
</ol>
</li>
</ol>
<p>The above protocol seems to work with the string lights that I have.</p>
<h2>Compared to WS2812b / Neopixels</h2>
<p>The WS2812b / Neopixel LEDs, tapes, and strings were developed about a decade after the iColor Flex string lights. It might be worth comparing and contrasting the Chromasic protocol to the WS2812b protocol.</p>
<p>First, the similarities. Sending a zero and a one is similar between the two protocols. A zero is a pulse with a short high time and a long low time. A one is a pulse with a long high time and short low time.</p>
<p>Now the differences:</p>
<table>
<tbody>
<tr>
<th>Item</th>
<th>WS2812b</th>
<th>Chromasic</th>
</tr>
<tr>
<td>Baud Rate</td>
<td>800 kHz</td>
<td>454.4 kHz</td>
</tr>
<tr>
<td>Bits Per Pixel</td>
<td>24</td>
<td>36</td>
</tr>
<tr>
<td>Idle Pattern</td>
<td>Hold data line low</td>
<td>Send zeros</td>
</tr>
<tr>
<td>Addressing Mode</td>
<td>Reset to address first node; used data is &#8220;swallowed&#8221; by the node and not sent to downstream nodes.</td>
<td>Send start code to address first node; consumed data is replaced by start codes sent to downstream nodes.</td>
<td></td>
</tr>
</tbody>
</table>
<p>Overall, the WS2812b protocol seems easier to implement on both microcontrollers and FPGAs mostly because you do not have to continuously send an idle pattern with the WS2812b LEDs.</p>
<h2>Gamma Correction</h2>
<p>Eight-bit DMX values from 0 to 255 map non-linearly to 12-bit values from 0 to 4094. This mapping is performed by the power data supply. I have not determined the exact mapping due to the time consuming nature of sending levels, capturing data with a logic analyzer, decoding it with my C code, then parsing through text files of zeros and ones. This would need to be done 254 more times to map all 256 DMX levels to their 12-bit values. I may build another FPGA in the future to help decode and determine the mapping used by the power data supplies.</p>
<h2>Using an FPGA to Implement the Protocol</h2>
<h3>Hardware Interface</h3>
<div id="attachment_1819" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/fpga-with-ckca-pmod.jpg"><img class="size-large wp-image-1819" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/fpga-with-ckca-pmod-1024x684.jpg" alt="Digilent Cora Z7 FPGA board with a custom PMOD board to interface the FPGA to the iColor Flex strings." width="640" height="428" /></a><p class="wp-caption-text">Digilent Cora Z7 FPGA board with a custom PMOD board to interface the FPGA to the iColor Flex strings.</p></div>
<p>The final step was to try my own implementation of the protocol against some of the iColor Flex light strings I own. I decided to use a Digilent Cora Z7 FPGA board and to build my own PMOD interface board to connect to the light strings. The interface board passes a DC power supply voltage to the light strings and contains a 3.3 V to 5 V level translator IC to convert the FPGA&#8217;s 3.3 V output to a 5 V data output for the light strings. It has a pair of AMP four-pin connectors so that up to two light strings may be connected at once.</p>
<h3>Verilog</h3>
<p>The protocol is implemented in two Verilog RTL modules. Both modules run at 10 MHz. The first module generates an enable at the baud rate of 1/2.2e-6 bits per second and encodes zeros and ones into the data encoding used by the light strings.</p>
<pre>module ckca_encode
(
    input    wire            clk,
    input    wire            rst,
    output    reg                baudEn,
    input    wire            txd,
    output    reg             dout
);

    reg [4:0] encodeCount;

    always @ (posedge clk)
    begin
        if (rst)
        begin
            baudEn &lt;= 0;
            dout &lt;= 1;
            encodeCount &lt;= 0;
        end
        else
        begin
            baudEn &lt;= (encodeCount == 20);

            if (encodeCount == 21)
            begin
                encodeCount &lt;= 0;
                dout &lt;= 1;
            end
            else
            begin
                encodeCount &lt;= encodeCount + 1;
                if ((encodeCount == 5) &amp;&amp; (txd == 0))
                begin
                    dout &lt;= 0;
                end
                else if ((encodeCount == 15) &amp;&amp; (txd == 1))
                begin
                    dout &lt;= 0;
                end
            end
        end
    end

endmodule</pre>
<p>The second module is a funky UART that can send either 20 or 21 bits based on a flag in the input data word. Input data words come from a FIFO connected to the FPGA&#8217;s AXI4-Lite bus and internal ARM CPU. Bit[12] of the data word is the 20/21 bit flag. Bits[11:0] of the data word are the data to transmit and are positioned within the 20/21 bits sent to the ckca_encode module. The bits are sent to the ckca_module at the baud rate using the enable generated by that module.</p>
<pre>module ckca_uart
(
    input    wire            clk,                // system clock
    input    wire            rst,                // synchronous, active-high system reset
    input    wire            baudEn,                // enable at baud rate
    input    wire            avail,                // new data byte to transmit available
    input    wire    [12:0]    data,                // 20/21b flag + 12 data bits
    output    reg                ack,                // data byte moved to transmit hold register
    output    reg                txd                    // transmit data out
);

localparam TXIDLE = 0, TXBRK = 1, TXMAB = 2, TXDAT = 3;

reg  [1:0] txbusy;                                // transmit state
reg  [4:0] bitnum;                                // current tx bit number
reg  [4:0] txbits;                                // number of bits to transmit minus one
reg    [19:0] txdata;                                // tranmsit data hold register

always @ (posedge clk)
begin
    if (rst)
    begin
        ack &lt;= 0;
        txd &lt;= 0;
        txbusy &lt;= 0;
        bitnum &lt;= 0;
        txbits &lt;= 0;
        txdata &lt;= 0;
    end
    else
    begin
        ack &lt;= 0;

        if (baudEn)
        begin
            case (txbusy)

                TXIDLE: begin
                    if (avail)
                    begin
                        ack &lt;= 1;
                        txd &lt;= 1;
                        txbusy &lt;= TXDAT;
                        bitnum &lt;= 0;
                        txbits &lt;= data[12] ? 20 : 19;
                        txdata &lt;= { 8'h00, data[11:0] };
                    end
                    else
                    begin
                        txd &lt;= 0;
                        bitnum &lt;= 0;
                        txbusy &lt;= TXIDLE;
                    end
                end

                TXDAT: begin
                    if (bitnum &gt;= txbits)
                    begin
                        if (avail)
                        begin
                            ack &lt;= 1;
                            txd &lt;= 1;
                            txbusy &lt;= TXDAT;
                            bitnum &lt;= 0;
                            txbits &lt;= data[12] ? 20 : 19;
                            txdata &lt;= { 8'h00, data[11:0] };
                        end
                        else
                        begin
                            txd &lt;= 0;
                            bitnum &lt;= 0;
                            txbusy &lt;= TXIDLE;
                        end
                    end
                    else
                    begin
                        txd &lt;= txdata[0];
                        txdata &lt;= { 1'b0, txdata[19:1] };
                        bitnum &lt;= bitnum + 1;
                    end
                end
        
            endcase
        end
    end
end

endmodule</pre>
<p>These two modules are instantiated inside a wrapper along with a FIFO and AXI4-Lite interface and connected to the Zynq FPGA&#8217;s ARM core using Vivado&#8217;s IP integrator.</p>
<div id="attachment_1822" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/vivado-block-diagram1.png"><img class="size-large wp-image-1822" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/vivado-block-diagram1-1024x668.png" alt="Two instances of my implementation of the protocol in the Vivado IP Integrator." width="640" height="418" /></a><p class="wp-caption-text">Two instances of my implementation of the protocol in the Vivado IP Integrator.</p></div>
<h3>Software</h3>
<p>Some quick software was written using the Xilinx SDK IDE to have 6 colors chase down a string of 10 nodes.</p>
<pre>// includes
#include "platform.h"
#include "xgpio.h"
#include "xil_printf.h"
#include "xparameters.h"

// short cuts 
#define CKCA0_TIMEBASE_VALUE_REG    (XPAR_CKCA_WRAPPER_0_BASEADDR + 0x10)
#define CKCA0_TIMEBASE_FLAG_REG     (XPAR_CKCA_WRAPPER_0_BASEADDR + 0x14)
#define CKCA0_FIFO_DATA_REG         (XPAR_CKCA_WRAPPER_0_BASEADDR + 0x18)

// color table
static const uint16_t colors[6][3] = {
    { 0x0FFE, 0x0000, 0x1000 }, // RED
    { 0x0FFE, 0x0FFE, 0x1000 }, // YELLOW
    { 0x0000, 0x0FFE, 0x1000 }, // GREEN
    { 0x0000, 0x0FFE, 0x1FFE }, // CYAN
    { 0x0000, 0x0000, 0x1FFE }, // BLUE
    { 0x0FFE, 0x0000, 0x1FFE }  // PURPLE
};

// main
int main()
{
    XGpio gpio;

    init_platform ();
    XGpio_Initialize(&amp;gpio, 0);
    XGpio_SetDataDirection(&amp;gpio, 2, 0x00000000); // set LED GPIO channel tristates to All Output
    XGpio_SetDataDirection(&amp;gpio, 1, 0xFFFFFFFF); // set BTN GPIO channel tristates to All Input

    int timer = 0;
    int color = 0;
    int j, k;

    while (1) {
        if (Xil_In32 (CKCA0_TIMEBASE_FLAG_REG) &amp; 0x1) {
            Xil_Out32 (CKCA0_TIMEBASE_FLAG_REG, 0x1);
            xil_printf (".");

            timer++;
            if (timer &gt;= 20) {
                timer = 0;

                // send start code
                Xil_Out32 (CKCA0_FIFO_DATA_REG, 0x1FFF);

                // cycle through colors
                k = color;
                for (j = 0; j &lt; 10; j++) {
                    Xil_Out32 (CKCA0_FIFO_DATA_REG, colors[k][0]);
                    Xil_Out32 (CKCA0_FIFO_DATA_REG, colors[k][1]);
                    Xil_Out32 (CKCA0_FIFO_DATA_REG, colors[k][2]);
                    if (++k &gt; 5) {
                        k = 0;
                    }
                }

                // send six empty nodes of data to push data through last nodes
                for (j = 0; j &lt; 6; j++) {
                    Xil_Out32 (CKCA0_FIFO_DATA_REG, 0x0000);
                    Xil_Out32 (CKCA0_FIFO_DATA_REG, 0x0000);
                    Xil_Out32 (CKCA0_FIFO_DATA_REG, 0x1000);
                }

                if (--color &lt; 0) {
                    color = 5;
                }
            }
        }
    }

    return 0;
}</pre>
<h3> Trying It All Out</h3>
<p>Here&#8217;s the result with a string of 10 iColor Flex MX nodes:</p>
<p><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/success-mx.jpg"><img class="alignnone size-large wp-image-1825" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/success-mx-1024x638.jpg" alt="success-mx" width="640" height="399" /></a></p>
<p>Here&#8217;s the result with a string of 6 iColor Flex MX gen 2 nodes:</p>
<p><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/success-mx-gen2.jpg"><img class="alignnone size-large wp-image-1826" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/success-mx-gen2-1024x584.jpg" alt="success-mx-gen2" width="640" height="365" /></a></p>
<p>Here&#8217;s the result with a string of 10 iColor Flex LMX nodes:</p>
<p><a href="https://bikerglen.com/wp/wp-content/uploads/2019/11/success-lmx.jpg"><img class="alignnone size-large wp-image-1827" src="https://bikerglen.com/wp/wp-content/uploads/2019/11/success-lmx-1024x576.jpg" alt="success-lmx" width="640" height="360" /></a></p>
<h2>Conclusion</h2>
<p>I successfully reverse engineered the protocol used to control iColor Flex string lights based on their Chromasic chip and Chromasic protocol. After reverse engineering the protocol, I built a small circuit board and FPGA to implement the protocol and control a few different types of light strings.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/reverse-engineering-the-icolor-flex-protocol/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Homebrew DMX-Controlled RGB LED Light</title>
		<link>https://bikerglen.com/blog/homebrew-rgb-led-light/</link>
		<comments>https://bikerglen.com/blog/homebrew-rgb-led-light/#comments</comments>
		<pubDate>Sat, 13 Apr 2019 01:28:29 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[DMX / Art-Net]]></category>
		<category><![CDATA[Fusion 360]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[PIC24]]></category>
		<category><![CDATA[RGB LED]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=1041</guid>
		<description><![CDATA[This project is a small DMX-512 controlled, color-changing RGB LED light. The light can be controlled via the DMX512 protocol or it can run a number of built-in programs depending on how the software is configured. The light incorporates an &#8230; <a href="https://bikerglen.com/blog/homebrew-rgb-led-light/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_1052" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190324_102016_cover_photo.jpg"><img class="wp-image-1052 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190324_102016_cover_photo-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">Assembled homebrew DMX-controlled RGB LED light fixture.</p></div>
<p>This project is a small DMX-512 controlled, color-changing RGB LED light. The light can be controlled via the DMX512 protocol or it can run a number of built-in programs depending on how the software is configured. The light incorporates an advanced 16-bit PIC24 microcontroller with PWM capabilities, a 3D printed enclosure, a laser cut acrylic lid, a custom switching power supply, and a MEMS oscillator. The light measures roughly 2.25&#8243; square by 1.25&#8243; high. This light is the evolution of my RGB LED light designs that span back over a decade.</p>
<p><span id="more-1041"></span></p>
<p>(This next section is long. If you want to skip the history of how this design came to be and go directly to a description of the design instead, click <a href="#hardware-design">here</a>.)</p>
<h2>Early RGB LED Light Designs</h2>
<p>The biggest influence on these RGB LED light designs has been the introduction of low-cost PCB manufacturers that cater to hobbyists and the introduction of affordable 3D printing.</p>
<h3>Mechanical Form Factors</h3>
<p>Early low-cost PCB manufacturing services such as those from ExpressPCB offered a <a href="https://www.expresspcb.com/miniboardplus-standard/">fixed-sized board with two layers and no solder masks for a low cost</a>. As a result, the board designs used through-hole components, were limited  to the sizes made available by the board house unless you wanted to pay a ton extra, and you were lucky to find an interesting enclosure that would hold your board. The free PCB layout tools of the time were a bit limited too but they worked well enough for simple boards.</p>
<p>The photo below shows one of my designs from the early 2000s. The board is about 3&#8243; by 2&#8243;, has through-hole components only, uses a <a href="https://www.microchip.com/wwwproducts/en/PIC16F688">PIC16F688 microcontroller</a>, and uses a linear regulator to step 24V down to 5V for the microcontroller. The linear regulator is not very efficient and runs hot to the touch. The ice cube enclosure is an Ikea lamp they sold in the early 2000s. I made a ton of these as gifts for family and friends.</p>
<p>If you&#8217;re interested in making a color changing lamp of your own, Ikea has tons of low-cost lamps that are extremely suitable to retrofitting with your own RGB LEDs and electronics.</p>
<div id="attachment_1064" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00750.jpg"><img class="wp-image-1064 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00750-1024x683.jpg" alt="DSC00750" width="640" height="427" /></a><p class="wp-caption-text">An RGB LED color changing light design of mine from the early 2000s. The circuit board was manufactured by ExpressPCB and it&#8217;s powered by a PIC16F688 microcontroller. The entire assembly was retrofitted into an ice cube lamp from Ikea.</p></div>
<h3>The Early Electronics</h3>
<p>Below is a close-up of the board from the ice cube lamp. There&#8217;s a microcontroller to control the LEDs, a Maxim part for receiving DMX, an oscillator, a linear regulator, and a transistor switch.</p>
<p><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00745.jpg"><img class="alignnone size-large wp-image-1065" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00745-1024x683.jpg" alt="DSC00745" width="640" height="427" /></a></p>
<p>The microcontroller is a <a href="https://www.microchip.com/wwwproducts/en/PIC16F688">Microchip PIC16F688</a>. The code for this microcontroller was written in assembly. PWM was initially implemented in the main loop of the code. These lights could only cycle through a serious of colors. Later PWM was implemented in an interrupt service routine (ISR). Once PWM was in the ISR, the main loop of the code was reworked to receive DMX. Now these lights could cycle through a series of colors or be controlled via DMX.</p>
<p>The worst part of these lights was there was no provision for in-circuit programming or debugging. The PIC16F688 supported in-circuit programming but I didn&#8217;t have room on the board for the connector. Updating the software required removing the PIC from the board, placing it in a dedicated programming fixture, re-programming the part, then placing the PIC back in the socket. For in-circuit debugging, a special bond out version of the chip had to be used.</p>
<h2>Technology Evolves—Custom Boards and Better CPUs</h2>
<div id="attachment_1067" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00770.jpg"><img class="wp-image-1067 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00770-1024x683.jpg" alt="DSC00770" width="640" height="427" /></a><p class="wp-caption-text">RGB LED lighting controller based on a PIC18F1320 microcontroller. Custom board size with solder masks but still using all through-hole components. This module drove a board of LEDs located in a lamp too small to hold both the LED board and driver electronics.</p></div>
<h3>Custom Boards</h3>
<p>In the late 2000s, SparkFun launched a low-cost PCB manufacturing service called BatchPCB. Pricing was $2.50 per square inch plus shipping. The service offered two layer boards with solder masks and silkscreens. They supported custom-sized boards and would even cut to a custom outline if provided. At the same time, Eagle CAD launched a free hobbyist version of their schematic capture and PCB layout tools.</p>
<p>These two developments suddenly allowed hobbyists to make their own high-quality custom boards of any shape and size. I took full advantage of the situation and made several new RGB LED lamps. Many of these boards were either round or designed to fit in extruded aluminum enclosures like the one in the photo above. The green boards on this blog post were all made at BatchPCB.</p>
<p>In 2010, DorkbotPDX launched a similar PCB batching service and opened it up to the general public. Hobbyists now had two different board services catering to small orders. DorkbotPDX eventually became <a href="https://oshpark.com/">oshpark.com</a> then in <a href="https://www.sparkfun.com/news/1138">2013 SparkFun shut down Batch PCB and referred users to OSHPark</a>. In June 2016, Autodesk purchased Eagle PCB. A free version of <a href="https://www.autodesk.com/products/eagle/free-download">Eagle PCB</a> continues to exist but users looking to upgrade to larger board areas have to move to Autodesk&#8217;s controversial pay-as-you-go usage model. For users looking for non-commercial / open source PCB CAD tools, <a href="http://kicad-pcb.org/">KiCad</a> has made terrific strides in the past two years and is now a viable alternative to Eagle PCB.</p>
<h3>Better CPUs and Better Tools</h3>
<div id="attachment_1078" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00779.jpg"><img class="wp-image-1078 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00779-1024x683.jpg" alt="DSC00779" width="640" height="427" /></a><p class="wp-caption-text">RGB LED lamp based on a PIC18F1320 microcontroller. The PIC18 has supports in-circuit programming and debugger and has enough horsepower to do ISR-based dimming while receiving DMX-512 or commands from an IR remote control.</p></div>
<p>Around the same time as the hobbyist PCB revolution, I upgraded the microcontroller in my lights from a PIC16F688 to a PIC18F1320. The PIC18F1320 had a PC-based toolchain that included a free C compiler and debugger. Additional optimizations could be purchased for the compiler but the free version was good enough to dim the LEDs inside an interrupt service routine. No more assembly code! The PIC18F1320 also offered in-circuit programming and debugging capabilities. These two capabilities shaved tons of time off the software development process.</p>
<h3>Evolution of Software-Based Dimming</h3>
<p>Another change I made around this time frame was to move from <a href="https://en.wikipedia.org/wiki/Pulse-width_modulation">pulse width modulation</a> (PWM) dimming to <a href="https://en.wikipedia.org/wiki/Pulse-density_modulation">pulse density modulation </a>(PDM) dimming. In PWM dimming, the duty cycle of a fixed-frequency square wave varies from 0% to 100% to dim the LED from completely off to completely on. In PDM dimming, both the frequency and density of a series of pulses vary to dim the LED from completely off to completely on. See the figure below.</p>
<div id="attachment_1085" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/pwm-vs-pdm.png"><img class="wp-image-1085 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/pwm-vs-pdm-1024x608.png" alt="pwm-vs-pdm" width="640" height="380" /></a><p class="wp-caption-text">In PWM dimming, the duty cycle of a square wave varies in proportion to the commanded LED brightness. The frequency of the square wave is the frequency of the ISR timer divided by the resolution of the system. In PDM dimming, the pulse density varies in proportion to the commanded LED brightness. The maximum frequency of the pulses is the frequency of the ISR timer. PDM dimming can result in higher refresh rates and less flickering when recorded on video.</p></div>
<p>To implement PDM dimming in software a variable is used as an accumulator. At a fixed frequency inside an interrupt service routine, the commanded brightness level is added to the accumulator. If the accumulator rolls over, i.e., the carry bit is set after the add, the output pin is asserted. If the carry bit is clear, the output pin is deasserted. In some architectures, it&#8217;s possible to directly copy the carry value to the output pin without using any comparison or branch instructions.</p>
<p>In my implementation, the accumulator and commanded brightness are both 16 bit unsigned integers but only the lower 10 bits of the integers are used. If after an add the 11th bit is set, that&#8217;s considered a carry and the output pin is asserted. If not, the output pin is cleared. The 11th bit is then cleared in preparation for the next cycle of the algorithm. This is repeated for each of the red, green, and blue channels.</p>
<p>Here&#8217;s the code for the red channel:</p>
<pre>        // default to all LEDs off
        pwm_temp = 0;

        // process red LED
        pwm_red_counter += pwm_red_level;
        if (pwm_red_counter &gt;= 1024) {
            pwm_red_counter -= 1024;
            pwm_temp |= RED_LED_BIT;
        }

        // process remaining channels
        // ...

        // update port a
        LATA = pwm_temp;</pre>
<p>The use of 10-bit accumulators gives 1024 distinct levels of brightness. Using 1024 levels enables better <a href="https://learn.adafruit.com/led-tricks-gamma-correction/the-quick-fix">gamma correction</a> and thus better brightness resolution particularly at lower brightness levels.</p>
<h3>A Step Backwards for Free Compilers Necessitates the Move to Hardware PWM</h3>
<p>Up until this point, I had been using the Windows-only MPLAB IDE and the free version of the C18 compiler. The limited optimizations of the free C18 compiler were sufficient to move in and out of the dimming ISR quickly enough to leave spare CPU cycles available in the main loop of the code.</p>
<p>Sometime around 2010, Microchip released the MPLAB X IDE and their new XC8 compiler. These were both cross platform and ran on Windows, Mac, and Linux. This was great. We could use the development tools wherever we wanted. Unfortunately the free version of the XC8 compiler had poorer performance when entering and exiting interrupts than the C18 compiler.</p>
<p>This resulted in the PIC18F1320 spending almost 100% of its time inside the ISR and as a result my ISR-based software dimming routines no longer functioned. This necessitated an upgrade to a PIC24 microcontroller with PWM done in hardware. With a PIC24 and PWM hardware, the performance of the compiler and the ISR entry/exit routines was no longer critical.</p>
<p>As a side note, in late 2018, I did break down and purchase the pro version of the XC8 compiler but at $1000 it&#8217;s out of reach for most hobbyists. In addition to the generated code running faster, the generated code is smaller. The pro version of the compiler is thus useful for compiling space constrained applications such as USB bootloaders and the Ethernet code included with their PoE eval board too.</p>
<h2>Some PIC Micros Have Hardware PWM!</h2>
<p>To take my RGB lights to the next level, I needed a better microcontroller that included hardware PWM features. Fortunately, Microchip has the Microchip Advanced Part Selector or <a href="https://www.microchip.com/maps/Microcontroller.aspx">MAPS tool</a>. This online tool lets you perform a parametric search through all their available devices to find devices that meet your needs.</p>
<p>The basic requirements were a PIC24 with at least 3 PWM channels and sufficient memory to not worry about the limitations of the free compiler. One additional requirement was the availability of a low-cost development board that would permit programming and testing of the PWM peripheral without having to build my own boards.</p>
<p>After some searching I found my part, the <a href="https://www.microchip.com/wwwproducts/en/PIC24EP128MC202">PIC24EP128MC202</a><a href="https://www.microchip.com/wwwproducts/en/PIC24HJ128GP202">,</a> and development board, the <a href="https://www.microchip.com/Developmenttools/ProductDetails/DM330013-2">Microstick II</a>. The PIC24EP128MC202 has three channels of hardware-based 16-bit PWM. Within an hour of receiving the development board and microcontroller, I had the basic PWM functionality working. Time to design some boards.</p>
<h3>The 6&#8243; Strip with 16-bit PWM Dimming and Gamma Correction</h3>
<div id="attachment_792" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2017/12/DSC00555_2048w.jpg"><img class="size-large wp-image-792" src="https://bikerglen.com/wp/wp-content/uploads/2017/12/DSC00555_2048w-1024x683.jpg" alt="PIC24-based RGB LED Strips. Each strip is 152.4mm long and contains six of each color of LED." width="640" height="427" /></a><p class="wp-caption-text">PIC24-based RGB LED Strips. Each strip is 152.4mm long and contains six of each color of LED.</p></div>
<p>The first RGB LED lamp design to use the PIC24EP128MC202 was a six-inch strip light. The strip light used six each of 3528 red, green, and blue surface mount LEDs. The board also featured slots that snapped into 3D printed tilted stands. The board was powered by 24V and had DMX control.</p>
<h3>DIN Rail Mount</h3>
<p><a href="https://bikerglen.com/wp/wp-content/uploads/2017/12/DSC00565_2048w.jpg"><img class="alignnone size-large wp-image-796" src="https://bikerglen.com/wp/wp-content/uploads/2017/12/DSC00565_2048w-1024x683.jpg" alt="DSC00565_2048w" width="640" height="427" /></a></p>
<p>The second iteration of the PIC24EP128MC202-based RGB LED controller was designed to control LED strips for my <a href="https://www.youtube.com/watch?v=5HJUm69fgeg">crate beast Halloween prop</a>. The requirements for this controller were that it be able to drive a few feet of LED strips and had a DIN-rail mount form factor so that it could be mounted beside the PLC that controlled the operation of the prop. This necessitated moving to large MOSFET power transistors instead of the smaller BJT transistors used on the strip version. Also, all I/O was placed on pluggable terminal blocks to facilitate quick repairs should they be required.</p>
<h3>Round v1</h3>
<p><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00753_crop.jpg"><img class="alignnone size-large wp-image-1063" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/DSC00753_crop-1024x683.jpg" alt="DSC00753_crop" width="640" height="427" /></a></p>
<p>The next iteration was a 2&#8243; round version of the six inch strip light. The electronics were placed on one board, the LEDs were placed on a second board, and the two boards connected together using some header strips and header pins. The electronics board contained slots that snapped into a mounting bracket. This permitted the board to lay flat or be taped or screwed in place. There were still some minor annoyances like not having a case, the power supply hit the bottom of the LED board, and the oscillator and low ESR caps are huge.</p>
<h3>Round v2</h3>
<p>That brings us to the latest version of the RGB LED lamp. The basic requirements were:</p>
<ul>
<li>The lamp is completely enclosed.</li>
<li>The lamp uses a low-profile switching power supply.</li>
<li>The lamp uses a small oscillator.</li>
<li>The lamp uses a small and inexpensive low-ESR cap for the PIC24.</li>
</ul>
<p>Other than the above, I liked the round form factor, software, and basic functionality of the first round version.</p>
<h2 id="hardware-design">Hardware Design</h2>
<div id="attachment_1055" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20181128_103851.jpg"><img class="size-large wp-image-1055" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20181128_103851-1024x576.jpg" alt="This board has a lot of experiments including a MEMS oscillator, a custom switching power supply, and a new low-ESR capacitor for the PIC24's Vcap pin." width="640" height="360" /></a><p class="wp-caption-text">This board has a lot of experiments including a MEMS oscillator, a custom switching power supply, and a new low-ESR capacitor for the PIC24&#8217;s Vcap pin.</p></div>
<p>This design had lots of new things to try out: a new power supply, a new oscillator, a new capacitor, and a new enclosure with an overlapping lip designed to compensate for tolerances in the vertical stack up of the assembly.</p>
<h3>Selecting a PIC24 Variant</h3>
<p>Picking a PIC24 was easy. The design would use the same PIC24EP128MC202 that the previous three iterations used. Below is a schematic showing the basic connections for the PIC24. To this basic schematic, we&#8217;ll add a switching power supply, a 10 MHz MEMS oscillator, DMX transmit and receive capability, and some transistor switches that control the LEDs.</p>
<div id="attachment_1098" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/1.png"><img class="size-large wp-image-1098" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/1-1024x764.png" alt="Basic PIC24 connections." width="640" height="478" /></a><p class="wp-caption-text">Basic PIC24 connections.</p></div>
<h3>Low ESR Cap Selection</h3>
<p>One of the goals for this project was to use a smaller and less expensive low-ESR cap on the PIC24&#8217;s VCAP/VDDCORE pin. Here&#8217;s the requirements according to the PIC24EP128MC202 data sheet:</p>
<p style="padding-left: 30px;">A low-ESR (&lt; 1 Ohm) capacitor is required on the VCAP pin, which is used to stabilize the voltage regulator output voltage. The VCAP pin must not be connected to VDD and must have a capacitor greater than 4.7 μF (10 μF is recommended), 16V connected to ground. The type can be ceramic or tantalum.</p>
<p>After perusing capacitor data sheets for over an hour, I finally settled on a TDK part that had &lt; 1 Ohm ESR at all frequencies between 10kHz and 100MHz. The TDK <a href="https://product.tdk.com/info/en/documents/chara_sheet/CGA5L1X7R1C106M160AC.pdf">CGA5L1X7R1C106M160AC</a> capacitor is a 10uF +/- 20% ceramic capacitor with an X7R temperature characteristic, a rating of 16V, a 1206 package, and best of all, a price of about fifty cents in small quantities. The previous low ESR cap was huge and over three dollars.</p>
<h3>TI Simple Switcher Buck Converter</h3>
<p>Another goal for this project was to use a lower-profile switching power supply capable of stepping the input +24V power supply voltage down to +3.3V for the PIC24 microcontroller and other digital logic. I had been using a Cui V7803-500 high-efficiency switching drop-in linear regulator replacement on the previous designs. This part is very tall and causes interference when mating the LED board to the logic board. I needed something shorter.</p>
<div id="attachment_1100" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/2.png"><img class="size-large wp-image-1100" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/2-1024x764.png" alt="TI Simple Switcher schematic." width="640" height="478" /></a><p class="wp-caption-text">TI Simple Switcher schematic.</p></div>
<p>TI has a series of high input voltage step down switching regulators called <a href="http://www.ti.com/power-management/non-isolated-dc-dc-switching-regulators/step-down-buck/buck-converter-integrated-switch/simple-switcher.html">TI Simple Switchers</a>. These are easy to use and require minimum external support components. I selected one of these then used their reference design schematic and PCB layout to recreate the circuit and layout on my project.</p>
<p>The schematic for the switching power supply is shown in the schematic above. Also on this schematic page are decoupling capacitors for all the digital circuitry and the power / data input connector. This power supply circuit has plenty of vertical clearance. Unfortunately as built, it occupies more board real estate than the CUI device.</p>
<h3>SiTime MEMS Oscillator</h3>
<p>To make room for the new switching power supply, I needed a smaller oscillator. Most small crystal oscillators are in leadless packages that are hard to solder. While I was working on this project, news broke about high helium atmospheres crashing iPhones. The root cause was helium penetrating the MEMS oscillator used in the iPhone and changing the oscillator&#8217;s frequency. I did a bit more research and discovered a company called <a href="https://www.sitime.com/">SiTime</a> that makes a wide range of MEMS oscillators.</p>
<p>Digging further, they had a <a href="https://www.sitime.com/products/automotive-high-temp-oscillators/sit2024">3.3V version in a tiny, easy-to-solder SOT23-5 package</a> that could be programmed to run at 10MHz. Even better, Digi-Key sells them and will program them to your requested frequency. The exact manufacturer part number is <a href="https://www.digikey.com/product-detail/en/sitime/SIT2024BETS-33N/SIT2024BETS-33N-ND/7422259">SIT2024BETS-33N</a> and the Digi-Key part number is <a href="https://www.digikey.com/product-detail/en/sitime/SIT2024BETS-33N/SIT2024BETS-33N-ND/7422259">SIT2024BETS-33N-ND</a>. Just add one to your cart and specify the programming frequency in the order notes. As shown in the schematic below, they&#8217;re pretty easy to use too. Just add a decoupling capacitor and tie the output enable pin high.</p>
<p><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/3.png"><img class="alignnone size-large wp-image-1104" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/3-1024x764.png" alt="3" width="640" height="478" /></a></p>
<h3> Receiving DMX</h3>
<p>The hardware for transmitting and receiving the DMX protocol is remarkably simple. If you want to spend a lot of money you can use isolated RS-485 transceivers. I&#8217;d already spent enough on this project so I used a <a href="http://www.ti.com/product/SN65HVD11">TI SN65HVD11D</a> as shown in the schematic below. Hook up the D- and D+ lines to the DMX connector. Hook up the data in, data out, and direction lines to the microcontroller. At some point, I need to figure out an ESD protection circuit for the DMX D+ and D- signals.</p>
<div id="attachment_1103" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/4.png"><img class="size-large wp-image-1103" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/4-1024x764.png" alt="DMX transmit / receive circuitry. This could use some ESD protection in a future version." width="640" height="478" /></a><p class="wp-caption-text">DMX transmit / receive circuitry. This could use some ESD protection in a future version.</p></div>
<h3>Transistor Switches</h3>
<p>I&#8217;ve been using FMMT619TA NPN BJT transistors to switch the strings of RGB LEDs on and off for what feels like forever now. There was no reason to change now. These are in a tiny SOT-23 package. They&#8217;re rated for 2A. They can easily switch on and off the 40mA of LED strings without getting hot or requiring heat sinks. A 1k resistor connected between each of the PIC&#8217;s PWM outputs and each transistor&#8217;s base limits the base current to prevent destruction of the transistor while also supplying enough base current to drive the transistor into its saturation region.</p>
<div id="attachment_1105" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/5.png"><img class="wp-image-1105 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/5-1024x764.png" alt="5" width="640" height="478" /></a><p class="wp-caption-text">NPN BJT transistors used to switch the LEDs on and off.</p></div>
<h3>Completed Schematic</h3>
<p>Below is the completed schematic for the RGB lamp&#8217;s controller board.</p>
<div id="attachment_1109" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/6.png"><img class="wp-image-1109 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/6-1024x796.png" alt="6" width="640" height="498" /></a><p class="wp-caption-text">Completed schematic.</p></div>
<h3>Board Layout</h3>
<p>Now that the schematic was complete, it was time to move on to the board layout. I drew the initial board outline as a sketch in Fusion 360. I exported the sketch as a DXF file then imported the DXF file on to layer 20, the dimension layer, in Eagle PCB. A few of the arcs and lines had to be touched up by hand to get the board outline to be a completely closed shape.</p>
<div id="attachment_1117" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/pcb-layout.png"><img class="wp-image-1117 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/pcb-layout-979x1024.png" alt="pcb-layout" width="640" height="669" /></a><p class="wp-caption-text">Completed board layout.</p></div>
<p>Components are arranged similarly to how they are on the first version of the round PCB RGB LED lamp. The power supply layout is copied from the TI Simple Switcher evaluation board. The power transistors that switch the LEDs on and off are on the back of the board. The top layer includes a +3.3V power fill. The bottom layer includes a ground fill. A second ground fill was included on the top layer directly underneath the switching power supply. This ground fill is heavily coupled to the bottom layer ground fill using tons of vias.</p>
<div id="attachment_1115" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/controller.png"><img class="wp-image-1115 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/controller-1024x500.png" alt="controller" width="640" height="313" /></a><p class="wp-caption-text">Oshpark board renders.</p></div>
<p>The final step in the board design process was to upload the board&#8217;s gerber files to Oshpark and check the renders for any final mistakes. This is where problems with the silk screen like incorrectly mirrored or overlapping text become apparent. Finally I ordered boards and assembled them when they arrived. Below is a photo of both sides of the assembled board.</p>
<div id="attachment_1130" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/stuffed-board.jpg"><img class="size-large wp-image-1130" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/stuffed-board-1024x512.jpg" alt="The completed board. Probably should get some isopropyl alchohol and clean it up a better sometime." width="640" height="320" /></a><p class="wp-caption-text">The completed board. Probably should get some isopropyl alchohol and clean it up a better sometime.</p></div>
<h3>The LED Board</h3>
<p>The LED board was simple in comparison to the controller board. It&#8217;s just a bunch of through hole LEDs, resistors, and terminal strips. The LEDs are arranged in a pair of red LED strings, a pair of green LED strings, and a pair of blue LED strings. Each red string uses 7 LEDs and each green and blue string use 5 LEDs. The resistors were chosen to limit the current to each string of LEDs to 15 mA.</p>
<p>Here&#8217;s the schematic. I have no idea if those CREE part numbers are good or not anymore. They&#8217;re several years old. I used LEDs from my parts stock. Sometime I&#8217;ll have to look up the exact part number I used and add them to this post.</p>
<div id="attachment_1131" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/led-board-sch.png"><img class="size-large wp-image-1131" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/led-board-sch-1024x764.png" alt="Led board schematic." width="640" height="478" /></a><p class="wp-caption-text">Led board schematic.</p></div>
<p>Here&#8217;s the Oshpark render:</p>
<div id="attachment_1116" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/led-board.png"><img class="wp-image-1116 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/led-board-1024x500.png" alt="led-board" width="640" height="313" /></a><p class="wp-caption-text">Oshpark render of the LED board.</p></div>
<p>And here&#8217;s a photo of both sides of the assembled LED board.</p>
<div id="attachment_1133" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/led-board.jpg"><img class="size-large wp-image-1133" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/led-board-1024x512.jpg" alt="The assembled LED board. Guess which LEDs are red." width="640" height="320" /></a><p class="wp-caption-text">The assembled LED board. Guess which LEDs are red.</p></div>
<h2>Mechanical Design</h2>
<div id="attachment_1054" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20181128_105508.jpg"><img class="size-large wp-image-1054" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20181128_105508-1024x576.jpg" alt="This build had two circuit boards, a 3D printed enclosure, a laser cut acrylic lid, and numerous screws and standoffs." width="640" height="360" /></a><p class="wp-caption-text">This build had two circuit boards, a 3D printed enclosure, a laser cut acrylic lid, and numerous screws and standoffs that all had to come together and function as a single unit.</p></div>
<p>This build was one of my more complicated mechanical designs as well. The enclosure needed to hold two circuit boards and a lens. It also had to have a cutout for the power / data connector. The vertical stackup had lots of tolerances yet the enclosure still needed to fit together tightly regardless of the actual dimensions of the parts used. I also planned on using a relatively new 3D printing process and material.</p>
<h3>Material</h3>
<p>Most of my 3D printing experience is with nylon printed on Electro Optical System&#8217;s line of selective laser sintering (SLS) printers. Around the time of this project, HP released their line of <a href="https://www8.hp.com/us/en/printers/3d-printers.html">HP Multi Jet Fusion 3D printers</a>. The service bureau I normally use for 3D prints, <a href="https://www.sculpteo.com/en/">Sculpteo</a>, was making a big push to popularize HP&#8217;s Jet Fusion process and get users to try out the new material. I figured I&#8217;d give it a try.</p>
<p>Sculpteo has a <a href="https://www.sculpteo.com/blog/2017/08/22/plastic-3d-printing-technologies-hp-multi-jet-fusion-vs-sls/">comparison</a> of the EOS&#8217;s SLS and the HP Jet Fusion technology. The design rules for both printers are very similar and I don&#8217;t tend to push the design rules with either technology. This means that what I print on one printer will usually print on the other printer without issues. Generally, the thinnest printable feature is 0.7mm thick and a thickness of 1.5mm to 2.0mm works well for walls.</p>
<p>The biggest differences between the two printers for me are the accuracy of the parts, the stiffness of the material, and the color options. The Jet Fusion prints have better accuracy and are slightly stiffer / less flexible than the EOS SLS parts.</p>
<div id="attachment_1135" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/plastics.jpg"><img class="size-large wp-image-1135" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/plastics-1024x682.jpg" alt="Two project enclosures printed on HP Jet Fusion 3D printers. One is the raw finish. The other is dyed black." width="640" height="426" /></a><p class="wp-caption-text">Two project enclosures printed on HP Jet Fusion 3D printers. One is the raw finish. The other is dyed black.</p></div>
<p>On the downside, Jet Fusion prints have less finishing options than EOS SLS parts. The EOS SLS PA12 nylon is white. This permits finished parts to be dyed just about any color. The Jet Fusion nylon is a dark gray. The only real color options are the raw dark gray, which is what I used on this project, and dyed black. Above is a photo of two different projects in the raw finish and the dyed black finish.</p>
<h3>Enclosure Bottom</h3>
<p>The enclosure bottom was designed to hold the PCB by the four tabs extending out from the central circular part of the board. These tabs fit in four recesses in the enclosure bottom and hold the board TODO mm above bottom of the enclosure. This allows room for small surface mount components like resistors, capacitors, and SOT23 transistors to be mounted on the bottom of the board.</p>
<p>The cavities that hold the tabs and board are 1.65mm deep to hold the 1.6mm thick board. The clearance between the board and all edges of the interior of the enclosure is 0.5mm. On the underside of the enclosure are four recesses to hold 2-56 pan head hex drive screws.</p>
<p>Here&#8217;s a render of the bottom half of the enclosure as viewed from the top:</p>
<div id="attachment_1139" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/bottom-top.png"><img class="wp-image-1139 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/bottom-top-1024x690.png" alt="bottom top" width="640" height="431" /></a><p class="wp-caption-text">Render of the bottom half of the enclosure as viewed from the top.</p></div>
<p>Here&#8217;s a render of the bottom half of the enclosure as viewed from the bottom:</p>
<div id="attachment_1140" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/bottom-bottom.png"><img class="wp-image-1140 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/bottom-bottom-1024x690.png" alt="bottom-bottom " width="640" height="431" /></a><p class="wp-caption-text">Render of the bottom half of the enclosure as viewed from the bottom.</p></div>
<h3>Enclosure Top</h3>
<p>The enclosure top rests on the enclosure bottom and hold the circuit board in place. It is tall enough to hold both boards with some clearance between the top of the LEDs and the bottom of the lid. Here&#8217;s a render of the top half of the enclosure as viewed from the top:</p>
<div id="attachment_1141" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/top-top.png"><img class="wp-image-1141 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/top-top-1024x690.png" alt="top-top" width="640" height="431" /></a><p class="wp-caption-text">Render of the top half of the enclosure as viewed from the top.</p></div>
<p>Here&#8217;s a render of the top half of the enclosure as viewed from the bottom:</p>
<div id="attachment_1142" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/top-bottom.png"><img class="wp-image-1142 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/top-bottom-1024x690.png" alt="top-bottom" width="640" height="431" /></a><p class="wp-caption-text">Render of the top half of the enclosure as viewed from the bottom.</p></div>
<h3>Connector Cutout</h3>
<p>To create the cutout for the connector, I used the Fusion 360 construction, sketch, and extrude commands. The first step was to use the construction tools to create four planes each offset from the sides of the connector by 0.25mm. The photo below shows the constructed planes:</p>
<div id="attachment_1143" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/construction.png"><img class="wp-image-1143 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/construction-1024x690.png" alt="constructing connector feedthrough" width="640" height="431" /></a><p class="wp-caption-text">Construction planes offset 0.25mm from the outside surfaces of the connector.</p></div>
<p>The next step was to create a new sketch on the bottom plane. This rectangle needed to be sized to cut away the portions of the enclosure around the connector. The left edge was at the left plane. The right edge was at the right plane. The front extended just beyond the enclosure front. The rear extended just beyond the inside wall of the enclosure.</p>
<p>Once the rectangle was sketched, I exited the sketch and used the extrude command to cut both halves of the enclosure. The extrusion height ran from the bottom plane to the top plane and the mode was set to cut:</p>
<div id="attachment_1144" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/extrude-up.png"><img class="wp-image-1144 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/extrude-up-1024x731.png" alt="the cut operation" width="640" height="457" /></a><p class="wp-caption-text">The extrude and cut operation.</p></div>
<p>This left me with a hole perfectly sized for the power / data connector.</p>
<h3>Compensating for Vertical Tolerances</h3>
<p>The vertical stackup has a lot of different components with varying tolerances. A solution was needed to ensure the enclosure halves fit together snug regardless of the individual component tolerances. The solution was to create overlapping lips on each half of the enclosure. If the vertical stackup came up short, the enclosure halves would rest on each other. If the vertical stackup came up tall, the lip would still fill the gap between the enclosure halves even if they didn&#8217;t directly rest on each other. Circled in red below is the lip that runs all the way around both halves of the enclosure.</p>
<div id="attachment_1138" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/Holder-02-v6-2.jpg"><img class="wp-image-1138 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/Holder-02-v6-2-1024x690.jpg" alt="Holder 02 v6 2" width="640" height="431" /></a><p class="wp-caption-text">Circled in red is the lip that runs all the way around both halves of the enclosure.</p></div>
<p>On the bottom half of the enclosure, the lip wall is 0.7mm thick and runs along the outside surface of the enclosure. It&#8217;s 1mm tall. On the top half of the enclosure, the lip is 0.8mm thick and extends 0.25mm into the inside of the enclosure. The clearance between the two lip walls when assembled is 0.25mm. On the top half of the enclosure, the overall lip height is 2mm. That is divided into two portions each with a height of 1mm. The lower portion mates with the lip on the bottom half of the enclosure. The upper portion is there to meet the minimum wall thickness requirements for the 3D printing process.</p>
<p>The photo below shows the overall stackup of the components inside the light fixture. You can see the lip on the two enclosure halves too.</p>
<div id="attachment_1147" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/side-view.jpg"><img class="size-large wp-image-1147" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/side-view-1024x683.jpg" alt="If you look closely, you can see the overlapping lips on each half of the enclosure in this photo." width="640" height="427" /></a><p class="wp-caption-text">If you look closely, you can see the overlapping lips on each half of the enclosure in this photo.</p></div>
<h3>Laser Cutting the Lid</h3>
<p>The final mechanical part of the project was to laser cut a lid for the enclosure out of clear acrylic. The laser cutting service requires a DXF file with the outline to cut. To generate a DXF file to cut, I created a sketch on the top of the enclosure then used the sketch project command to project the geometry of the top of the enclosure into the sketch. Once that was completed, I right clicked on the sketch in the design browser and selected export DXF. I uploaded the DXF file to the laser cutting service and received a laser cut acrylic lid for the project about a week later.</p>
<h2>Software</h2>
<h3>Setting the Config Bits</h3>
<p>One of the more painful steps when using a new PIC microcontroller for the first time is determining the correct values for the processor&#8217;s config bits. These bits are programmed alongside the firmware. The usually control the clock source for the processor and the functionality of some I/O pins. When they&#8217;re wrong, things don&#8217;t work as expected. Errors in the config bits can result in your PIC running at half speed, one-fourth speed, or hilariously, 32kHz instead of 32MHz. Here&#8217;s the values of the config bits I used on this project:</p>
<pre>// FICD
#pragma config ICS = PGD3
#pragma config JTAGEN = OFF

// FOSCSEL
#pragma config FNOSC    = FRC
#pragma config PWMLOCK  = OFF
#pragma config IESO     = OFF

// FOSC
#pragma config POSCMD   = EC
#pragma config OSCIOFNC = OFF
#pragma config IOL1WAY  = OFF
#pragma config FCKSM    = CSECMD

// FWDT
#pragma config PLLKEN   = ON
#pragma config WINDIS   = OFF
#pragma config FWDTEN   = OFF</pre>
<p>The FICD config bits control debugging. In this case, the in-circuit debugging is placed on the PGD3 pins and JTAG is disabled. The FOSCSEL bits select the internal RC oscillator. The internal RC oscillator will be used at power up until the PLL is configured and locked to the external SiTime MEMS oscillator.</p>
<p>The FOSC bits select an external oscillator on the clock input, set the OSC2 pin as a general purpose IO, enable clock switching, and enable multiple reconfigurations of the peripheral pin select module. Clock switching must be enabled to switch from the internal RC oscillator to the PLL clock output later in software. The PPS select allow the external IO pins on the PIC24 to be assigned to different peripherals inside the PIC24. If you&#8217;re designing a brushless motor controller or antilock brake system where malfunctions could be destructive, setting the IOL1WAY bit to ON would be a good idea to prevent errant software glitches from reconfiguring the IO pins. In our case, multiple reconfigurations are fine.</p>
<p>The final group of bits are the FWDT watchdog timer bits. We enable PLL lock detection but disable the watchdog timer. Again, if you&#8217;re designing a brushless motor controller or antilock brake system where malfunctions could be destructive, enabling the watchdog timer might be a good idea.</p>
<h3>Clock Switchover</h3>
<p>Based on the configuration bits, our PIC24 boots with the internal RC oscillator as the clock source for the CPU. The PIC24 is capable of running much faster than that though by locking its internal PLL to an external clock source and running from the PLL clock output. Here&#8217;s the code to do that:</p>
<pre>    // Configure PLL prescaler, PLL postscaler, PLL divisor
    // with 10MHz external clock
    // Fin   = 10MHz
    // Fplli = Fin/N1  = 10/2  = 5MHz     0.8 &lt; Fplli &lt; 8.0
    // Fsys  = Fplli*M = 5*32  = 160MHz   120 &lt; Fsys  &lt; 340
    // Fosc  = Fsys/N2 = 160/2 = 80MHz    15  &lt; Fosc  &lt; 120
    // Fcy   = Fosc/2  = 80/2  = 40MHz
    PLLFBD             = 30; // PLLFBD  = M-2  = 32-2 = 30
    CLKDIVbits.PLLPOST =  0; // N2 = 2 =&gt; PLLPOST = 0 
    CLKDIVbits.PLLPRE  =  0; // N1 = 2 =&gt; PLLPRE  = 0
    
    // Initiate Clock Switch to Primary Oscillator with PLL (NOSC=0b011)
    __builtin_write_OSCCONH(0x03);
    __builtin_write_OSCCONL(OSCCON | 0x01);

    // Wait for Clock switch to occur
    while (OSCCONbits.COSC!= 0b011);
    
    //  Wait for PLL to lock
    while (OSCCONbits.LOCK!= 1);</pre>
<p>The code above boots using the internal RC oscillator and enables the PLL. We then switch immediately to using the clock output from the PLL. Once the PLL is locked to the external SiTime MEMS oscillator, we boot into the main portion of our code. The result is that our PIC24 is now running at its maximum rated speed.</p>
<h3>Using the PWM Peripheral</h3>
<p>The following initialization code configures the PWM peripheral to run at a PWM frequency of 1220.7 Hz (1220.7 Hz is the 80 MHz Fosc divided by 65536):</p>
<pre>    // initialize PWM
    PTCONbits.EIPU = 1;
    PTCON2bits.PCLKDIV = 0b000;
    PTPER = 65535;

    PHASE1 = PHASE2 = PHASE3 = 0;
    PDC1 = PDC2 = PDC3 = 0x100;
    DTR1 = DTR2 = DTR3 = 0;
    ALTDTR1 = ALTDTR2 = ALTDTR3 = 0;
    IOCON1 = IOCON2 = IOCON3 = 0xC000;
    PWMCON1 = PWMCON2 = PWMCON3 = 0x0000;
    FCLCON1 = FCLCON2 = FCLCON3 = 0x0003;
    
    PTCONbits.PTEN = 1;</pre>
<p>The following code is then used to update the PWM peripheral with new red, green, and blue values:</p>
<pre>PDC1 = PMapLut[rx_data[0]];
PDC2 = PMapLut[rx_data[1]];
PDC3 = PMapLut[rx_data[2]];</pre>
<p>The PWM peripheral has 16-bit resolution so I also needed a new gamma table to take advantage of the increased resolution. The PMapLut array holds the gamma correction table. Here&#8217;s the most recent version of my gamma table:</p>
<pre>static const unsigned short PMapLut[256] = {
       0,    63,  127,  191,  191,  255,  255,  319,  319,  383,  447,  447,  511,  511,  575,  639,
      703,  703,  767,  831,  895,  895,  959, 1023, 1087, 1151, 1151, 1215, 1279, 1343, 1407, 1471, 
     1535, 1599, 1663, 1727, 1791, 1855, 1919, 1983, 2047, 2111, 2239, 2303, 2367, 2431, 2495, 2623, 
     2687, 2751, 2815, 2943, 3007, 3135, 3199, 3263, 3391, 3455, 3583, 3647, 3775, 3839, 3967, 4031, 
     4159, 4287, 4351, 4479, 4607, 4735, 4799, 4927, 5055, 5183, 5311, 5439, 5567, 5631, 5759, 5887,
     6015, 6207, 6335, 6463, 6591, 6719, 6847, 6975, 7167, 7295, 7423, 7615, 7743, 7871, 8063, 8191,
     8383, 8511, 8703, 8831, 9023, 9151, 9343, 9535, 9727, 9855,10047,10239,10431,10623,10751,10943,
    11135,11327,11519,11775,11967,12159,12351,12543,12735,12991,13183,13375,13631,13823,14079,14271,
    14527,14719,14975,15167,15423,15679,15871,16127,16383,16639,16895,17151,17407,17663,17919,18175,
    18431,18687,18943,19199,19519,19775,20031,20351,20607,20863,21183,21503,21759,22079,22335,22655,
    22975,23295,23551,23871,24191,24511,24831,25151,25471,25791,26175,26495,26815,27135,27519,27839,
    28223,28543,28927,29247,29631,29951,30335,30719,31103,31423,31807,32191,32575,32959,33343,33727,
    34175,34559,34943,35327,35775,36159,36607,36991,37439,37823,38271,38719,39103,39551,39999,40447,
    40895,41343,41791,42239,42687,43135,43647,44095,44543,45055,45503,46015,46463,46975,47423,47935,
    48447,48959,49471,49983,50495,51007,51519,52031,52543,53055,53631,54143,54655,55231,55743,56319,
    56895,57407,57983,58559,59135,59711,60287,60863,61439,62015,62591,63167,63807,64383,65023,65535
};</pre>
<h3>Selecting and Configuring Modes</h3>
<p>When the software begins operation, it checks the pushbutton switch to see if it is depressed. If it is, the software checks to see that the switch remains depressed 50 times over one second. If it is, the software enters its configuration mode.</p>
<p>In configuration mode, the default operation of the light and the DMX address can be set by sending a specially formatted DMX packet to the light. The light can be configured for gamma-corrected 8-bit or raw 16-bit DMX operation, random strobe mode, sine oscillator mode, color wash mode, or lamp test mode. Once the mode is configured, the red channel blinks three times and the light returns to normal operation.</p>
<h4>DMX</h4>
<p>In DMX mode, the software listens for its DMX address. Once three (GC 8-bit mode) or six (raw 16-bit mode) addressed bytes are received, the software updates the PWM levels with the received light levels. To configure GC 8-bit mode and set the fixture address, the following DMX packet is sent to the fixture while it is in configuration mode:</p>
<pre>&lt;dmx addr hi byte&gt; &lt;dmx addr lo byte&gt; &lt;0x00&gt; &lt;~dmx addr hi byte&gt; &lt;~dmx addr lo byte&gt; &lt;0xff&gt;</pre>
<p>To configure raw 16-bit mode and set the fixture address, the following DMX packet is sent to the fixture while it is in configuration mode:</p>
<pre>&lt;dmx addr hi byte&gt; &lt;dmx addr lo byte&gt; &lt;0x00&gt; &lt;~dmx addr hi byte&gt; &lt;~dmx addr lo byte&gt; &lt;0xff&gt;</pre>
<p>The DMX address in the packets above ranges from 1 to 512.</p>
<h4>Random Strobe</h4>
<p>In random strobe mode, the three channels of the fixture blink randomly. This mode was supported to blink the white lights on my Crate Beast Halloween project. In that project, an additional IO pin on the PIC24 had to be asserted to enable the flashing lights. To configure random strobe mode, send the following DMX packet to the fixture while it is in configuration mode:</p>
<pre>0x02 0x02 0x00 0xfd 0xfd 0xff</pre>
<h4>Sine Oscillators</h4>
<p>In sine oscillator mode, the three channels output a sine wave. The frequency of the sine wave varies smoothly and randomly causing the lights to go in and out of sync with each other over time. This mode is great for slow ambient background light effects when you don&#8217;t want to worry about programming a complete DMX show.</p>
<p>A friend and I wrote this software initially while I was in college in the early 90s. Over the decades, it&#8217;s been run on numerous platforms. I currently use this mode in my Crate Beast Halloween prop for the red background lighting inside the crate, the background fire effect on my zombie pit, and the green/cyan/UV foreground lighting on my zombie containment unit.</p>
<p>To configure sine oscillator mode, send the following DMX packet to the fixture while it is in configuration mode:</p>
<pre>0x02 0x01 0x00 0xfd 0xfe 0xff</pre>
<h4>Color Wash</h4>
<p>In color wash mode, the fixture smoothly scrolls through a color wheel of 1536 different fully saturated RGB hues. This mode is great for slow ambient background color-changing light effects when you don&#8217;t want to worry about programming a complete DMX show. To configure color wash mode, send the following DMX packet to the fixture while it is in configuration mode:</p>
<pre>0x02 0x04 0x00 0xfd 0xfb 0xff</pre>
<h4>Lamp Test</h4>
<p>In lamp test mode, the fixture cycles through each channel at full brightness with about a one second pause between channels. To configure lamp test mode, send the following DMX packet to the fixture while it is in configuration mode:</p>
<pre>0x02 0x03 0x00 0xfd 0xfc 0xff</pre>
<h2>Changes for Next Version</h2>
<div id="attachment_1149" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/IMG_20190324_102016_cover_photo.jpg"><img class="size-large wp-image-1149" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/IMG_20190324_102016_cover_photo-1024x682.jpg" alt="The finished light. It's never too early to start thinking about the next version." width="640" height="426" /></a><p class="wp-caption-text">The finished light. It&#8217;s never too early to start thinking about the next version.</p></div>
<p>After disassembling the light several times to hold down the configuration button during power up, one change I would make to the hardware would be to make the button accessible without disassembling the light. The easiest way to accomplish this change would be to create a new board layout that uses a right-angle button, place the button close to the edge of the board, then finally place a small hole in the enclosure that permits pressing of the button with a small non-conductive object such as a toothpick.</p>
<p>Another upgrade would be to make the firmware upgradeable over the DMX interface. This would require a bi-directional RS-485 adapter for a PC or Mac and the installation of a bootloader in the PIC24&#8217;s FLASH memory. If the configuration button were held down during power up, the bootloader could listen for a command to load new firmware over the DMX interface. If the command was received, the upgrade would continue. If not, the bootloader would time out and jump into the existing firmware which could then permit configuring the operating mode and DMX address or jump to normal operation. This should only require software changes and thus be possible using the existing hardware.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/homebrew-rgb-led-light/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PIC18 Four-Channel DMX Relay Controller</title>
		<link>https://bikerglen.com/blog/pic18-four-channel-dmx-relay-controller/</link>
		<comments>https://bikerglen.com/blog/pic18-four-channel-dmx-relay-controller/#comments</comments>
		<pubDate>Tue, 03 Oct 2017 20:31:11 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[CNC Milling]]></category>
		<category><![CDATA[DMX / Art-Net]]></category>
		<category><![CDATA[Fusion 360]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>

		<guid isPermaLink="false">http://bikerglen.com/blog/?p=732</guid>
		<description><![CDATA[Halloween was right around the corner and I needed a timer with a bunch of relays to trigger some store-bought props and a fog machine periodically. (Mental note: read fog machine specs carefully—not all come with timer remotes.) My first &#8230; <a href="https://bikerglen.com/blog/pic18-four-channel-dmx-relay-controller/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_733" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/pic18-dmx-relay-a.png"><img class="size-large wp-image-733" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/pic18-dmx-relay-a-1024x683.png" alt="PIC18F1320-based, four-channel DMX Relay Controller" width="640" height="427" /></a><p class="wp-caption-text">A four-channel DMX relay controller based on a PIC18F1320.</p></div>
<p>Halloween was right around the corner and I needed a timer with a bunch of relays to trigger some store-bought props and a fog machine periodically. (Mental note: read fog machine specs carefully—not all come with timer remotes.) My first thought was an Arduino and cheap relay board. Second thought was to build something with a micro and some relays. Third thought was that if I’m going to build something, might as well add DMX and package it up into a neat enclosure. Hence, the four channel DMX-controlled relay project was born.</p>
<p><span id="more-732"></span></p>
<p><strong>Design Parameters</strong></p>
<p>My go to 8-bit micro is a <a href="http://www.microchip.com/wwwproducts/en/PIC18F1320">PIC18F1320</a>. I’ve used them on tons of projects, all the development tools are already installed on my computer, and I’m pretty familiar with their idiosyncrasies and peripherals. I’ve also already written both DMX transmitter and DMX receiver code for this micro. The other micros I use a lot are all <a href="http://www.microchip.com/design-centers/16-bit">PIC24s</a> but a 16-bit micro is overkill for this project. PIC18F1320 it is!</p>
<p>Another constraint on this design was to have something that easily fits in an enclosure. I’ve been using <a href="https://www.hammfg.com/electronics/small-case/extruded/1455">Hammond extruded aluminum enclosures</a> for a while now too. They’re well made and look sharp. One of their smaller enclosures holds a 50mm by 80mm PCB which should be plenty of room for this design. Using the smallest enclosure possible reduces the cost of the board, the enclosure, and the end panels.</p>
<p>One last constraint that bears mentioning is the relay selection. I’m only switching small low-voltage, low-current loads. The <a href="https://www.components.omron.com/product-detail?partId=226">Omron G5V-1 series</a> of relays are physically small and capable of switching up to 1A at 24VDC. This matched the sorts of loads I was expecting to switch and four of them would fit on my PCB.</p>
<p>Design decisions made: use a PIC18F1320, use a Hammond 1455C801 enclosure, and use Omron G5v-1DC5 relays.</p>
<p><strong>Schematic</strong></p>
<p>Here’s the schematic for the DMX relay controller. The controller consists of a PIC 18 microcontroller, a crystal oscillator, a power supply, a programming connector, a DMX interface, some relays and their drivers, and an illuminated pushbutton.</p>
<div id="attachment_739" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/dmx-relay-schematic.png"><img class="size-large wp-image-739" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/dmx-relay-schematic-1024x682.png" alt="DMX relay board schematic." width="640" height="426" /></a><p class="wp-caption-text">DMX relay board schematic.</p></div>
<p>I had previously built a few PIC18 projects that used pulse width modulation (PWM) to dim four channels of LEDs with 10-bit resolution. Those projects were powered from 24V and ran the PIC18 as fast as it would run (FCY=40MHz) so there would be plenty of time to service the very frequent interrupts while still listening to the serial port for DMX data. I started with that hardware and software as the basis for this new design but swapped out the LED drivers for some relay drivers and relays.</p>
<p>The PIC18F1320 is capable of running at 40MHz at 5V with a 10MHz crystal oscillator. There&#8217;s also a PIC18LF1320 variant that will run at 24MHz at 3.3V with a 6MHz crystal oscillator. Either would work for this design. I went with the 5V version and made this a 5V-only design simply because I&#8217;ve had an easier time finding stock, off-the-shelf crystal oscillators in my preferred package for hand soldering that run at 5V than 3.3V.</p>
<p>For an oscillator, I picked a 10MHz, 5V ECS part that I’ve used on past designs. It’s a little big but it’s also very easy to solder by hand. I’m running the PIC18 oscillator in its HSPLL oscillator mode. With the 10MHz crystal, the PIC18 runs with an FCY of 40MHz—way faster than needed for this project because the relays are only either on or off and creation of PWM outputs in an interrupt service routine is not required.</p>
<p>For a power supply, I typically use <a href="http://www.cui.com/product/power/dc-dc-converters/non-isolated/0.5-a-output-current/v78-500-series">Cui V7805-500</a> or <a href="http://www.cui.com/product/power/dc-dc-converters/non-isolated/0.5-a-output-current/vxo78-500-series">Cui VXO7805-500</a> switching DC-DC converters. Both have a very wide input voltage range&#8211;from about 6 to 30+ volts. The wide input voltage is important if controlling, for example, a strand of five or six blue or green LEDs wired in series. In this example, the LEDs would be powered from +24V and then the +24V would be connected to the input of the regulator to generate +5V for the microcontroller. Using a cheap linear regulator such as the <a href="https://en.wikipedia.org/wiki/78xx">LM7805</a> with a 24V input would result in at least burned fingers and quite possibly a failure of the regulator without a proper heatsink.</p>
<p>The Cui regulators can supply 500mA of current while still running cool to the touch. The relays and the rest of the design only consume about 160mA so plenty of margin. As with most regulators, the CUI parts require some capacitors on both the inputs and outputs for stability. I designed the board to hold one of these switching regulators but ultimately decided not to stuff the component and fed the board directly from a 5V power supply connected to the power connector.</p>
<p>The Microchip standard programming interface is a 6-pin single-row 0.1” header. A number of years ago (possibly over a decade ago), I decided I wanted to use a connector that occupied less board space than the single-row header. I started using a 10-pin double row 2mm header. I should probably switch to 5-pin single row 2mm header at some point. Other than the connector, it’s the same as the standard programming interface.</p>
<p>I copied and pasted both the 2mm header and the /MCLR pin circuitry for this design from an earlier PIC24 design. On PIC24 designs, the /MCLR reset pin requires a 10k pull-up resistor and is particularly sensitive to electrostatic discharge. The 330Ω resistor and 0.1µF capacitor form a low-pass filter and serve to reduce the likelihood of an ESD event resetting the microcontroller. They’re not needed on the PIC18 design so I stuffed the 330Ω resistor pads with a 0Ω jumper and left the 0.1µF capacitor off the board altogether. These changes are noted in the schematic’s info layer.</p>
<p>For the DMX interface, I’m using <a href="http://www.te.com/usa-en/product-5520251-4.html">two RJ-45 connectors</a> and a Texas Instruments <a href="http://www.ti.com/product/SN65HVD06">SN65HVD06 RS-485 transceiver</a>. The RJ-45 connectors are wired using the less popular <a href="http://www.dl.colorkinetics.com/files/web/support/pro/wiring/RJ45_TO_RJ45.pdf" target="_blank">Color Kinetics standard</a> where pin 1, the white with orange stripe wire, is the inverting or (-) data signal and pin 2, the orange wire, is the non-inverting or (+) data signal.</p>
<p>As mentioned above, I’m using four Omron G5V-1-DC5 relays. The coil voltage is 5V and the coil draws 30mA when energized. The relay’s contacts can switch up to 1 V at 24VDC. Because the board layout does not have adequate separation between traces for AC line voltage and the board is in an ungrounded aluminum enclosure, this design is NOT suitable for switching AC line voltage. Use with small DC loads under 24V only.</p>
<p>I did not physically have room to connect all the relays’ contacts pins to the outside world. Instead I connected the commons of the top two relays together and the commons of the bottom two relays together and routed these two signals to the outside world. I routed out the normally-open contacts for all four relays. This only required a six position screw terminal strip which fit comfortably on the circuit board and the end panels of the enclosure.</p>
<p>Finally, it’s always good to have a pushbutton and an LED on a microcontroller project. I’m using a <a href="http://www.nkkswitches.com/wp-content/themes/impress-blank/search/inc/part.php?part_no=GB15JVC" target="_blank">very slim NKK illuminated pushbutton</a> that will fit between the RJ-45 jacks and the side of the enclosure. The pushbutton will be used to set the DMX address and the LED indicates the state of the microcontroller: DMX address programming, DMX address confirmation, DMX data valid, or running an idle loop. More on this later in the software section.</p>
<p><span style="color: #000000;"><b>Designing the Board for the Enclosure</b></span></p>
<div id="attachment_779" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/keepouts.png"><img class="size-large wp-image-779" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/keepouts-1024x668.png" alt="Avoid these keep out regions when designing a board to fit the Hammond 1455C801 extruded aluminum enclosure." width="640" height="418" /></a><p class="wp-caption-text">Avoid these keep out regions when designing a board to fit the Hammond 1455C801 extruded aluminum enclosure.</p></div>
<p>The board was designed to fit in a <a href="https://www.hammfg.com/part/1455C801" target="_blank">Hammond 1455C801</a> extruded aluminum enclosure. The enclosure has 2mm deep card guides on either side of it to hold an 80mm x 50mm circuit board. In addition, the channel for the end panel screws extends an additional 1.55mm into the interior volume of the enclosure. Any components on the board need to avoid the volume occupied by the card guides and screw channel. This requires a 3.55mm  high keep out region at both the bottom and top edges of the board. I used 4mm to be safe. This is particularly important for conductive components and vias that could possibly make contact with the conductive enclosure.</p>
<p>When placing components on the ends of the enclosure, they need to avoid the screws that hold the end panels to the extruded chassis and protrude through both the plastic bezel and end panels. The centers of the screws are 2mm from the edge of the board. The screws have a radius of 2.5mm. The minimum aluminum around any component on the end panels should be about 1mm. If you add these up, the outside edges of any components protruding through an end panel should be at least 5.5mm from the edge of board.</p>
<p>The plastic bezel is 1.5mm thick. The end panels are 1.5mm thick. The outside faces of the end panels will then be 3mm from the left and right edges of the board. Any components that are flush mounted will need to hang off the edge of the board by 3mm. Adjust this dimension up or down depending on the desired amount for a component to extend past or be recessed into the face of the enclosure.</p>
<p><strong>Layout</strong></p>
<div id="attachment_740" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/dmx-relay-board.png"><img class="wp-image-740 size-large" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/dmx-relay-board-1024x584.png" alt="dmx-relay-board" width="640" height="365" /></a><p class="wp-caption-text">DMX relay board PCB layout.</p></div>
<p>For a layout, I started with a previous design that used this same enclosure, same pushbutton, and same connectors. The only change was moving from a five position Phoenix header to a six position Phoenix header. I’m happy with the layout but I really need to find a smaller surface mount crystal oscillator package that is easy to solder by hand.</p>
<p><strong>Ordering Boards</strong></p>
<p>I ordered the boards from <a href="https://oshpark.com/projects/S3gRq4cx/" target="_blank">OSHPark</a>. Here are the renders. The cost for three boards was $31.00.</p>
<div id="attachment_741" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/relay-board-oshpark-render-top.png"><img class="size-large wp-image-741" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/relay-board-oshpark-render-top-1024x641.png" alt="OSHPark render of the top of the DMX relay controller board." width="640" height="401" /></a><p class="wp-caption-text">OSHPark render of the top of the DMX relay controller board.</p></div>
<div id="attachment_742" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/relay-board-oshpark-render-bottom.png"><img class="size-large wp-image-742" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/relay-board-oshpark-render-bottom-1024x641.png" alt="OSHPark render of the bottom of the DMX relay controller board." width="640" height="401" /></a><p class="wp-caption-text">OSHPark render of the bottom of the DMX relay controller board.</p></div>
<p><strong>Enclosure End Panel Design</strong></p>
<p>Once the boards were back and stuffed, I verified they fit in the enclosure as intended. The clearance between the bottom of the board and the enclosure is a bit tight so I used some wire cutters to trim the leads of the longer components to prevent them from making contact with the enclosure and creating a short. Ideally, I’d move to 100% surface mount components when using this enclosure, but I have not done so yet.</p>
<div id="attachment_736" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/pic18-dmx-relay-b-1280.jpg"><img class="size-large wp-image-736" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/pic18-dmx-relay-b-1280-1024x682.jpg" alt="Data side of the DMX relay controller." width="640" height="426" /></a><p class="wp-caption-text">Data side of the DMX relay controller.</p></div>
<div id="attachment_737" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/pic18-dmx-relay-c-1280.jpg"><img class="size-large wp-image-737" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/pic18-dmx-relay-c-1280-1024x682.jpg" alt="Power side of the DMX relay controller." width="640" height="426" /></a><p class="wp-caption-text">Power side of the DMX relay controller.</p></div>
<p>Now that I knew the boards fit the enclosure, it was time to design the end panels. I first did this for this arrangement of connectors and pushbuttons on this enclosure over a decade ago. I did it using hand-drawn sketches before the days of easily accessible and affordable CAD packages. Unfortunately, I lost my notes.</p>
<p>The basic process is to draw a dimensioned 2D sketch of the circuit board with the components on one end of the enclosure. Now draw a dimensioned sketch of the end panel over this sketch. The end panel needs to be placed over the circuit board just like it will be when the enclosure is assembled. With a bit of math, you can extrapolate the y positions and heights of the components on the board to the x and y positions of the components on the end panel.</p>
<p>Once the centers of all the components on the panel are known, it’s time to calculate the hole and cut out sizes. When calculating cut out sizes, the smallest milling bit available at Front Panel Express has a diameter of 1mm. The corners of any cutouts will necessarily have a rounded corner with a radius of 0.5mm. If you make the cutout about 0.5mm larger than component, the component will fit easily into the cutout when assembling the enclosure but there could be a bit of interference in the corners.</p>
<p>Repeat for the other end of the enclosure. I’m sure this process could be sped up and made less error prone using Fusion 360 or any other reasonably decent CAD software.</p>
<p>I used <a href="https://www.frontpanelexpress.com/" target="_blank">Front Panel Express</a> to design and mill the end panels. Once I had the x-y coordinates and cutout sizes, I launched their software. I copied the dimensions from the enclosure data sheet for the basic dimensions of the panel and and the location and dimensions of the screw holes. I chose a thickness of 1.5mm for the end panels.</p>
<p>I then transcribed the positions and dimensions of my cut outs from my notes into Front Panel Express. The final end panels are shown in the figure below.</p>
<div id="attachment_744" style="width: 648px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/Untitled-1.png"><img class="size-full wp-image-744" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/Untitled-1.png" alt="Front and rear panels for the DMX relay board’s enclosure." width="638" height="589" /></a><p class="wp-caption-text">Front and rear panels for the DMX relay board’s enclosure.</p></div>
<p><strong>Verifying Fit</strong></p>
<div id="attachment_738" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/pic18-dmx-relay-d.jpg"><img class="size-large wp-image-738" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/pic18-dmx-relay-d-1024x683.jpg" alt="3D render of the DMX controller in its enclosure with end panels." width="640" height="427" /></a><p class="wp-caption-text">3D render of the DMX controller in its enclosure with end panels.</p></div>
<p>Before spending the money to have the end panels fabricated, I checked their dimensions using <a href="https://www.frontpanelexpress.com/" target="_blank">Front Panel Express</a>, <a href="http://ecad.io" target="_blank">ecad.io</a>, and <a href="https://www.autodesk.com/products/fusion-360/overview" target="_blank">Autodesk Fusion 360</a>. The first step is to gather the required files for Fusion 360.</p>
<p>In the Front Panel Express design software, I exported my front panels as DXF files without reference points. I used ecad.io and the .brd file from Eagle PCB to create a 3D mechanical model of my circuit board without any components on it and exported it as a STEP v2.14 assembly file. I then dug around the component manufacturers’ websites to find 3D models of the enclosure and all the components that would extend through the end panels.</p>
<p>Once I had all the required files, I launched Fusion 360 and uploaded all the files. The DXF files for the end panels needed some depth. I opened each DXF file, used the Push/Pull tool to change the depth of the panels to 1.5mm then hid the sketch and saved the files.</p>
<p>At this point, I created a new design and new component in Fusion 360. I imported each component I previously uploaded into the new design and used the joint command in the assemble menu to place the components on the circuit board, the circuit board in the enclosure, and then the panels on the end of the enclosure.</p>
<p>I used the interference command under the inspect menu to check for interferences between the screw heads and my panels and the connectors and pushbutton and my panels. The interference command detected some interference in the corners of a few of the connectors but it was not enough to concern me.</p>
<p>At this point, I was confident in ordering the panels from Front Panel Express.</p>
<p><strong>Software<br />
</strong></p>
<p>The software has four main functions: initialization, DMX address programming, normal DMX run mode, and DMX failure mode.</p>
<p>After reset, the initialization function initializes all the hardware then checks to see if the pushbutton is held down. If the pushbutton is held down and continues to be held down for an entire second, the software jumps into the DMX address programming mode. If the pushbutton is not held down or is released early, the software reads the board’s existing DMX address from the PIC18’s EEPROM and jumps into the DMX run mode.</p>
<p>In the DMX address programming mode, the software listens to the incoming data stream for a DMX channel with the level set to 0xFF. Once a channel with that level is detected, the address of that channel becomes the address of the first relay. The last three relays are assigned the next three consecutive addresses after the first relay. For example, if 0xFF is received on channel 8, the relays will be assigned to channels 8, 9, 10, and 11. Once programming is complete, the address information is saved in EEPROM, the pushbutton light blinks three times, and the software enters the DMX run mode.</p>
<p>In the DMX run mode, the software listens to the incoming data stream for the DMX channels matching the addresses of the relays. Levels for the matching channels are saved to memory. Once the level for the last relay is received, all the relays are updated to their new states. If a level is less than 128, the corresponding relay will be turned off. If a level is greater than or equal to 128, the corresponding relay will be turned on. If less than four relays of channels are received, the relays will not be updated.</p>
<p>While in DMX run mode, if the software does not receive a valid DMX stream for ten seconds, the software will leave DMX run mode and enter DMX failure mode. As soon as a valid DMX stream is received, the software will leave DMX failure mode and return to DMX run mode.</p>
<p>While in DMX failure mode, an idle loop is executed. In this loop, the user can write software to control the relays in absence of a valid DMX signal. This could be as simple as turning all the relays off. For my zombie fogger project, this loop turns on the zombie’s LED lighting and triggers the zombie’s sound effects and fog machine every 30 seconds.</p>
<p><strong>The Final Product</strong></p>
<p>Here’s a photograph of the final product with the end panels installed.</p>
<div id="attachment_788" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/dmx-relay-v2-enclosure-with-panels.jpg"><img class="size-large wp-image-788" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/dmx-relay-v2-enclosure-with-panels-1024x683.jpg" alt="DMX relay controller with machined end panels installed." width="640" height="427" /></a><p class="wp-caption-text">DMX relay controller with machined end panels installed.</p></div>
<p><strong>But wait…there&#8217;s more!</strong></p>
<p>As an added bonus, with the Luminair 3 app and an Art-Net to DMX interface, I can control my zombies from an iPad!</p>
<div id="attachment_761" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/10/ipad-zombies.jpg"><img class="size-large wp-image-761" src="http://bikerglen.com/wp/wp-content/uploads/2017/10/ipad-zombies-1024x696.jpg" alt="Control zombies with an iPad!" width="640" height="435" /></a><p class="wp-caption-text">Control zombies with an iPad!</p></div>
<p><strong>Design Files</strong></p>
<p>Design files are located in my <a href="https://github.com/bikerglen/pic18-dmx-relay-board" target="_blank">Github account</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/pic18-four-channel-dmx-relay-controller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Color Kinetics ColorBurst 6 Teardown</title>
		<link>https://bikerglen.com/blog/color-kinetics-colorburst-6-teardown/</link>
		<comments>https://bikerglen.com/blog/color-kinetics-colorburst-6-teardown/#comments</comments>
		<pubDate>Mon, 09 Jun 2014 04:25:48 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[Lighting]]></category>
		<category><![CDATA[RGB LED]]></category>
		<category><![CDATA[Teardowns]]></category>

		<guid isPermaLink="false">http://bikerglen.com/blog/?p=281</guid>
		<description><![CDATA[I’ve had three Color Kinetics ColorBurst 6 RGB LED fixtures in my front yard for about ten years now. They’ve survived numerous winter snowstorms and spring monsoons. Recently one of the three fixtures started taking on water and the blue &#8230; <a href="https://bikerglen.com/blog/color-kinetics-colorburst-6-teardown/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_323" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_2000_2560.jpg"><img class=" wp-image-323 " title="Guts of my Waterlogged ColorBurst 6" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_2000_2560-1024x681.jpg" alt="" width="640" height="425" /></a><p class="wp-caption-text">The internals of my formerly waterlogged Color Kinetics ColorBurst 6 RGB LED lighting fixture.</p></div>
<p>I’ve had three Color Kinetics ColorBurst 6 RGB LED fixtures in my front yard for about ten years now. They’ve survived numerous winter snowstorms and spring monsoons. Recently one of the three fixtures started taking on water and the blue and green channels began flickering. Having served its useful life in the front yard, I promptly removed it and replaced it with a new fixture. This left me with a water logged fixture that almost but not quite worked. Time to drain the water and do a proper teardown. Read on to see how a commercial-grade RGB LED light fixture works.</p>
<p><span id="more-281"></span></p>
<h2>Background</h2>
<div id="attachment_332" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_0824_2560.jpg"><img class="size-large wp-image-332" title="C200 Track Fixtures" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_0824_2560-1024x683.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">Color Kinetics C200 RGB LED track fixtures hacked to be usable without the track.</p></div>
<p>If you’re not familiar with Color Kinetics or their products, they created some of the first RGB LED lighting fixtures shortly after the invention of the blue LED. Their earliest products, like the C200 fixture shown above, were based on multiple strings of ordinary 5mm red, green, and blue LEDs connected in series with each string driven at about 20mA.</p>
<p>Multiple strings of the same color are then connected in parallel. Each group of LEDs of the same color is connected to a driver and that driver is connected to a microcontroller. The microcontroller pulse width modulates the LEDs to control their brightness in response to a DMX-512 signal from a light board or other DMX controller. The fixtures run on +24VDC supplied by an external power supply.</p>
<div id="attachment_348" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_2006_2560_cropped.jpg"><img class=" wp-image-348" title="ColorBurst 6" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_2006_2560_cropped-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">A Color Kinetics ColorBurst 6 fixture in my front yard after 10 years of exposure to the elements.</p></div>
<p>The ColorBurst 6 fixture shown above is one of CK’s 2nd generation fixtures and one of the first lighting products to use Lumileds’s 1 Watt Luxeon emitters. This fixture debuted around the 2002 time frame. It’s much more sophisticated than the earlier design. It’s (mostly) waterproof and uses strings of red, green, and blue high-power LEDs.</p>
<p>The mounting bracket permits the light to be aimed. Exiting from the bottom of the bracket are three wires: power (+24VDC), ground, and data. These connect to an intelligent power supply that both supplies power and relays data from either a DMX or Ethernet network to the fixture. According to the data sheet, the fixture consumes about 25W with all three channels at full brightness.</p>
<p>Covering the front of the fixture is either a clear or frosted piece of tempered glass. The fixture with the clear glass has a beam angle of 10° and the fixture with the frosted glass has a beam angle of 21°. The tempered glass is permanently bonded to the painted aluminum enclosure using a waterproof sealant.</p>
<h2>Literally Cracking It Open</h2>
<p>The first step to disassembling the broken fixture was to remove the tempered glass from the front of the fixture. After ten years of exposure to the elements, the white paint under the sealant began to flake and allowed water to penetrate into the broken fixture. Even though the seal was leaking, the glass was still tightly bonded to the aluminum housing.</p>
<p>To remove the glass, I donned some safety glasses and gloves and used a large screwdriver and hammer to shatter the tempered glass. A bit of scraping removed the paint, sealant, and any remaining glass shards around the perimeter. A quick rinse with the garden house removed the dust, dirt, and broken glass inside the enclosure.</p>
<h2>Components and Block Diagram</h2>
<div id="attachment_324" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_2000_2560_annotated.jpg"><img class=" wp-image-324" title="Annotated ColorBurst 6 Guts" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_2000_2560_annotated-1024x681.jpg" alt="" width="640" height="425" /></a><p class="wp-caption-text">The internals of a ColorBurst 6 RGB LED lighting fixture with key compoents highlighted. The description of each highlighted component is in the text accompanying this photo.</p></div>
<p>The fixture has six red LEDs, six green LEDs, six blue LEDs, three integrated circuits, three MOSFETs, one diode, and numerous passives. These components are soldered to an aluminum core PCB which has better heat dissipation properties than a normal FR4 PCB. In the photo above the various key components are highlighted in the following colors:</p>
<ul>
<li>Red: Microchip PIC16F628 flash-based, 8-bit CMOS microcontroller. The PIC is the brains of the operation. It receives brightness commands from the power / data supply and sets the brightness of the red, green, and blue LEDs appropriately.</li>
<li>Yellow: National Semiconductor LM78L05 +5V linear regulator. A small diode is connected in series between the +24V power input and the regulator to lower the power dissipation in the regulator.</li>
<li>Blue: Three Fairchild FQD7N10L N-Channel QFET MOSFETs.</li>
<li>Green: Texas Instruments LMH6644 75mA rail-to-rail quad output amplifier, aka op amps.</li>
<li>Pink: a 20MHz crystal.</li>
<li>White: quick disconnect terminal for data input. The black alligator clip is connected to the ground terminal. The red alligator clip is connected to the +24VDC power terminal.</li>
</ul>
<p>The LEDs are not highlighted but since they’re illuminated, you can see the position and color of each LED. These are most likely Lumileds Luxeon 1W emitters. All LEDs of the same color are connected in series. The anode of the first LED in each series is connected to +24VDC and the cathode of the last LED in each series is connected to the drain of one of the three MOSFETs.</p>
<p>The power supply voltage is +24V. The forward voltage of red LEDs is about 2V and the forward voltage of the green and blue LEDs is about 3.5V. The combined forward voltage of each string of six LEDs is well below the power supply voltage thus permitting the LEDs to fully illuminate when the MOSFET is in an on state.</p>
<p>The aluminum core PCB is bonded to the aluminum enclosure and serves to conduct heat from the LEDs to the enclosure where it can be dissipated into the atmosphere via convection.</p>
<p>After identifying the components and reading a few of their patents, I’m beginning to get an idea of how their fixture might be put together. Below is my block diagram.</p>
<div id="attachment_342" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/colorburst6blockdiagram.png"><img class="size-large wp-image-342" title="ColorBurst 6 Block Diagram" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/colorburst6blockdiagram-1024x479.png" alt="" width="640" height="299" /></a><p class="wp-caption-text">Possible block diagram for a ColorBurst 6 fixture.</p></div>
<p>Let’s examine each of the major functional blocks in detail.</p>
<h2>Power and Communications</h2>
<div id="attachment_334" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_0829_2560.jpg"><img class="size-large wp-image-334" title="Power / Data Supplies" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/DSC_0829_2560-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">Color Kinetics PDS-60 and PDS-150e power / data supplies.</p></div>
<p>The photo above shows two different power supplies. The smaller gray 60W power supply can drive two ColorBurst 6 fixtures. The larger black 150W power supply can drive up to six ColorBurst 6 fixtures. The 60W supplies are available in preprogrammed, DMX, or Ethernet configurations. This one is a preprogrammed supply. The 150W supplies always support both DMX and Ethernet. Both power supplies are universal input DC switching power supplies and convert whatever the local line voltage and frequency is to +24VDC to power the fixtures.</p>
<p>Besides supplying power, the power supplies relay brightness levels from a DMX or Ethernet-based lighting network to the lighting fixtures. From some prior reverse engineering work, I determined that the protocol to the lights is basically DMX except that the signalling used is a single-ended signal that swings between ground and +24V instead of the normal RS-422 differential signal.</p>
<p>When a power supply is on a DMX network, it only has to change the voltage levels and can send the signal to the light with no or minimal processing. When a power supply is on an Ethernet network, it receives UDP packets on its Ethernet interface, parses the light levels out of the received UDP packets, then converts them to the +24V version of DMX used by the fixtures.</p>
<div id="attachment_345" style="width: 553px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/datainput.png"><img class="size-full wp-image-345 " title="Data Input Circuit" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/datainput.png" alt="" width="543" height="295" /></a><p class="wp-caption-text">ColorBurst 6 data input circuit.</p></div>
<p>At the light, the +24V DMX signal is received on the quick disconnect terminal highlighted in white. This signal runs through a voltage divider constructed from 33k and 10k resistors to produce a signal that is just barely within the microcontroller’s absolute maximum ratings. This signal is fed to the UART RX pin on the PIC16F628 microcontroller, pin 8. The UART TX pin, pin 9, is not connected. The schematic above shows the data input circuit and its connection to the PIC microcontroller.</p>
<h2>The Device Enumeration Mystery</h2>
<p>The unconnected UART TX pin opened up a mystery. When connected to an Ethernet network, the power supplies can determine and report the serial numbers of the connected lighting fixtures back to the host computer. How can the power supplies do this when there’s no return path for data from the light fixture back to the power supply?</p>
<p>But there is a return path—the current consumption of the fixtures. My hypothesis was that the power / data supply selectively told fixtures with certain bits set or clear in their serial numbers to turn off or on. The power / data supply would then measure the current consumption to determine if a connected light was in fact off or on. Other than that, the search should work like a normal DMX/RDM binary search for fixtures.</p>
<p>To test my hypothesis, I used Color Kinetic’s QuickPlay Pro software to instruct my Ethernet power / data supply to enumerate the connected lights while the light was powered by the power / data supply. It found the light and reported the correct serial number. I then conducted a second experiment. I left the data and ground connections to the power / data supply but used a bench supply to supply the power to the fixture. I instructed the software to enumerate the connected lights again. Nothing. Not 100% definitive proof that my hypothesis was correct but good enough proof for me for now. I did not examine the enumeration protocol in greater detail.</p>
<h2>Constant Current Sources</h2>
<p>The next step was to figure out how the constant current sources worked. I used my bench DMM’s two-wire ohmmeter and continuity test functions to ohm out the circuit. This can be a tedious process but fortunately the constant current sources were relatively simple. The figure below shows the schematic I created for the red channel of the fixture. The green and blue channels are identical. Much to my disappointment, this is a linear regulator circuit. I would have preferred to have seen some sort of a much higher efficiency switching regulator circuit.</p>
<div id="attachment_355" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/currentsource.png"><img class=" wp-image-355  " title="Constant Current Source" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/currentsource.png" alt="" width="640" height="461" /></a><p class="wp-caption-text">One of the three constant current sources used to drive the three different colors of LEDs.</p></div>
<p>For the purposes of our analysis, we can treat R19 and C1 as opens and R22 and R23 as shorts. R19 serves to shut down the constant current source in case of an open in the current sense circuit. C1, R22, and R23 will have very little current running through them in the steady state. This makes C1 an open and the voltage drop across R22 and R23 will be almost zero. R20 and R21 in parallel act as a current sensing resistor. Their combined resistance is 1.5 ohms. Let’s replace them with a single resistor called Rsense of 1.5 ohms. The simplified schematic below makes analysis of the circuit much simpler.</p>
<div id="attachment_363" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/simplifiedschematic.png"><img class="size-medium wp-image-363" title="Simplified Schematic" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/simplifiedschematic.png" alt="" width="640" height="461" /></a><p class="wp-caption-text">By assuming ideal operation of the op amp and MOSFET, the schematic can be simplified.</p></div>
<p>Let’s figure out the voltage, V(-), at the inverting terminal of the op amp. In an ideal op amp, no current will flow into its inputs. These means that the current through each LED, the current through the MOSFET from its drain to its source, and the current through the sense resistor must all be equal.</p>
<p>From Ohm’s law, the voltage across the current sense resistor will then be equal to the current through the resistor, Isense, multiplied by the resistance of the resistor, Rsense. This is the same voltage as at the inverting terminal of the op amp:</p>
<p style="text-align: center;">V(-) = Vsense = Isense • Rsense</p>
<p style="text-align: left;">Rearrange this to find the current for a given voltage at the inverting terminal:</p>
<p style="text-align: center;">Isense = V(-) / Rsense</p>
<p style="text-align: left;">The current through the LEDs is the same as the current through the sense resistor:</p>
<p style="text-align: center;">Ileds = V(-) / Rsense</p>
<p>An ideal op amp will adjust its output to keep the voltage, V(-), at its inverting terminal equal to the voltage, V(+), at it noninverting (+) terminal:</p>
<p style="text-align: center;">Ileds = V(+) / Rsense</p>
<p>The voltage, V(+), at the noninverting terminal of the op amp depends on if the PIC microcontroller is driving its output pin low (0V) or high (5V). In the case of the microcontroller driving its output pin low, the voltage, V(+), at the noninverting terminal of the op amp will be:</p>
<p style="text-align: center;">V(+)lo = 0V • (1.07kΩ / (1.07kΩ + 8.87kΩ) = 0V</p>
<p>And the LED current when the PIC drives it output low will then be</p>
<p style="text-align: center;">Ileds = V(+)lo / Rsense<br />
Ileds = 0V / 1.5Ω<br />
Ileds = 0A</p>
<p>In other words, when the output pin of the microcontroller is low, no current will flow through the LEDs and they will not be illuminated. In the case of the microcontroller driving its output pin high, the voltage, V(+), at the noninverting terminal of the op amp will be:</p>
<p style="text-align: center;">V(+)hi = 5V • (1.07kΩ / (1.07kΩ + 8.87kΩ) = 0.538V</p>
<p>And the LED current when the PIC drives it output high will then be</p>
<p style="text-align: center;">Ileds = V(+)hi / Rsense<br />
Ileds = 0.538V / 1.5Ω<br />
Ileds = 0.359A</p>
<p>In other words, when the output pin of the microcontroller is high, the current through the LEDs will be about 359mA. From looking at data sheets for various 1W LEDs, we expect the drive current at full brightness to be about 350mA. The calculated values match the expected values!</p>
<p>To summarize, when the microcontroller output pin is low, the LEDs are off because no current flows through them. When the microcontroller output pin is high, the LEDs are on at their full brightness because their maximum rated forward current is flowing through them.</p>
<h2>Dimming</h2>
<p>Even though the microcontroller can only turn each color of LEDs completely off or completely on, this fixture is still capable of setting each color of LEDs to one of 256 different levels of brightness. This level control is done by altering the amount of time a channel of LEDs is on relative to the amount of time that the same channel of LEDs is off. If the switching of the LEDs off and on occurs fast enough, the eye will see the average level of the LEDs rather than the individual periods where the LEDs are either off or on. If the switching is not quite performed fast enough, the eye will see the average color but may also perceive an annoying flickering. When all three channels are mixed (such as by pointing the fixture at a white wall), the fixture can generate any of 16,777,216 colors.</p>
<div id="attachment_368" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/pwm.png"><img class="size-medium wp-image-368" title="PWM Dimming" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/pwm.png" alt="" width="640" height="385" /></a><p class="wp-caption-text">Pulse width modulation dimming.</p></div>
<p>One technique used to switch LEDs on and off quickly to dim them is pulse width modulation (PWM). In PWM, a fixed period of time is divided into a portion of time where the LEDs are on and another portion of time where the LEDs are off. This fixed period of time is usually referred to by its reciprocal, the PWM frequency. The portion of time on relative to the entire period is referred to as the duty cycle. In the figure above, (A) represents the LEDs at 25% power, (B) represents the LEDs at 50% power, and (C) represents the LEDs at 75% power. (A), (B), and (C) all have the same PWM frequency but the duty cycle in each varies by 25%. The PWM frequency generally needs to be at least 120Hz to prevent annoying flickering.</p>
<p>The ColorBurst 6 fixture does <strong>not</strong> use pulse width modulation dimming! Both the frequency and duration of the on time and off time vary depending on the programmed brightness level. For example, at a level of 1 (out of 255), the LEDs are on for 400ns every 1.69ms. At a level of 2 (out of 255), the LEDs are on for 400ns every 0.792ms. At higher brightness levels, the LEDs are switched on or off every 26.4µs. At this 26.4µs interval, the LEDs will either be turned on for 26.4µs, turned off for 26.4µs, turned on for 400ns / off for 26µs, or turned on for 1600ns / off for 24.8µs depending on the programmed brightness level. Brighter levels have more of the on for 26.4µs periods; dimmer levels have more of the off for 26.4µs periods.</p>
<p>I have not worked out the exact on times / off times / frequencies for all the different levels. I may do this in the future but it’s really not needed to understand the operation of the fixture.</p>
<p>Two other points to consider when dimming LEDs:</p>
<ol start="1">
<li>An LED’s color will drift depending on both the forward current through the LED and the die temperature. You can dim an LED by changing the current through the LED but the color may shift as the brightness levels are changed. For more consistent color, it’s better to drive the LEDs with a fixed current and dim the LEDs by rapidly switching that current off and on. You’ll still have some color shift from die temperature changes as the duty cycle is increased but they’ll be less than the color shift caused by varying the current.</li>
</ol>
<ol start="2">
<li>This lighting fixture supports 256 levels of brightness for each of three primary colors. These levels are linear in that, for example, the 128th level should be perceived as 50% brightness by a human audience; the 64th level as 25%, the 192nd as 75%, etc. Internally, the fixtures use a gamma correction algorithm to map the programmed level to a duty cycle that appears to be that brightness to humans.<br />
&nbsp;<br />
To implement the gamma correction algorithm and create 256 levels of perceptually-linear brightness, the underlying dimming technique must support many more levels of brightness than 256. The ColorBurst 6 dimming is most likely done in software at interrupt time. Since there aren’t enough clock cycles available to do higher than about 10-bit resolution PWM in software, the fixture varies both the frequency and duration of the on times to achieve an accurate perceptually-linear dimming curve.</li>
</ol>
<h2>Thermal Overload Detection</h2>
<p>The ColorBurst 6 fixture has a built-in over temperature circuit. When the fixture becomes too hot, the microcontroller sets the fixture to the dimmest red color for thirty minutes to allow the fixture to cool down. The circuit for this is quite simple as shown in the schematic below.</p>
<div id="attachment_371" style="width: 437px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/thermal.png"><img class="size-full wp-image-371" title="Thermal Overload Sensor" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/thermal.png" alt="" width="427" height="295" /></a><p class="wp-caption-text">RT3’s resistance decreses as the board temperature increases. The microcontroller uses this sensor to detect over heating and shut down the fixture.</p></div>
<p>R26 and RT3 form a voltage divider. RT3 is a thermistor of some sort. In my cool fixture at room temperature the resistance was about 10.0kΩ. After running the fixture for five minutes, the resistance had decreased to 7.5kΩ. The output of the voltage divider is connected to the AN1 input of the PIC microcontroller. This pin is an input to the PIC’s analog-to-digital converter. As the resistance of the thermistor changes in response to the board temperature, the voltage on the pin changes. The microcontroller periodically samples this voltage using the analog-to-digital converter and at a certain threshold enables the fixture’s thermal protection mode. I could force the fixture into its thermal protection mode by momentarily grounding pin 20.</p>
<h2>Additional Resources and Footnotes</h2>
<p>I hope you enjoyed reading this teardown of my waterlogged Color Kinetics ColorBurst 6 RGB LED light fixture. The following additional resources are suggested reading if you’d like to learn more about this fixture.</p>
<ul>
<li><a href="http://www.colorkinetics.com/support/datasheets/ColorBurst_6_ProductGuide.pdf">ColorBurst 6 product guide</a> (on CK website, for the latest version of fixture)</li>
<li>Color Kinetics has a ton of patents on their RGB LED lighting fixtures. Many of the details of their products are spelled out in these patents. One of the earliest patents is <a href="https://www.google.com/patents/US6016038">#6,016,038</a>, for a “Multicolored LED lighting method and apparatus.” This patent describes the technology in their C200 light fixtures.</li>
</ul>
<p>Both Color Kinetics and Lumileds are now owned by Philips. I’m not sure of the exact acquisition date for either company.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/color-kinetics-colorburst-6-teardown/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Folding the Six Panel Wall into a Cube</title>
		<link>https://bikerglen.com/blog/folding-the-six-panel-wall-into-a-cube/</link>
		<comments>https://bikerglen.com/blog/folding-the-six-panel-wall-into-a-cube/#comments</comments>
		<pubDate>Sun, 25 May 2014 23:18:17 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[BeagleBone Black]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[LED Matrix]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[RGB LED]]></category>

		<guid isPermaLink="false">http://bikerglen.com/blog/?p=127</guid>
		<description><![CDATA[After seeing this cube and this cube, I decided it was time to build an LED cube of my own leveraging the BeagleBone Black and FPGA work I had already done for my six-panel mini video wall. The cube project &#8230; <a href="https://bikerglen.com/blog/folding-the-six-panel-wall-into-a-cube/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>After seeing <a href="https://www.flickr.com/photos/osr/12689589335/">this cube</a> and <a href="https://learn.adafruit.com/diy-led-video-cube/overview">this cube</a>, I decided it was time to build an LED cube of my own leveraging the BeagleBone Black and FPGA work I had already done for <a href="http://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/">my six-panel mini video wall</a>. The cube project is essentially purely mechanical since the existing BBB software and FPGA code will work unmodified to drive the cube.</p>
<div id="attachment_154" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/hangingcube.jpg"><img class="size-large wp-image-154" title="Hanging Cube" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/hangingcube-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">The finished cube hanging from the rafters in my basement.</p></div>
<p><span id="more-127"></span></p>
<h2>3D Printed Brackets</h2>
<p>The first step in this project was to decide how to hold the six RGB LED panels together in a cube shape. I experimented with cutting and drilling aluminum angle iron into brackets to hold each panel to its neighbors. That experiment worked but was not easy to replicate. I finally decided to draw a set of brackets using Sketchup and have the brackets 3D printed. The brackets would attach at the corners and midpoints of each panel. Since I do not own a 3D printer, I used <a href="http://sculpteo.com">sculpteo.com</a> to print the brackets out of white nylon.</p>
<div id="attachment_130" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/brackets.jpg"><img class="size-large wp-image-130" title="3D Printed Brackets" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/brackets-1024x683.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">3D printed brackets. The larger brackets hold the corners together. The small brackets hold the midpoints together.</p></div>
<p>I wanted to be able to hang the cube from the ceiling. Rather than hang the cube by its power cord or networking cable, I decided to hang the bracket using a piece of wire rope. I swaged two stops on to one end of the wire rope. The wire rope and stops are a bit rough and would eventually wear through the plastic nylon corner so I used <a href="shapeways.com">shapeways.com</a> to 3D print a pre-drilled hanging bracket for the top corner out of stainless steel.</p>
<div id="attachment_131" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/cube-hanging-bracket.jpg"><img class="size-large wp-image-131" title="cube-hanging-bracket" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/cube-hanging-bracket-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">Cube Hanging Bracket</p></div>
<p>Both the Sketchup and STL files for each of these different brackets are in my <a href="https://github.com/bikerglen/beagle/tree/master/projects/led-panel-6up/mechanical/3d_cube">github repository</a>.</p>
<h2>Panel Order</h2>
<p>The next step was to decide the order of the panels. I wanted to minimize the seams between images so I decided panels 1, 2, and 3 should connect at their sides then panels 4, 5, and 6 should connect at their sides. I also wanted the panel with the minimum number of wired connections to be the lid. Panel 1 only has one power connection and one data connection so it had to be the lid. Finally panels 1, 2, and 3 would slide sideways into panels 4, 5, and 6. This would make the corner where panels 1, 4, and 5 come together the top.</p>
<div id="attachment_129" style="width: 647px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/123456.png"><img class="size-full wp-image-129" title="Panel Ordering" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/123456.png" alt="" width="637" height="425" /></a><p class="wp-caption-text">Panel ordering. Panels 1, 2, 3 and 4, 5, 6 form two seamless units that are connected together.</p></div>
<h2>Construction</h2>
<p>The next step was to assemble the cube using the brackets and M3 x 6mm screws.</p>
<div id="attachment_191" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/brackets2.jpg"><img class="size-large wp-image-191" title="Brackets Connecting Panels" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/brackets2-1024x681.jpg" alt="" width="640" height="425" /></a><p class="wp-caption-text">Some of the brackets holding the RGB LED panels together.</p></div>
<p>The lid panel is secured using friction. I cut the heads off four longer M3 screws and threaded those into the four corners of the lid panel. Friction and gravity are enough to hold the lid panel on top of the cube.</p>
<div id="attachment_133" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/lid.jpg"><img class="size-large wp-image-133" title="M3 Post on Lid Panel" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/lid-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">One of four corners of panel 1, the lid panel, showing the M3 post used to hold the lid on to the cube.</p></div>
<p>Temporarily assemble the cube and mark the corners of the panel where the wire rope will exit the cube.</p>
<div id="attachment_135" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/corners1.jpg"><img class="size-large wp-image-135" title="corners1" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/corners1-1024x681.jpg" alt="" width="640" height="425" /></a><p class="wp-caption-text">Mark the corners with a white paint marker then file them down with a rotary tool.</p></div>
<p>Disassemble the marked panels and use a rotary tool or file to knock the corners of the panels down just enough for the wire rope to exit the cube. Labeling the panels with tape makes it easier to keep track of which panel is which as the cube is being assembled.</p>
<div id="attachment_147" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/corners2.jpg"><img class="size-large wp-image-147" title="Corners After Grinding" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/corners2-1024x681.jpg" alt="" width="640" height="425" /></a><p class="wp-caption-text">The corners of panels 1, 4, and 5 were they meet at the top of the cube. The corners were knocked down just enough with a rotary tool for the wire rope to exit the cube.</p></div>
<p>Complete the mechanical assembly of the cube using seven of the nylon corner brackets and eight of the nylon side brackets. The corner brackets will need to be rotated to accommodate the holes in the panels.</p>
<div id="attachment_148" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/inside.jpg"><img class=" wp-image-148 " title="Inside the Cube Before Wiring" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/inside-1024x768.jpg" alt="" width="640" height="480" /></a><p class="wp-caption-text">Inside the cube before wiring. Looks like I forgot a screw too.</p></div>
<h2> Electrical Connections</h2>
<p>Now wire the cube. Connect the output of panel 6 to the input of panel 5, the output of panel 5 to the input of panel 4, etc., until finally connecting the output of panel 2 to in the input of panel 1. You’ll need to make a slightly longer ribbon cable assembly to connect the output of panel 4 to the input of panel 3. Connect the output of the LogiBone FPGA board to the input of panel 6.</p>
<p>After making the data connections, use three of the wire harnesses that came with the LED panels to supply power to the cube. I used a wire nut to join all the ground connections together and another wire nut to join all the +5V connections together. These were connected using some hookup wire to a 2.1mm DC barrel jack that mates with the plug on my +5V DC power supply.</p>
<div id="attachment_150" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/connections.jpg"><img class="size-large wp-image-150" title="Wired Cube Interior" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/connections-1024x768.jpg" alt="" width="640" height="480" /></a><p class="wp-caption-text">Wired cube interior. The BBB and LB FPGA boards are inside a plastic bag until a proper mounting bracket can be fabricated.</p></div>
<p>Be sure to use electrical tape to insulate any exposed power conductors and secure any cables that could come loose inside the enclosure. I have the BeagleBone Black and LogiBone FPGA board inside a plastic bag to keep them from shorting to any exposed conductors on the LED panels. This is a temporary measure (beware of heat!) until I have time to design a bracket to mount the BBB and LB boards to the inside surface of one of the LED panels.</p>
<h2>The Finished Product</h2>
<p>Here’s a photo of the finished cube hanging in my basement.</p>
<div id="attachment_154" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/hangingcube.jpg"><img class="size-large wp-image-154" title="Hanging Cube" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/hangingcube-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">The finished cube hanging from the rafters in my basement.</p></div>
<h2>Using a Stand to Display the Cube</h2>
<p>I also built a small stand out of dowel rods and MDF plywood. I’ve yet to paint the stand. If you would rather use a stand than hang the cube, the magic angle for cutting the dowel rods is 55 degrees. The stand still needs to be painted flat black.</p>
<div id="attachment_160" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/deskstand.jpg"><img class="size-large wp-image-160" title="Cube Stand" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/deskstand-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">The cube sitting in its stand on my desk. The dowel rods are cut at 55 degrees and hold the cube with the top corner pointing straight up. The stand still needs to be painted black.</p></div>
<h2>Some Ideas for Improvements</h2>
<p>The interior of the cube gets quite warm. Ideally the BBB and LB would be located in a plastic housing attached to the wire rope above and outside the cube. A short ribbon cable would then run from the plastic housing to the interior of the cube. Lastly, I need to install the wireless drivers and connect to the BBB over WiFi instead of using a wired Ethernet cable. This would greatly reduce the bulky wiring exiting the top of the cube.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/folding-the-six-panel-wall-into-a-cube/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Expanding the BeagleBone Black and FPGA to Drive 6 (or more) Panels</title>
		<link>https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/</link>
		<comments>https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/#comments</comments>
		<pubDate>Sat, 05 Apr 2014 06:07:09 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[BeagleBone Black]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[LED Matrix]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[RGB LED]]></category>

		<guid isPermaLink="false">http://bikerglen.com/blog/?p=73</guid>
		<description><![CDATA[After completing my first BeagleBone Black + FPGA project and tutorial where I drove a single 32&#215;32 RGB LED matrix, I decided it was time to go bigger. The result is the project shown below—a 3 x 2 matrix of &#8230; <a href="https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>After completing my first BeagleBone Black + FPGA <a href="http://bikerglen.com/blog/?p=42">project</a> and <a href="http://bikerglen.com/projects/lighting/led-panel-1up/">tutorial</a> where I drove a single 32&#215;32 RGB LED matrix, I decided it was time to go bigger. The result is the project shown below—a 3 x 2 matrix of 32&#215;32 RGB LED panels. That’s 6,144 RGB LEDs or 18,432 LED chips—each of which can be controlled with 12-bit color at a refresh rate of 200Hz. Let’s take a closer look at the steps required to move from driving one panel to driving six panels.</p>
<p>Here is a video on YouTube of the <a href="http://www.youtube.com/watch?v=LBeVMGOgWvY">six panel project in action</a>.</p>
<div id="attachment_84" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/04/DSC_1838_2128.jpg"><img class="size-large wp-image-84" title="Perlin Noise" src="http://bikerglen.com/wp/wp-content/uploads/2014/04/DSC_1838_2128-1024x681.jpg" alt="" width="640" height="425" /></a><p class="wp-caption-text">576mm x 384mm RGB LED “wall” displaying a frame of Perlin noise. The BeagleBone Black can perform the roughly 600,000 3D Perlin noise calculations required to produce a smooth animation sequence at about 50% CPU utilization.</p></div>
<div id="attachment_88" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/04/video-wall-rear.jpg"><img class="size-large wp-image-88" title="rear of rgb led wall" src="http://bikerglen.com/wp/wp-content/uploads/2014/04/video-wall-rear-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">576mm x 384mm RGB LED “wall” construction showing six 192mm x 192mm 32&#215;32 RGB LED panels, the 3mm thick aluminum frame, two pieces of 20x40mm aluminum extrusion, wall mounting brackets, electronics, and power supply.</p></div>
<p><span id="more-73"></span></p>
<h2>The Frame</h2>
<p>The first step was to build a frame to mount the panels. I used a set of calipers to locate each mounting hole and determine the clearance required for each of the connectors on the LED panels. I drew the frame using the free front panel design software from frontpanelexpress.com. I added holes to mount the BeagleBone Black and a 60W +3.3V power supply. Once I had the basic layout completed, I decided to use 20mm x 40mm aluminum extrusions to give the panel some depth to hold the electronics behind the frame and panels. I finally had the frame and two wall mounting brackets fabricated at frontpanelexpress.com.</p>
<h2>The Verilog</h2>
<p>The Verilog needed some changes to drive the increased number of panels:</p>
<ul>
<li>The number of clock cycles used to shift each set of RGB data bits into the panels was reduced from 3 to 2.</li>
<li>The frame buffer memories were increased from 2 x 1024 x 12 bits to 2 x 8192 x 12 bits.</li>
<li>To maintain my 12-bit color depth and 200Hz refresh rate, the clock used to drive the panel refresh logic was bumped to 25MHz from 10MHz.</li>
<li>I added support for global dimming so that the overall brightness of the panel could be controlled without affecting the color depth of the panel.</li>
</ul>
<p>These changes were relatively quick and easy to make. A few simulations and a run through the Xilinx ISE tools yielded a new bit file ready to drive up to six panels.</p>
<p>The Xilinx Spartan 6 LX9 has enough block RAM to drive up to 16 panels. By bumping the clock to 30MHz from 25MHz, 8 panels could be driven. If the refresh rate were dropped to 100Hz, 16 panels could be driven. If more I/Os were available on the LogiBone FPGA board, 16 panels could be driven at 200Hz. All with 12-bit color.</p>
<h2>The Software</h2>
<p>Most of the software used to display patterns only required changing the display width and height defines and the write levels function to port to the larger display. The exception was the Perlin noise routine. In a floating point implementation with all compiler optimization disabled, the Perlin noise routine could only drive about 1.5 panels. I converted the Perlin noise routine to use fixed point arithmetic and turned on -O3 compiler optimizations. With these changes, the BeagleBone Black can perform the approximately 600,000 3D Perlin noise operations required to update the 6144 pixels fifty times a second at about 50% CPU utilization.</p>
<h2>The Results</h2>
<p>Below are some photos and <a href="http://youtu.be/LBeVMGOgWvY">here is a video of the six panel project in action</a>.</p>

<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/dsc_1838_2128/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/DSC_1838_2128-150x150.jpg" class="attachment-thumbnail" alt="576mm x 384mm RGB LED “wall” displaying a frame of Perlin noise." /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/video-wall-rear/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/video-wall-rear-150x150.jpg" class="attachment-thumbnail" alt="576mm x 384mm RGB LED “wall” construction." /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/bbb_mounting/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/bbb_mounting-150x150.jpg" class="attachment-thumbnail" alt="BeagleBone Black CPU board, LogiBone FPGA board, and PMOD-to-panel adapter board." /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/wall_mounting_detail/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/wall_mounting_detail-150x150.jpg" class="attachment-thumbnail" alt="Wall Mounting Detail" /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/extrusion_detail/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/extrusion_detail-150x150.jpg" class="attachment-thumbnail" alt="Extrusion Detail" /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/dsc_1820/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/DSC_1820-150x150.jpg" class="attachment-thumbnail" alt="Sneak Preview" /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/img_20140404_213943_802/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/IMG_20140404_213943_802-150x150.jpg" class="attachment-thumbnail" alt="Obligatory Generic Falling Blocks Video Game" /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/dsc_1848/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/DSC_1848-150x150.jpg" class="attachment-thumbnail" alt="Bloodshot Eyeball Animated GIF" /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/dsc_1875/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/DSC_1875-150x150.jpg" class="attachment-thumbnail" alt="Audio Spectrum Analyzer" /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/dsc_1883/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/DSC_1883-150x150.jpg" class="attachment-thumbnail" alt="Test Pattern" /></a>
<a href='https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/dsc_1845/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2014/04/DSC_1845-150x150.jpg" class="attachment-thumbnail" alt="Nyan Cat" /></a>

<h2>Resources</h2>
<p>Source code for the FPGA, the software, and the frame design are available in my <a href="https://github.com/bikerglen/beagle/tree/master/projects/led-panel-6up">github repository</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/expanding-the-beaglebone-black-and-fpga-to-drive-6-or-more-panels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Driving a 32&#215;32 RGB LED Matrix with a BeagleBone Black and an FPGA</title>
		<link>https://bikerglen.com/blog/driving-a-32x32-rgb-led-matrix-with-a-beaglebone-black-and-an-fpga/</link>
		<comments>https://bikerglen.com/blog/driving-a-32x32-rgb-led-matrix-with-a-beaglebone-black-and-an-fpga/#comments</comments>
		<pubDate>Fri, 04 Apr 2014 20:33:19 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[BeagleBone Black]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[LED Matrix]]></category>
		<category><![CDATA[Lighting]]></category>
		<category><![CDATA[RGB LED]]></category>

		<guid isPermaLink="false">http://bikerglen.com/blog/?p=42</guid>
		<description><![CDATA[My latest project uses a BeagleBone Black and a Xilinx Spartan 6 LX9 FPGA to drive a 32&#215;32 RGB LED matrix. This project lets me display cool and interesting patterns on a matrix of 32&#215;32 RGB LEDs. That’s 1024 RGB &#8230; <a href="https://bikerglen.com/blog/driving-a-32x32-rgb-led-matrix-with-a-beaglebone-black-and-an-fpga/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>My latest project uses a BeagleBone Black and a Xilinx Spartan 6 LX9 FPGA to drive a 32&#215;32 RGB LED matrix.</p>
<div id="attachment_49" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/04/IMG_1478_blog.jpg"><img class="size-large wp-image-49" title="BeagleBone Black + LogiBone FPGA board driving a SparkFun 32x32 RGB LED panel." src="http://bikerglen.com/wp/wp-content/uploads/2014/04/IMG_1478_blog-1024x683.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">BeagleBone Black + LogiBone FPGA board driving a SparkFun 32x32 RGB LED panel.The displayed pattern is a frame from a Perlin noise pseudorandom sequence.</p></div>
<p>This project lets me display cool and interesting patterns on a matrix of 32&#215;32 RGB LEDs. That’s 1024 RGB LEDs or 3072 individual LED chips that need to be controlled! Rather than attempt to control all the LEDs in software only or using one of the BBB’s programmable real-time units (PRU), I decided to use the CPU to generate the patterns and use the FPGA to handle the heavy duty task of refreshing the LEDs.</p>
<p><span id="more-42"></span>Using the FPGA to refresh the LEDs leaves me with nearly 100% of the BBB CPU available to generate patterns and lets me implement 12-bit color at a refresh rate of 200Hz. A 200Hz refresh rate has no perceptible flicker and prevents scan lines from showing when photographing or filming the panel. A typical 12-bit color software implementation using the PRU to refresh the panels only refreshes at 50 to 60Hz.</p>
<p>Having the CPU free to compute patterns rather than refresh the display lets me generate some rather complicated patterns that otherwise might not be possible. Right now the most complicated and interesting pattern is seamlessly looping Perlin noise but other various abstract patterns, animated GIFs, text, etc., can be displayed.</p>
<p>Seamlessly looping Perlin noise running at 50Hz on 1024 pixels requires 102,400 3D Perlin noise calculations per second. Using floating point math with no compiler optimization, this quickly burns through the BBB CPU cycles. Had I attempted to refresh the panel using a small embedded processor such as an Arduino, I wouldn’t have had the CPU bandwidth available to both calculate this complicated pattern and refresh the display.</p>
<div id="attachment_68" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/04/rgb-led-panel-with-power.png"><img class="size-large wp-image-68" title="rgb led panel wiring" src="http://bikerglen.com/wp/wp-content/uploads/2014/04/rgb-led-panel-with-power-1024x576.png" alt="" width="640" height="360" /></a><p class="wp-caption-text">The wiring that is required to interface the BBB and LogiBone FPGA board to the 32x32 RGB LED panel.</p></div>
<p>To build this project, I used a stock BeagleBone Black SOC board, a ValentFX LogiBone FPGA board with a Xilinx Spartan 6 LX9 FPGA, a 32&#215;32 RGB LED panel from SparkFun, and some jumper wires from Pololu Robotics. The LogiBone FPGA board was a beta unit acquired through their Kickstarter campaign. To build and simulate the FPGA, I used the free Xilinx WebPack tools. Being free, the Xilinx WebPack tools permit hobbyists (or anyone building small designs) to simulate, synthesize, map, and place and route code for a select set of Xilinx’s devices.</p>
<p>Speaking of simulation, do it! The very first bit file I loaded into the FPGA board worked the very first time I loaded it except that I had a mirror image on the display from feeding the RGB data into the display right-to-left instead of left-to-right. I reversed the order, ran another sim, and built another part. Bingo. Second try. Perfection.</p>
<p>After building everything and getting everything to work, I made a short video demonstration of the project, wrote a complete tutorial on how anyone with a BeagleBone Black, a LogiBone FPGA board, and an LED panel can replicate results, then uploaded all the required code and files to github. Below are links to the code, tutorial, and video.</p>
<p>Links to Project Files:</p>
<p><a title="Source Code" href="https://github.com/bikerglen/beagle/tree/master/projects/led-panel-v01">Source Code</a></p>
<p><a title="Step-by-Step Tutorial" href="http://bikerglen.com/projects/lighting/led-panel-1up/">Step-by-Step Tutorial</a></p>
<p><a title="Demonstration Video" href="http://youtu.be/OIyI8KaPdwk">Demonstration Video</a></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/driving-a-32x32-rgb-led-matrix-with-a-beaglebone-black-and-an-fpga/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
