<?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; 3D Printing</title>
	<atom:link href="https://bikerglen.com/blog/category/3d-cadcam/3d-printing-3d-cadcam/feed/" rel="self" type="application/rss+xml" />
	<link>https://bikerglen.com/blog</link>
	<description>A blog by Glen Akins</description>
	<lastBuildDate>Mon, 16 Feb 2026 00:47:00 +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>PIC16F1459 USB Volume Knob</title>
		<link>https://bikerglen.com/blog/pic16f1459-usb-volume-knob/</link>
		<comments>https://bikerglen.com/blog/pic16f1459-usb-volume-knob/#comments</comments>
		<pubDate>Mon, 14 Oct 2019 17:18:23 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[USB Human Interface Device (HID)]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=1607</guid>
		<description><![CDATA[The PIC16F1459 is proving to be quite the versatile part when it comes to building USB devices. Previously, I&#8217;ve used it to upgrade my giant keyboard, various flavors of one-key keyboards, a USB-controlled industrial stack light, and an annoying CAPS &#8230; <a href="https://bikerglen.com/blog/pic16f1459-usb-volume-knob/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_1600" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/usb-volume-knob-top.jpg"><img class="wp-image-1600 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/usb-volume-knob-top-1024x682.jpg" alt="The completed USB volume knob project. It uses an off-the-shelf knob and a PIC16F1459 microcontroller. The enclosure is 3D printed." width="640" height="426" /></a><p class="wp-caption-text">The completed USB volume knob. The 3D printed enclosure houses a custom board design, a PIC16F1459 microcontroller, and an optical encoder. The knob itself is an aluminum off-the-shelf component from TE Connectivity.</p></div>
<p>The PIC16F1459 is proving to be quite the versatile part when it comes to building USB devices. Previously, I&#8217;ve used it to upgrade my <a href="https://bikerglen.com/blog/building-a-giant-usb-three-key-mechanical-keyboard/">giant keyboard</a>, various flavors of <a href="https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/">one-key keyboards</a>, a USB-controlled <a href="https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/">industrial stack light</a>, and an annoying CAPS LOCK <a href="https://bikerglen.com/blog/the-annoying-caps-lock-warning-buzzer/">warning buzzer</a>.  In this project, I&#8217;m going to use the PIC16F1459 to build a USB volume knob that works similarly to the volume keys on some USB keyboards. Read on to find out more about the design of the USB volume knob.</p>
<p><span id="more-1607"></span></p>
<h2>Enclosure Design</h2>
<h3>Design Inspiration and Criteria</h3>
<p>Believe it or not, I designed the enclosure for this project before I ever even thought about building a USB volume knob. A few months ago, I set out to to design a generic enclosure that was somewhat roomy that I could use for any small project. The volume knob just happened to be the first project to come along after designing the generic enclosure.</p>
<div id="attachment_1237" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/notch-connectors.jpg"><img class="size-large wp-image-1237" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/notch-connectors-1024x682.jpg" alt="Close up of the notch and connectors." width="640" height="426" /></a><p class="wp-caption-text">Close up of the notch and connectors.</p></div>
<p>I thought about enclosures I designed in the past and a few elements of two enclosures in particular struct me as unique and something I should bring forward to my generic enclosure design. The first was the round form factor and the rear panel notch on the USB <a href="https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/">stack light controller</a> base. These are shown in the photo of the stack light controller above.</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>
<p>The second was the way the overlapping lips worked to seal the two halves of the <a href="https://bikerglen.com/blog/homebrew-rgb-led-light/">PIC24 DMX RGB light</a> together. If you look closely, you can see these in the photo of the light&#8217;s enclosure above.</p>
<p>After deciding on these key design elements, I narrowed down a few other design criteria:</p>
<ol>
<li>The enclosure should bolt together with 2-56 threaded black oxide screws and nuts.</li>
<li>The enclosure should be 0.75 inch tall since this was the largest commonly available 2-56 thread black oxide screw length.</li>
<li>The enclosure would be 60 mm in diameter.</li>
<li>The flat edge of the board that would accommodate any necessary connectors would be 24 mm wide. 24 mm easily allows for a micro USB connector or USB C connector plus a second small connector or reset button,</li>
<li>The enclosure walls would be 1.5 mm thick.</li>
<li>The circular overhangs above and below the notch would be 2 mm thick to imply the enclosure is thicker and sturdier than it really is.</li>
</ol>
<h3>Parametric Modeling</h3>
<div id="attachment_1625" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/parameters.png"><img class="size-large wp-image-1625" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/parameters-1024x601.png" alt="Parameters used to control the size of the enclosure." width="640" height="376" /></a><p class="wp-caption-text">Parameters used to control the size of the enclosure.</p></div>
<p>Since this was a generic enclosure being designed for a project that doesn&#8217;t exist yet, it&#8217;d be great to be able to resize the enclosure later based on the actual needs of the project. Fortunately Fusion 360 supports parametric modeling. With parametric modeling, you define a list of parameters and their values. Instead of specifying a fixed value when drawing a feature in the model, you use the name of the parameter instead. Now when you go back to the table and change the parameter&#8217;s value, the model will automatically update and resize based on the new value.</p>
<p>The list of parameters and their values I used for this enclosure is shown in the photo above. When I sketched the circle that became the base of the model, I entered &#8220;enclosure_diameter&#8221; for the diameter of the circle rather than &#8220;60 mm.&#8221; Now if I decide I want a larger enclosure, I can go back to the table and change the expression for the enclosure_diameter from &#8220;60 mm&#8221; to &#8220;70 mm&#8221; and the base will magically grow to 70 mm in diameter. Another cool thing is expressions can be chained like the calculation of the board diameter above which is based on the enclosure diameter, the wall thickness, and a small offset.</p>
<p>Parametric modeling can be difficult to get right. It takes a bit of planning and foresight to get it right. The enclosure bottom seems to work OK. For some reason, the enclosure top doesn&#8217;t move its screw holes correctly when the diameter is changed and the enclosure_height doesn&#8217;t really work at all. I may fix this in a later version of the enclosure design. I called it good enough for now though and moved on.</p>
<h3>Enclosure Bottom</h3>
<div id="attachment_1628" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/enc-bottom-top.png"><img class="size-large wp-image-1628" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/enc-bottom-top-1024x819.png" alt="Interior view of the bottom half of the enclosure." width="640" height="512" /></a><p class="wp-caption-text">Interior view of the bottom half of the enclosure.</p></div>
<p>The photo above shows the interior of the bottom half of the completed enclosure. The board rests on top of the hexagonal extrusions that hold the hex nuts.</p>
<div id="attachment_1629" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/enc-bottom-bottom.png"><img class="size-large wp-image-1629" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/enc-bottom-bottom-1024x819.png" alt="Exterior view of the bottom half of the enclosure." width="640" height="512" /></a><p class="wp-caption-text">Exterior view of the bottom half of the enclosure.</p></div>
<p>The photo above shows the exterior of the bottom half of the completed enclosure. The hexagonal holes hold the hex nuts that secure the two halves of the enclosure together.</p>
<h3>Enclosure Top</h3>
<div id="attachment_1630" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/enc-top-bottom.png"><img class="size-large wp-image-1630" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/enc-top-bottom-1024x819.png" alt="Interior view of the top half of the enclosure." width="640" height="512" /></a><p class="wp-caption-text">Interior view of the top half of the enclosure.</p></div>
<p>The photo above shows the interior of the top half of the completed enclosure. The screws that hold the enclosure together run through the center of the hollow posts. The ends of the hollow posts hold the circuit board in place. The flat portion notched out of the rear of the enclosure is very visible in this view.</p>
<div id="attachment_1631" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/enc-top-top.png"><img class="size-large wp-image-1631" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/enc-top-top-1024x819.png" alt="Exterior view of the top half of the enclosure." width="640" height="512" /></a><p class="wp-caption-text">Exterior view of the top half of the enclosure.</p></div>
<p>The photo above shows the exterior of the top half of the completed enclosure. The holes are tapered so that the flat head screws lay flush with the top of the enclosure.</p>
<p>That&#8217;s the finished generic version of the enclosure. Once we&#8217;ve selected an encoder and knob, we&#8217;ll add a hole for the encoder as well as a hole for a female micro USB B connector.</p>
<h3>Creating and Exporting a Board Outline</h3>
<div id="attachment_1634" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/bottom-with-board.png"><img class="size-large wp-image-1634" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/bottom-with-board-1024x819.png" alt="A generic circuit board located inside the enclosure. I added a 3D model of a right-angle tactile switch to see how a reset button might fit inside the enclosure." width="640" height="512" /></a><p class="wp-caption-text">A generic circuit board located inside the enclosure. I added a 3D model of a right-angle tactile switch to see how a reset button might fit inside the enclosure.</p></div>
<p>Since this was a generic enclosure design, it only made sense to have an empty board outline I could use a starting point when designing various boards to fit inside the enclosure.</p>
<p>I constructed a plane on top of the hex standoffs then created a sketch on that plane. I projected the interior of the enclosure and offset it by 0.5 mm away from the walls of the enclosure to create the board outline. I also need to create keepouts for the hex standoffs and circular posts that contact the board inside the enclosure. I projected these from the bottom and top of the enclosure into the sketch as well.</p>
<div id="attachment_1636" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/board-outline1.png"><img class="size-large wp-image-1636" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/board-outline1-1024x974.png" alt="The completed board outline in Eagle PCB. The white outline is on the Dimension (20) layer. The hex and round keep out areas are on the blue bKeepout (40) and red tKeepout (39) layers respectively." width="640" height="609" /></a><p class="wp-caption-text">The completed board outline in Eagle PCB. The white outline is on the Dimension (20) layer. The hex and round keep out areas are on the blue bKeepout (40) and red tKeepout (39) layers respectively.</p></div>
<p>Once the sketch was completed, I exported it as a DXF file from Fusion 360 then imported it into the dimension layer in Eagle PCB. I moved the hex standoff lines to the bottom keepout layer and the round standoff lines to the top keepout layer. I left the board outline on the dimension layer. The DXF export and import wasn&#8217;t perfect so I had to patch up the board outline some on the dimension layer. Finally, I added the holes for the 2-56 screws and saved the file as an Eagle BRD file to use as a starting point for any designs utilizing the enclosure.</p>
<h2>Selecting an Encoder</h2>
<p>A tweet from one my co-workers was the inspiration to build a USB volume knob based on the work I&#8217;d done on the small keyboards and caps lock warning buzzer. Turning a variable resistor would not work for a USB volume knob though because a variable resistor outputs an absolute resistance / position value and there is not a USB HID command to set the volume to a fixed level. You can turn the volume down, you can turn the volume up, and you can toggle mute with USB HID. That&#8217;s it.</p>
<p>Also, a variable resistor has fixed end points in its rotation. Even if I could hack something to detect which way the variable resistor was being turned and send the correct USB HID commands to the computer, eventually I&#8217;d hit an endpoint in the knobs rotation and that endpoint would likely not be aligned with the lowest volume or highest volume setting on the computer.</p>
<div id="attachment_1638" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/encoders.jpg"><img class="size-large wp-image-1638" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/encoders-1024x682.jpg" alt="Two different types of encoders." width="640" height="426" /></a><p class="wp-caption-text">Two fundamentally different encoder examples.</p></div>
<p>I needed a device that could signal the volume to go up when turned one direction and that could signal the volume to go down when turned the other direction. Also pushing the knob should toggle mute. Fortunately such a device exists&#8211;the rotary encoder. I&#8217;ve heard them called incremental encoders, rotary pulse generators, or simply encoders. These come in a bunch of different varieties.</p>
<p>The photo above shows two examples. The one with the ribbon cable is an optical rotary encoder with a quadrature encoded output. The smaller one is a mechanical rotary encoder that closes different switch contacts based on CW or CCW rotation of the shaft. The optical encoder is over $30. The mechanical encoder is closer to $3.</p>
<p>As an aside, the optical encoder pictured above has been in production for over 30 years. It was originally developed within the test and measurement division of HP for use on the front panels of their test equipment. When Agilent split off from HP in 2000, the production of the encoder went to Agilent. The encoder then went to Avago in the Agilent-Avago split in 2015. It&#8217;s currently sold by Broadcom after the Avago acquistion of Broadcom and their subsequent name change.</p>
<p>Here are some key parameters to be aware of when selecting an encoder:</p>
<ul>
<li>Shaft size: 1/4-inch (6.35 mm) and 6 mm are the most common sizes. Shaft size needs to match the diameter of the hole in the center of the chosen knob.</li>
<li>Shaft shape: Either round or D shaped. Round works. D shaped is easier to lock into place and prevent rotation of the knob on the shaft.</li>
<li>Shaft length: The value is all over the place. It&#8217;s important that the locking screw on the chosen knob can make solid contact with whatever length shaft is chosen. It&#8217;s also aesthetically important that the shaft is not too long otherwise the knob will bottom out and look way too far away from the chassis.</li>
<li>Smooth or with detents: Smooth encoders rotate freely. Encoders with detents click into place after each change in output state.</li>
<li>Optical or mechanical: Optical encoders have longer lifetimes, offer more pulses per revolution, and are more expensive. Mechanical encoders are the opposite.</li>
<li>Number of pulses per revolution: How many pulses does the knob generate in one revolution. 16, 32, 120, and 256 are common values. Some specialized encoders for motor shaft positioning applications generate even more.</li>
<li>Encoding: quadrature / gray scale or discrete pulse per direction. We&#8217;ll get into quadrature / gray scale encoding in the software section below.</li>
<li>Integrated switch: Some encoders have an integrated pushbutton switch; others don&#8217;t.</li>
<li>Supply voltage: Optical encoders typically run from a specific supply voltage and have open-drain / open-collector outputs. Mechanical encoders are a bit more flexible in terms of acceptable voltages.</li>
<li>Panel mount or board mount. Panel mount encoders have threaded stems and mount to the panel using a hex nut. Board mount encoders solder directly to the board. The distance between board and enclosure and encoder and knob all have to be considered during design with either type. I generally find board mount encoders to be less flexible in terms of positioning than panel mount encoders.</li>
</ul>
<div id="attachment_1591" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/2.jpg"><img class="wp-image-1591 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/2-1024x575.jpg" alt="2" width="640" height="359" /></a><p class="wp-caption-text">The Grayhill 62S11-M5-020C encoder used for this project. The sticker is leftover from another project and was used to keep the encoder from shorting to the board during software development.</p></div>
<p>I picked the Grayhill 62S11-M5-020C encoder that&#8217;s shown in the photo above. It has the following attributes:</p>
<ul>
<li>1/4&#8243; diameter D shaft.</li>
<li>Detented with 32 pulses per revolution.</li>
<li>Optical with quadrature encoding and an integrated switch.</li>
<li>Panel mount with a short ribbon cable and small connector.</li>
</ul>
<p>All this goodness was not cheap. The encoder goes for about $45 at quantity one.</p>
<h2>Selecting a Knob</h2>
<div id="attachment_1640" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/knobs.jpg"><img class="wp-image-1640 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/knobs-1024x682.jpg" alt="knobs" width="640" height="426" /></a><p class="wp-caption-text">Three alternative knob options for the USB volume knob.</p></div>
<p>After selecting an encoder, the next step was to select a knob. I need a knob to fit a 1/4&#8243; shaft and I wanted metal knob. I narrowed down to the four options shown in the picture above. The two larger knobs are made by TE Connectivity. They have a glossy finish. The two smaller knobs are made by Kilo International. They have a matte finish.</p>
<p>My favorite knob is the one front and center in the photograph but I decided it was too small compared to the enclosure. The knob I ultimately selected and is on the USB volume knob in the photo above is TE Connectivity part # KN1251B1/4 and sells for about $15. The runner up knob is Kilo International part # OEDNI-90-4-5 and sells for about $7. I&#8217;m definitely going to have to build something in the future that uses a few of the Kilo International knobs.</p>
<h2>Finishing the Enclosure Design</h2>
<div id="attachment_1642" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/section-analysis1.png"><img class="size-large wp-image-1642" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/section-analysis1-1024x819.png" alt="Section analysis showing the vertical alignment of the encoder within the enclosure." width="640" height="512" /></a><p class="wp-caption-text">Section analysis showing the vertical alignment of the encoder within the enclosure.</p></div>
<p>Now that I had a knob and encoder picked out, it was time to return to the enclosure design. The encoder has a 3/8-32 thread and <a href="https://littlemachineshop.com/images/gallery/PDF/TapDrillSizes.pdf">requires a 0.3970&#8243; hole (PDF link)</a>. I created a hole centered on the top half of the enclosure with this diameter then it was time to think about the vertical alignment of the enclosure, circuit board, encoder, and knob.</p>
<p>Fortunately Grayhill had a 3D model of their encoder and TE Connectivity had a 3D model of their knob. I imported these into the enclosure design and used the joint tool to place the encoder in the hole and to place the knob on the end of the encoder shaft. The Grayhill 3D model wasn&#8217;t an exact match so there&#8217;s a rogue connector and cable protruding outside the enclosure but that&#8217;s OK for now.</p>
<p>Fusion 360&#8217;s section analysis tool allowed me to see a cutaway view of how the knob, encoder, PCB, and enclosure fit together. I played with the alignment until I found something where there was enough clearance between the knob and the enclosure to allow the integrated push button in the encoder to be pressed.</p>
<p>This ultimately required the encoder to be recessed 4.5 mm below the top of the enclosure and the knob to be elevated 1/16&#8243; above the end of the shaft of the encoder. I could use washers to satisfy the former requirement. Instead I bulked up the 3D printed material between the encoder and enclosure to the required thickness. To satisfy the latter requirement, I placed a 1/16&#8243; spacer with an outside diameter of 1/4&#8243; into the knob before mounting it on the encoder&#8217;s shaft. Kind of a kluge but it works well.</p>
<p>I added the cutout for the micro USB B connector to the rear of the enclosure using the same technique I used when making connector cutouts on the <a href="https://bikerglen.com/blog/homebrew-rgb-led-light/">DMX-controlled RGB LED light</a>. The final version of the 3D printed enclosure with the micro USB B connector cutout and the encoder and knob mounted is shown the image below. I then generated the STL files and sent them for 3D printing at Sculpteo using <a href="https://www.sculpteo.com/blog/2017/10/25/how-to-design-for-hp-multi-jet-fusion-technology/">HP&#8217;s Multi Jet Fusion 3D</a> printing technology.</p>
<div id="attachment_1594" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/puck_v2_v16_grayhill_encoder-v7.png"><img class="size-large wp-image-1594" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/puck_v2_v16_grayhill_encoder-v7-1024x819.png" alt="Finished enclosure design." width="640" height="512" /></a><p class="wp-caption-text">Finished enclosure design.</p></div>
<h2>Designing the Electronics and Board</h2>
<div id="attachment_1643" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/schematic.png"><img class="size-large wp-image-1643" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/schematic-1024x764.png" alt="Completed schematic." width="640" height="478" /></a><p class="wp-caption-text">Completed schematic.</p></div>
<p>The schematic for the electronics is shown in the image above. It&#8217;s identical to the schematic for the updated version of the <a href="https://bikerglen.com/blog/updates-to-the-annoying-caps-lock-warning-buzzer/#more-1548">Annoying CAPS LOCK Warning Buzzer</a> except for the addition of a connector for the Grayhill optical rotary encoder and a few more LEDs.</p>
<p>The Grayhill encoder requires +5V DC to power the infrared light sources inside the encoder. It has open-drain / open-collector outputs and requires 2.2k pullup resistors on its CH A and CH B outputs to function. The encoder&#8217;s integrated push button switch uses the PIC&#8217;s internal weak pullup function so no pullup resistor is required on the switch output signal.</p>
<div id="attachment_1644" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/board.png"><img class="size-large wp-image-1644" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/board-985x1024.png" alt="Completed board." width="640" height="665" /></a><p class="wp-caption-text">Completed board.</p></div>
<p>The USB volume knob board is 56 mm in diameter. It is absolutely roomy compared to the 1&#8243; x 1&#8243; boards used for the caps lock warning buzzer and assorted one key keyboards. As a result, the layout was significantly easier and faster to finish.</p>
<p>I started with the generic board outline file I created while designing the enclosure. On that board outline I placed the critical components like the USB connector, the encoder connector, and the ESD suppression diodes first.</p>
<p>I placed the rest of the components next while leaving a big open area in the center to avoid any components making contact with the metallic base of the encoder or interfering with the folding of the encoder&#8217;s ribbon cable. After placing all the components, it was time to route the board.</p>
<p>I created a ground plane on each side of the board then connected the two ground planes using lots of vias through the board. Horizontal traces run on the front side of the board and vertical traces run on the rear. The +5V power is routed where its needed using traces. The completed and stuffed board is shown in the photo below.</p>
<div id="attachment_1646" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/board.jpg"><img class="size-large wp-image-1646" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/board-1024x682.jpg" alt="The completed and stuffed circuit board. I left the buzzer off for now." width="640" height="426" /></a><p class="wp-caption-text">The completed and stuffed circuit board. I left the buzzer off for now.</p></div>
<h2>Software</h2>
<p>I did have one slight snag while building this project: the software. Just because volume keys are on many USB keyboards doesn&#8217;t mean the volume keys function like the rest of the keys on the keyboard. The USB HID spec treats the volume keys quite differently. As a result, the software I used on the one key keyboards and caps lock warning buzzer was going to require some pretty arcane (if USB HID is not your thing) modifications to control the computer&#8217;s volume.</p>
<h3>USB HID Report Descriptors</h3>
<p>During device enumeration, the connected USB device tells the USB host what type of device it is. If it is a USB HID device, the device also has to tell the host the types and formats of reports it will send to the host and the types and formats of reports it expects from the host. This is done using a USB HID report descriptor.</p>
<p>The USB HID report descriptor is built using codes from the USB HID specification and a supplementary document called the USB HID usage tables. The USB HID report descriptor provides the host with enough information to parse USB input reports or to create USB output reports.</p>
<p>This offloads a lot of complexity from the device to the host. The host must be able to deal with arbitrarily formatted input reports from USB HID devices. It must also be able to create arbitrarily formatted output reports to send to USB HID devices. There&#8217;s no guarantee that different USB HID devices that perform similar functions will have identical or even similarly formatted input and output reports.</p>
<p>The code below shows the USB HID report descriptor that my small one key keyboards and the caps lock warning buzzer use. It asks the host to send an output report with the status of the five common LEDs (Num Lock, Scroll Lock, Caps Lock, etc.) and three padding bits. It also tell the host that the device will send the state of the eight modifier keys followed by up to six keys from the key code chart when polled by the host.</p>
<pre>const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={
{   0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x06,                    // USAGE (Keyboard)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
    0x95, 0x05,                    //   REPORT_COUNT (5)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x05, 0x08,                    //   USAGE_PAGE (LEDs)
    0x19, 0x01,                    //   USAGE_MINIMUM (Num Lock)
    0x29, 0x05,                    //   USAGE_MAXIMUM (Kana)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x03,                    //   REPORT_SIZE (3)
    0x91, 0x03,                    //   OUTPUT (Cnst,Var,Abs)
    0x95, 0x06,                    //   REPORT_COUNT (6)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0}                          // End Collection
};</pre>
<p>Further complicating things, the volume control keys are not a part of the keyboard usage page in the HID usage tables. They&#8217;re part of a separate usage page called the consumer control usage tables. If we want to send volume control keys to the host, we need to send some HID usage codes from a different usage table than we used for the keyboard.</p>
<p>Unfortunately, there&#8217;s no way to mix the keyboard usage with the consumer usage in a single input report. This means our device needs to send one type of input report when a keyboard key is pressed and a second, different type of input report when the volume is adjusted. (Or we could do away with sending keyboard usage input reports altogether but I wanted to keep the caps lock status and did not want to preclude sending +/- key presses instead of volume up / volume down in the future.)</p>
<p>Telling the host our device is capable of sending two different USB input reports is done using USB HID collections. There&#8217;s already one USB HID collection in the code above. The code below builds on the code above and adds a second USB HID collection. Everything up to the start of the second USB HID collection in the code below is identical to the code above.</p>
<pre>const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={
{   0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x06,                    // USAGE (Keyboard)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x85, 0x01,                    //   REPORT_ID
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
    0x95, 0x05,                    //   REPORT_COUNT (5)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x05, 0x08,                    //   USAGE_PAGE (LEDs)
    0x19, 0x01,                    //   USAGE_MINIMUM (Num Lock)
    0x29, 0x05,                    //   USAGE_MAXIMUM (Kana)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x03,                    //   REPORT_SIZE (3)
    0x91, 0x03,                    //   OUTPUT (Cnst,Var,Abs)
    0x95, 0x06,                    //   REPORT_COUNT (6)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0,                          // End Collection

    0x05, 0x0C,                    // USAGE_PAGE (Consumer Devices)
    0x09, 0x01,                    // USAGE (Consumer Control)
    0xA1, 0x01,                    // COLLECTION (Application)
    0x85, 0x02,                    //   REPORT_ID
    0x05, 0x0C,                    //   USAGE_PAGE (Consumer Devices)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x07,                    //   REPORT_COUNT (7)
    0x09, 0xB5,                    //   USAGE (Scan Next Track)
    0x09, 0xB6,                    //   USAGE (Scan Previous Track)
    0x09, 0xB7,                    //   USAGE (Stop)
    0x09, 0xCD,                    //   USAGE (Play / Pause)
    0x09, 0xE2,                    //   USAGE (Mute)
    0x09, 0xE9,                    //   USAGE (Volume Up)
    0x09, 0xEA,                    //   USAGE (Volume Down)
    0x81, 0x02,                    //   INPUT (Data, Variable, Absolute)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x81, 0x01,                    //   INPUT (Constant)
    0xC0}                          // End Collection
};</pre>
<p>The first thing this new, second USB HID collection does is tell the host we&#8217;re going to send codes from the USB HID consumer control usage tables. This is done using the USAGE_PAGE and USAGE instructions. Next, this input report will have an ID of 0x02. Then it tells the host we&#8217;re going to send the state of the track controls and volume controls and one padding bit. Lastly, it closes the collection with the end collection instruction. This <a href="https://www.microchip.com/forums/m618147.aspx">forum post</a> on Microchip&#8217;s website was invaluable in figuring out the modifications that were required to send the volume keys in a USB input report.</p>
<p>Another slight wrinkle is that if there is only one type of input report, the input report ID is not specified in the USB input reports sent from the device to the host. If there&#8217;s more than one type of input report, however, the input report ID must be specified in the USB input report. This means our USB input reports need to be bumped in length from eight bytes to nine bytes everywhere they&#8217;re referenced in our code.</p>
<p>If you&#8217;re really curious about all the code changes to support a second type of USB HID input report, I suggest doing a diff between the annoying caps lock warning buzzer source code and the USB volume knob source code. Source code for both devices is in my Github repositories.</p>
<h3>Decoding the Encoder’s Quadrature Outputs</h3>
<div id="attachment_1683" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/quadrature-codes.png"><img class="size-large wp-image-1683" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/quadrature-codes-1024x321.png" alt="Truth table and waveform illustration from the Grayhill encoder data sheet." width="640" height="201" /></a><p class="wp-caption-text">Truth table and waveform illustration from the Grayhill encoder data sheet.</p></div>
<p>If you look at OUTPUT A and OUTPUT B in the above diagram, you can see that OUTPUT B lags OUTPUT A by 90 degrees. This is called quadrature encoding. As a result, the outputs of the encoder looks like a gray code counter and only one output signal changes per click / move of the encoder.</p>
<p>To determine the direction the encoder is moving you need to know the last state of the two outputs and the current state of the two outputs. Based on the last state and the current state, you can determine if the encoder is being turned clockwise or counterclockwise.</p>
<p>For example, let&#8217;s start at position number 3 in the diagram above. A and B are both high. We save this state to a variable. Some amount of time later, we read the encoder again. If A and B are still both high, the encoder has not been turned. If however, A is now low while B is still high, the encoder has been turned one click clockwise. If however, A is still high while B is now low, the encoder has been turned one click counterclockwise.</p>
<p>To avoid missing encoder pulses, software must read the encoder at least twice as fast as the highest expected pulse rate. My software polls the encoder at a 1 kHz rate. This allows the encoder to be turned up to 500 pulses per second without missing a pulse. With a manually turned knob with only 32 pulses per revolution, that rate is acceptable. If you have a microcontroller capable of generating interrupts on the change of state of input pins, you can handle much higher rotational speeds.</p>
<p>The code to read the encoder and determine whether the volume needs to go up or down is shown below. The variable last_knob holds the last known state of the encoder&#8217;s outputs. The variable this_knobs is assigned the current state of the encoder&#8217;s outputs. The switch statement determines which way the knob is being turned and updates the signed variable value_knob up or down based on the direction the knob is turned.</p>
<pre>#define S2_PORT  PORTBbits.RB5      // CHA
#define S3_PORT  PORTBbits.RB4      // CHB

void BUTTON_UpdateStates (void)
{
    ...
    // this_knob = { CHB, CHA }
    this_knob = (S3_PORT &lt;&lt; 1) | S2_PORT;
    switch (last_knob) {
        case 0: if (this_knob == 1) { value_knob--; } else if (this_knob == 2) { value_knob++; } break;
        case 1: if (this_knob == 0) { value_knob++; } else if (this_knob == 3) { value_knob--; } break;
        case 2: if (this_knob == 0) { value_knob--; } else if (this_knob == 3) { value_knob++; } break;
        case 3: if (this_knob == 1) { value_knob++; } else if (this_knob == 2) { value_knob--; } break;
    }
    last_knob = this_knob;
}</pre>
<p>Inside the code that responds to the USB bus&#8217;s input polling requests is code to see if value_knob is less than or greater than zero. This code is shown below. If it&#8217;s less than zero, it sets the volume_down bit in the USB input report that will be sent to the host computer. If it&#8217;s greater than zero, it sets the volume_up bit in the USB input report that will be sent to the host computer. There&#8217;s quite a bit of abstraction and redirection in this code since I did not attempt to simplify it any from the Microchip for Library Applications source code.</p>
<pre>inputReport.report_id = 0x02;
if(BUTTON_IsPressed(BUTTON_USB_DEVICE_HID_KEYBOARD_KEY_0) == true) {
    inputReport.modifiers.media.mute = 1;
}
if(BUTTON_IsPressed(BUTTON_USB_DEVICE_HID_KEYBOARD_KEY_1) == true) {
    inputReport.modifiers.media.volumeDown = 1;
}
if(BUTTON_IsPressed(BUTTON_USB_DEVICE_HID_KEYBOARD_KEY_2) == true) {
    inputReport.modifiers.media.volumeUp = 1;
}</pre>
<p>Inside the BUTTON_isPressed function below is the actual check to see if value_knob is positive or negative. The caller calls BUTTON_isPressed with the value BUTTON_S2 to see if the volume needs to be turned down. If it does, the function returns true and value_knob is incremented to mark that we&#8217;ve handled this volume down request from the user. The caller calls BUTTON_isPressed with the value BUTTON_S3 to see if the volume needs to be turned up. If it does, the function returns true and value_knob is decremented to mark that we&#8217;ve handled this volume down request from the user. BUTTON_S1 implements the mute function.</p>
<p>The incrementing and decrementing of the value_knob variable allows for the encoder to be turned faster than volume updates can be sent over the USB bus. Once the encoder stops turning, the USB bus will eventually catch up and value_knob will settle on zero. The code that generates the USB input reports might need to be updated to send a &#8216;0&#8217; for all the mute / volume keys between presses for this to work properly.</p>
<pre>bool BUTTON_IsPressed(BUTTON button)
{
    switch(button) {
        case BUTTON_S1:
            return ((state1 &gt;= 2) ? true : false);
        case BUTTON_S2:
            if (value_knob &lt; 0) {
                value_knob++;
                return true;
            }
            return false;
        case BUTTON_S3:
            if (value_knob &gt; 0) {
                value_knob--;
                return true;
            }
            return false;
        case BUTTON_NONE:
            return false;
    }
    return false;
}</pre>
<h3>Program the Bootloader</h3>
<div id="attachment_1687" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/programming-bootloader.jpg"><img class="wp-image-1687 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/programming-bootloader-1024x682.jpg" alt="An extremely staged photo of using the Tag-Connect cable to program the USB bootloader." width="640" height="426" /></a><p class="wp-caption-text">An extremely staged photo of using the Tag-Connect cable to program the USB bootloader.</p></div>
<p>Up until this point, I had been using the MPLAB X IDE and my REAL ICE debugger to program and debug the firmware directly on the PIC16F1459. Now  that the firmware was debugged, it was time to go to a more production oriented approach to programming and updating the USB volume knob firmware.</p>
<p>I used the MPLAB X IDE and my REAL ICE programmer to program a USB bootloader into the microcontroller. This allows updates to the firmware to be made directly over the USB bus without taking the USB volume knob apart and without using a dedicated programmer and programmer cable. This is the exact same USB bootloader I used on the one key keyboards and annoying caps lock warning buzzer.</p>
<h3>Program the Firmware</h3>
<div id="attachment_1567" style="width: 451px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/usb-bootloader.png"><img class="size-full wp-image-1567" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/usb-bootloader.png" alt="The main (and only) window of the Microchip Library for Applications USB Bootloader utility." width="441" height="442" /></a><p class="wp-caption-text">The main (and only) window of the Microchip Library for Applications USB Bootloader utility.</p></div>
<p>Once the bootloader was programmed into the PIC16F1459, I could update the USB volume knob firmware using the Microchip Library for Applications (MLA) USB Bootloader Utility. A screenshot of the utility is shown above. The process is as follows:</p>
<ol>
<li>Launch the MLA bootloader utility from the MLA install directory.</li>
<li>Hold down the knob while plugging the USB volume knob into the USB port on the PC.</li>
<li>Wait for the device attached and device ready messages as shown in the dialog box above.</li>
<li>Click the open button in the GUI and select the .hex file from the dist directory inside the USB volume knob firmware directory.</li>
<li>Click the program button to program the firmware into the USB volume knob.</li>
<li>Click the reset button to reset the PIC and launch the application firmware. You can also unplug the USB volume knob then plug it back into the PC. Do not hold down the knob this time.</li>
<li>Test the firmware update by turning the knob to change the volume and pressing the knob to mute / unmute the volume.</li>
</ol>
<h3>Testing</h3>
<div id="attachment_1689" style="width: 263px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/volumes.png"><img class="size-full wp-image-1689" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/volumes.png" alt="Turn the knob and you should see the volume go up and down. Press the knob and you should see the volume mute and unmute." width="253" height="185" /></a><p class="wp-caption-text">Turn the knob and you should see the volume go up and down. Press the knob and you should see the volume mute and unmute.</p></div>
<p>Test the knob before assembling the knob into the enclosure. Turn the knob to change the volume and press the knob to mute / unmute the volume.</p>
<h2>Assembly</h2>
<div id="attachment_1648" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/assembly.jpg"><img class="size-large wp-image-1648" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/assembly-1024x683.jpg" alt="Parts and tools required for assembly. Note how the encoder's ribbon cable is accordion folded into place." width="640" height="427" /></a><p class="wp-caption-text">Parts and tools required for assembly. Note how the encoder&#8217;s ribbon cable is accordion folded into place.</p></div>
<p>Assembly went pretty smoothly. First mount the encoder to the top of the enclosure using the hardware included with the encoder. Next accordion fold the ribbon cable as shown in the photograph above. Connect the encoder cable to the circuit board then press the circuit board against the top of the enclosure. While holding the circuit board in place, thread a few screws through the top of the enclosure and fit the bottom of the enclosure over the screws. Insert the nuts into their recesses on the bottom of the enclosure and tighten all four screws using a 3/64&#8243; or 0.050&#8243; hex driver.</p>
<p>A top view of the assembled USB volume knob is shown in the photo below.</p>
<div id="attachment_1600" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/usb-volume-knob-top.jpg"><img class="size-large wp-image-1600" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/usb-volume-knob-top-1024x682.jpg" alt="The completed USB volume knob project. It uses an off-the-shelf knob and a PIC16F1459 microcontroller. The enclosure is 3D printed." width="640" height="426" /></a><p class="wp-caption-text">The completed USB volume knob project. It uses an off-the-shelf knob and a PIC16F1459 microcontroller. The enclosure is 3D printed.</p></div>
<p>A side view of the rear of the assembled USB volume knob is shown in the photo below.</p>
<div id="attachment_1602" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/usb-volume-knob-rear.jpg"><img class="size-large wp-image-1602" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/usb-volume-knob-rear-1024x682.jpg" alt="Flat section on the rear of the enclosure to accommodate the micro USB connector." width="640" height="426" /></a><p class="wp-caption-text">Flat section on the rear of the enclosure to accommodate the micro USB connector.</p></div>
<p>My desk is kind of slick. I dug through the junk drawer in the kitchen to find some rubber bumpers to place on the bottom of the USB volume knob to keep it in place while turning it. I only had two bumpers left. That&#8217;d be kind of wobbly so I cut the waste material surrounding the two remaining bumpers to size then stuck it on the bottom of the USB volume knob instead:</p>
<div id="attachment_1601" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/10/usb-volume-knob-bottom.jpg"><img class="size-large wp-image-1601" src="https://bikerglen.com/wp/wp-content/uploads/2019/10/usb-volume-knob-bottom-1024x682.jpg" alt="Rubber stuck to bottom of enclosure to keep it from sliding on my desk." width="640" height="426" /></a><p class="wp-caption-text">Rubber stuck to bottom of enclosure to keep it from sliding on my desk.</p></div>
<h2>Design Files</h2>
<p>Design files are available for the enclosure, board, and software in my <a href="https://github.com/bikerglen/usb-volume-knob">Github repository</a> for the project.</p>
<h2>Resources</h2>
<p>The following online resources were helpful while figuring out the needed USB input report descriptors to report desired volume changes to the PC:</p>
<ul>
<li>This Microchip forum post:<br />
<a href="https://www.microchip.com/forums/m618147.aspx"> https://www.microchip.com/forums/m618147.aspx</a></li>
<li>This tutorial on USB HID Report Descriptors:<br />
<a href="https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/">https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/</a></li>
</ul>
<p>Readers may also find the following resources helpful:</p>
<ul>
<li>A good description of the USB HID setup process:<br />
<a href="http://kevincuzner.com/2018/02/02/cross-platform-driverless-usb-the-human-interface-device/">http://kevincuzner.com/2018/02/02/cross-platform-driverless-usb-the-human-interface-device/</a></li>
<li>The USB HID Landing Page:<br />
<a href="https://www.usb.org/hid">https://www.usb.org/hid</a></li>
<li>The USB Device Class Definition for Human Interface Devices (HID):<br />
<a href="https://www.usb.org/sites/default/files/documents/hid1_11.pdf">https://www.usb.org/sites/default/files/documents/hid1_11.pdf</a></li>
<li>The USB HID usage tables:<br />
<a href="https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf">https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/pic16f1459-usb-volume-knob/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updates to the Annoying CAPS LOCK Warning Buzzer</title>
		<link>https://bikerglen.com/blog/updates-to-the-annoying-caps-lock-warning-buzzer/</link>
		<comments>https://bikerglen.com/blog/updates-to-the-annoying-caps-lock-warning-buzzer/#comments</comments>
		<pubDate>Mon, 30 Sep 2019 04:40:56 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[USB Human Interface Device (HID)]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=1548</guid>
		<description><![CDATA[In my first post on the Annoying CAPS LOCK Warning Buzzer, I concluded with a list of future improvements to make to the project. Those updates are now implemented and the Annoying CAPS LOCK Warning Buzzer is more robust than &#8230; <a href="https://bikerglen.com/blog/updates-to-the-annoying-caps-lock-warning-buzzer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_1549" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzer-updates.jpg"><img class="size-large wp-image-1549" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzer-updates-1024x683.jpg" alt="Some minor updates to the annoying caps lock warning buzzer." width="640" height="427" /></a><p class="wp-caption-text">Some new additions to the annoying caps lock warning buzzer (circled in green).</p></div>
<p>In my <a href="https://bikerglen.com/blog/the-annoying-caps-lock-warning-buzzer/">first post on the Annoying CAPS LOCK Warning Buzzer</a>, I concluded with a list of future improvements to make to the project. Those updates are now implemented and the Annoying CAPS LOCK Warning Buzzer is more robust than ever. Read on to find out more about the improvements.</p>
<p><span id="more-1548"></span></p>
<h2>Goals for Improvements</h2>
<p>The list of new features and improvements is pretty short:</p>
<ol>
<li>Include a ground plane on both sides of the board. Route +5V as traces.</li>
<li>Add some basic ESD protection.</li>
<li>Add a button and LED to use with a USB bootloader and firmware update utility to apply firmware updates.</li>
<li>Make the button and LED accessible without disassembling the buzzer.</li>
</ol>
<p>Let&#8217;s run through each of the improvements separately.</p>
<h2>Ground Plane</h2>
<p>On the old board, the ground plane was on the component / top layer with a +5V plane on the bottom. This wasn&#8217;t causing any problems (that I know of) but the ground plane was broken by up all the pads for the surface-mount components. In the new version, both sides of the board contain a filled ground plane with lots of vias to bond the two ground planes to each other. The +5V is now routed as traces on the bottom of the board.</p>
<p>In theory this will reduce noise on the board and improve the electromagnetic compatibility of the board. One day I&#8217;ll have to bring both the old board and new board to work, find a spectrum analyzer and EMC probe set, and learn to make some EMC measurements. In the meantime, at least I didn&#8217;t break anything with the ground plane changes.</p>
<h2>ESD Protection</h2>
<div id="attachment_1558" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/esd-protection.jpg"><img class="wp-image-1558 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/esd-protection-1024x683.jpg" alt="esd-protection" width="640" height="427" /></a><p class="wp-caption-text">That&#8217;s the Nexperia PRTR5V0U2X ESD protection diode below the five millimeter mark on my Adafruit PCB ruler. It&#8217;s small but not any worse than an SOT-23 transistor to hand solder.</p></div>
<p>The second change was to add some basic ESD protection using a Nexperia <a href="https://assets.nexperia.com/documents/data-sheet/PRTR5V0U2X.pdf">PRTR5V0U2X ultra-low capacitance double rail-to-rail ESD protection diode</a>. This single device protects both USB data lines even in the absence of a supply voltage. The device needs to be located as close as possible to the USB connector and be very-well connected to the ground plane of the board.</p>
<h2>Button and LED and Resistor</h2>
<div id="attachment_1560" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/button-led-resistor.jpg"><img class="size-large wp-image-1560" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/button-led-resistor-1024x683.jpg" alt="A KMR2 tactile switch, an 0805 1k resistor, and an 0805 orange LED." width="640" height="427" /></a><p class="wp-caption-text">A KMR2 tactile switch, an 0805 1k resistor, and an 0805 orange LED.</p></div>
<p>The next improvement was to enable the use of the Microchip Library for Applications (MLA) USB bootloader to update the firmware on the Annoying CAPS LOCK Warning Buzzer. At boot time, the USB MLA bootloader checks a pushbutton switch. If the switch is pushed, the bootloader goes into a mode where the application firmware can be updated over USB. If the switch is not pressed, the USB MLA bootloader boots directly into the application firmware.</p>
<p>I needed a small pushbutton switch to use with the bootloader. I searched Digi-Key and Mouser looking for an SMD tactile switch. I found lots of candidates. I finally settled on a C&amp;K Switches KMR211NGLFS tactile switch. If you have an Adafruit Feather M0 board, this is very similar to the reset switch on that board.</p>
<p>The MLA USB bootloader can also blink an LED to indicate the state of the bootloader. I decided to take advantage of this feature. I selected a Dialight 599-0130-007F 0805 SMD orange LED. Any color would work but orange is somewhat different than the typical red or green LEDs on projects. Finally, I needed a current limiting resistor for the LED. I went with a small 1k 5% 0805 SMD resistor.</p>
<h2>Enclosure Modifications</h2>
<div id="attachment_1563" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/caps-lock-buzzer-v2-v5.png"><img class="size-large wp-image-1563" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/caps-lock-buzzer-v2-v5-1024x683.png" alt="The updated enclosure. Two two millimeter diameter holes on the bottom allow access to the tactile switch and LED." width="640" height="427" /></a><p class="wp-caption-text">The updated enclosure. Two two millimeter diameter holes on the bottom allow access to the tactile switch and LED.</p></div>
<p>To make the pushbutton and LED accessible without having to disassemble the warning buzzer, I added two 2 mm holes to the bottom of the enclosure. When the board is placed in the enclosure, one hole is directly over the pushbutton and the other hole is directly over the LED. The pushbutton can be pushed via a small screwdriver or paper clip. The LED light is visible by turning the buzzer upside down.</p>
<h2>Updated Schematic</h2>
<div id="attachment_1564" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/caps-lock-buzzer-v2-schematic.png"><img class="size-large wp-image-1564" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/caps-lock-buzzer-v2-schematic-1024x764.png" alt="Updated schematic. The U2, SW1, R2, and USER1 LED are new to this version of the design." width="640" height="478" /></a><p class="wp-caption-text">Updated schematic. The U2, SW1, R2, and USER1 LED are new to this version of the design.</p></div>
<p>The schematic above show the updates made for the second version of the warning buzzer. U2, SW1, R2, and the USER1 LED are new to this version of the design.</p>
<h2>Updated Boards</h2>
<div id="attachment_1562" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/new-vs-old-boards.jpg"><img class="size-large wp-image-1562" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/new-vs-old-boards-1024x683.jpg" alt="Old board on the left. New board on the right." width="640" height="427" /></a><p class="wp-caption-text">Old board on the left. New board on the right.</p></div>
<p>The photo above shows the old version of the design on the left and the new version of the design on the right. Most of components and traces are in the same place. The current limiting resistor for LED D2 / USER1 is on the reverse side of the board. Notice the many vias on the new design of the board. These vias connect the ground planes on each side of the board together.</p>
<h2>Updated Enclosure</h2>
<div id="attachment_1597" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzer-back-1.jpg"><img class="size-large wp-image-1597" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzer-back-1-1024x682.jpg" alt="The bottom of the annoying CAPS LOCK warning buzzer with the modifications to expose the LED and pushbutton." width="640" height="426" /></a><p class="wp-caption-text">The bottom of the annoying CAPS LOCK warning buzzer with the modifications to expose the LED and pushbutton.</p></div>
<p>The bottom of the updated enclosure is shown in the above photo. The hole with the orange glow is the LED. The other hole is for accessing the pushbutton swtich.</p>
<h2>Updated BOM</h2>
<p>The components that are new to the second version of the design are listed in the table below. You&#8217;ll also need a second 0805 1k 5% resistor.</p>
<table width="994">
<tbody>
<tr>
<td width="42">Line #</td>
<td width="126">Mfr. #</td>
<td width="126">Manufacturer</td>
<td width="508">Description</td>
<td width="70">Order Qty.</td>
<td width="122">Price (USD)</td>
</tr>
<tr>
<td>1</td>
<td>KMR211NGLFS</td>
<td>C&amp;K Switches</td>
<td>Tactile Switch</td>
<td>1</td>
<td>$0.52</td>
</tr>
<tr>
<td>2</td>
<td>PRTR5V0U2X,215</td>
<td>Nexperia</td>
<td>5.5V ESD Protection Diodes</td>
<td>1</td>
<td>$0.51</td>
</tr>
<tr>
<td>3</td>
<td>599-0130-007F</td>
<td>Dialight</td>
<td>0805 Orange LED</td>
<td>1</td>
<td>$0.26</td>
</tr>
</tbody>
</table>
<h2>Using the Bootloader</h2>
<div id="attachment_1567" style="width: 451px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/usb-bootloader.png"><img class="size-full wp-image-1567" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/usb-bootloader.png" alt="The main (and only) window of the Microchip Library for Applications USB Bootloader utility." width="441" height="442" /></a><p class="wp-caption-text">The main (and only) window of the Microchip Library for Applications USB Bootloader utility.</p></div>
<p>The MLA USB bootloader must be programmed using a PIC programmer such as the PICkit 4 or ICD 4 and the MPLAB X IDE or IPE. Once the bootloader is programmed, the bootloader can be used to update the application firmware. To update the firmware:</p>
<ol>
<li>Launch the MLA bootloader utility from the MLA install directory.</li>
<li>Hold down the button using a paper clip or small screwdriver while plugging the warning buzzer into the USB port on the PC. Be sure to push on the pushbbutton; not the LED.</li>
<li>Wait for the device attached and device ready messages as shown in the dialog box above.</li>
<li>Click the open button in the GUI and select the .hex file from the dist directory inside the caps lock buzzer firmware directory.</li>
<li>Click the program button to program the firmware into the warning buzzer.</li>
<li>Click the reset button to reset the PIC and launch the application firmware. You can also unplug the warning buzzer then plug it back into the PC. Do not hold down the pushbutton this time.</li>
<li>Test the firmware update by toggling the CAPS LOCK key on the keyboard to turn the warning buzzer off and on.</li>
</ol>
<h2>Design Files</h2>
<p>All design files are in my <a href="https://github.com/bikerglen/caps-lock-buzzer">caps-lock-buzzer repository on github</a>.</p>
<p>The v2 schematic and board files:</p>
<ul>
<li><a href="https://github.com/bikerglen/caps-lock-buzzer/blob/master/boards/v2/caps-lock-buzzer.sch">Schematic</a></li>
<li><a href="https://github.com/bikerglen/caps-lock-buzzer/blob/master/boards/v2/caps-lock-buzzer.brd">Board</a></li>
</ul>
<p>The Fusion 360 Archive and STL files for the enclosure:</p>
<ul>
<li><a href="https://github.com/bikerglen/caps-lock-buzzer/blob/master/enclosure/v2/caps-lock-buzzer-v2-v5.f3z">Fusion 360 Archive</a></li>
<li><a href="https://github.com/bikerglen/caps-lock-buzzer/blob/master/enclosure/v2/caps-lock-buzzer-v2-top.stl">Enclosure Top STL File</a></li>
<li><a href="https://github.com/bikerglen/caps-lock-buzzer/blob/master/enclosure/v2/caps-lock-buzzer-v2-bottom.stl">Enclosure Bottom STL File</a></li>
</ul>
<p>The updated software:</p>
<ul>
<li><a href="https://github.com/bikerglen/caps-lock-buzzer/blob/master/software/HID_Bootloader_-_PIC16F1459_-_v5.10.zip">PIC16F1459 Bootloader Project</a> for use with this Hardware</li>
<li><a href="https://github.com/bikerglen/caps-lock-buzzer/tree/master/software/caps-lock-buzzer-pic16f1459-btld.X">Caps Lock Buzzer Firmware</a> for use with the Bootloader and this Hardware</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/updates-to-the-annoying-caps-lock-warning-buzzer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Annoying CAPS LOCK Warning Buzzer</title>
		<link>https://bikerglen.com/blog/the-annoying-caps-lock-warning-buzzer/</link>
		<comments>https://bikerglen.com/blog/the-annoying-caps-lock-warning-buzzer/#comments</comments>
		<pubDate>Sun, 15 Sep 2019 16:50:46 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[USB Human Interface Device (HID)]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=1395</guid>
		<description><![CDATA[The only way to make CAPS LOCK even more annoying was to make it audible! Now never type a password in all upper case, join 500 lines together in vi, or turn a harmless forum post into an ANGRY SCREED &#8230; <a href="https://bikerglen.com/blog/the-annoying-caps-lock-warning-buzzer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><iframe src="https://www.youtube.com/embed/-V8hzF0jGLM" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>
<p>The only way to make CAPS LOCK even more annoying was to make it audible! Now never type a password in all upper case, join 500 lines together in vi, or turn a harmless forum post into an ANGRY SCREED without warning again! This project uses a PIC16F1459 to monitor the USB output report containing the CAPS LOCK status from the connected PC. When CAPS LOCK is enabled, the PIC turns on an annoying warning buzzer. Read on to build your own.</p>
<p><span id="more-1395"></span></p>
<h2>Motivation</h2>
<div id="attachment_1407" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzer.jpg"><img class="size-large wp-image-1407" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzer-1024x775.jpg" alt="The completed annoying caps lock warning buzzer." width="640" height="484" /></a><p class="wp-caption-text">The completed annoying caps lock warning buzzer.</p></div>
<p>The CAPS LOCK key is the most annoying key on the keyboard. It&#8217;s always getting in the way. Ever enter a password with CAPS LOCK enabled? Enough times to get locked out of your account? Yeah, me too.</p>
<p>The only way to make CAPS LOCK even more annoying was to make it loud! As a side effect, you&#8217;ll always know when CAPS LOCK is enabled so entering the wrong password, joining lines when you&#8217;re just trying to scroll down in vi, or answering an entire email in ANGRY SCREED format should be history.</p>
<h2>Derived from the One Key USB Keyboard</h2>
<div class="mceTemp">
<div id="attachment_948" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00651_crop2.jpg"><img class="wp-image-948 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00651_crop2-1024x682.jpg" alt="The single ESC key USB keyboard." width="640" height="426" /></a><p class="wp-caption-text">The single ESC key USB keyboard.</p></div>
<p>This project is almost identical to my <a href="https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/">one key USB keyboard</a> project. The key switch and LED have been replaced by a transistor and a buzzer. The enclosure has a round hole instead of a square hole. The software previously turned on an LED when CAPS LOCK was set. Now it uses a different pin to enable the buzzer instead. A few small changes yield an entirely different result. The selecting parts section below is repeated verbatim from that design. Skip forward to the schematic section if you&#8217;ve already read it.</p>
</div>
<h2>Selecting Parts</h2>
<h3>Picking a USB Microcontroller</h3>
<p>I chose a PIC16F1459 in an SSOP-20 package for the microcontroller. The PIC16F145x family provides a minimal parts count solution to implementing the USB 2.0 standard. No external oscillator is required because this micro has an internal 48MHz oscillator and uses active clock tuning to fine-tune the internal oscillator frequency to the recovered clock from the USB host. This micro, a USB connector, and three capacitors are all that are needed to implement a fully-functional USB 2.0 device.</p>
<div id="attachment_930" style="width: 1012px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/min-sch.png"><img class="wp-image-930 size-full" src="https://bikerglen.com/wp/wp-content/uploads/2018/05/min-sch.png" alt="Minimal PIC16F1459 schematic for USB 2.0 operation." width="1002" height="351" /></a><p class="wp-caption-text">Minimal PIC16F1459 schematic for USB 2.0 operation.</p></div>
<p>Once I selected the microcontroller, I needed to pick a package for the microcontroller. The PIC16F1459 is available in DIP, SOIC, SSOP, and QFN packages. I chose the SSOP-20 package. The two larger packages were too big to fit in the allocated board space and the QFN package, though smaller, would be considerably more difficult to hand solder.</p>
<h3>The USB Connector</h3>
<p>Next up was to find a suitable USB Micro-B connector. Since the entire board was to be hand soldered, I wanted a connector with locating pins to position the connector on the board while I soldered it and with enough room between the connector housing and the five signals pins that I could easily see what I was doing with a microscope. I ordered a bunch of USB Micro-B connectors, examined each of them, and finally found a Wurth Electronics connector that met my needs.</p>
<div id="attachment_937" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC_2096_crop.jpg"><img class="wp-image-937 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2018/05/DSC_2096_crop-1024x681.jpg" alt="DSC_2096_crop" width="640" height="426" /></a><p class="wp-caption-text">Wurth Electronics USB Micro-B Receptacle part number 629105136821. It has little black plastic posts to keep the connector centered while soldering and plenty of room between the shell and pins for the soldering iron, flux, solder, and inevitably, wick.</p></div>
<h2>Schematic</h2>
<div id="attachment_1408" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzer-schematic.png"><img class="size-large wp-image-1408" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzer-schematic-1024x764.png" alt="Schematic of the annoying caps lock warning buzzer." width="640" height="478" /></a><p class="wp-caption-text">Schematic of the annoying caps lock warning buzzer.</p></div>
<p>Pictured above is the complete schematic for the caps lock buzzer. Let&#8217;s take a closer look at the buzzer, the transistor switch, and programming the PIC16F1459.</p>
<h3>The Buzzer</h3>
<div id="attachment_1410" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzers.jpg"><img class="size-large wp-image-1410" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/buzzers-1024x682.jpg" alt="Buzzer candidates. I went the smallest of the three." width="640" height="426" /></a><p class="wp-caption-text">Buzzer candidates. I went with the smallest of the three.</p></div>
<p>The buzzer needed to run from 5V since that is the USB bus voltage. The current consumption needed to be less than 1 A to prevent overloading the USB bus. I selected a through-hole buzzer to make aligning the buzzer with the board and consequently the hole in the 3D printed enclosure simpler. The final criteria was to select a buzzer that fit in the existing one-key keyboard enclosure without protruding too much. I found a buzzer that ran from 5V, consumed 35 mA, and only protruded out of the existing enclosure design by 0.42 mm. The frequency is 2.7 kHz with an SPL of 80 dBA.</p>
<h3>Designing the Transistor Switch</h3>
<p>The transistor switch circuit is a pretty basic transistor switch circuit. When the PIC drives the PWM0 signal, current flows from the base through the emitter of the transistor. This current turns on the transistor and a current conducts from the positive supply rail, through the buzzer, and from the collector to the emitter of the transistor.</p>
<p>R1 is selected to drive the transistor into the saturation region and to minimize the heat dissipation in the transistor. A 1k resistor usually works well but let&#8217;s calculate the resulting current with a 1k resistor to double check. To calculate the minimum base-emitter current, we need to know the worst-case output voltage at the output of the PIC and the worst-case base-emitter saturation voltage of the transistor.</p>
<p>From the data sheet, the V(OH) of the PIC is V(DD)-0.7 volts and the V(BE)(SAT) of the transistor is 1.0 V. The minimum base-emitter current will be (5 &#8211; 0.7 &#8211; 1.0 V) / (1 k) = 3.3 mA. The current consumption of the selected buzzer is 35 mA and the h(fe) of the transistor is 200. The base current required to drive the transistor into the saturation region is 35 mA / 200 = 0.175 mA.</p>
<p>The transistor will definitely be operating in the saturation region when the PIC turns on the PWM0 output signal. We could use a higher resistor if we want to further minimize the heat dissipation of the transistor but 3.5 mA is much less than the maximum base-emitter current of the transistor and I have a lot of 0805 1k resistors in my parts box.</p>
<p>Diode D1 is present to protect the transistor from the flyback voltage generated by the inductive load of the buzzer when the transistor is switched off. The voltage that is created at the collector of the transistor will be safely sunk to the positive supply rail rather than building up to a level that could potentially destroy the transistor.</p>
<h3>Programming the PIC16F1459</h3>
<div id="attachment_1414" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/IMG_20190310_162519.jpg"><img class="size-large wp-image-1414" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/IMG_20190310_162519-1024x576.jpg" alt="The old way of programming." width="640" height="360" /></a><p class="wp-caption-text">The old way of programming.</p></div>
<p>In previous designs, I&#8217;ve used a row of plated holes designed to make with a six-position, single-row, square-post, 0.1&#8243; pitch header to connect to the PIC programmer and debugger (shown above). This works well but takes up a lot of area on both sides of the board.</p>
<div id="attachment_1412" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/tag-connect.jpg"><img class="wp-image-1412 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/tag-connect-1024x682.jpg" alt="Tag-Connect programming cable connected to the programming pins on the circuit board,." width="640" height="426" /></a><p class="wp-caption-text">The new way: a Tag-Connect programming cable connected to the programming pins on the circuit board.</p></div>
<p>For this design, I&#8217;m using a <a href="http://www.tag-connect.com/">TAG-Connect cable</a> to connect the programmer/debugger to the board (shown above). This uses roughly half the area of the 0.1&#8243; header and only requires holes for three small alignment pins.</p>
<h2>Board</h2>
<div id="attachment_1419" style="width: 857px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/boards1.png"><img class="wp-image-1419 size-full" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/boards1.png" alt="boards" width="847" height="387" /></a><p class="wp-caption-text">A rendering of the boards from OSHPark.com.</p></div>
<p>Shown above is a rendering of the completed board design. The board outline is identical to the board outline of the one-key keyboard board outline. The layout is very similar as well. Note the footprint for the Tag-Connect programming cable to the left of the buzzer on the bottom of the board.</p>
<h2>Software</h2>
<h3>USB Output Reports and the CAPS LOCK State</h3>
<p>The CAPS LOCK state of a keyboard attached to a PC is maintained by the PC; not the keyboard. If you attach five keyboards to a PC and hit the CAPS LOCK key on one keyboard, the CAPS LOCK light on all five attached keyboards will illuminate. You can then hit the CAPS LOCK key on a different keyboard and all the CAPS LOCK lights will turn off.</p>
<p>This is implemented by the connected PC sending a periodic USB output report to all the attached keyboards. Inside this USB output report is a bit indicating the current state of the CAPS LOCK, NUM LOCK, and SCROLL LOCK keys. Attached keyboards examine these bits when the USB output report is received and turn their lights on and off according to these bits.</p>
<p>The annoying caps lock buzzer looks like a keyboard to the host PC except it doesn&#8217;t have any keys. The host sends the periodic USB output reports to our &#8220;keyboard&#8221; and when the USB output report is received, our &#8220;keyboard&#8221; turns the buzzer on or off to match the state of the CAPS LOCK bit in the USB output report.</p>
<h3>Writing the Software</h3>
<p>The software for this design is based on the <a href="https://www.microchip.com/mplab/microchip-libraries-for-applications">Microchip Library for Applications</a> (MLA) USB HID demo for low-pin count PIC micrcontrollers. In the unmodified version of the software, the software turns an LED on or off based on the USB output reports described in the previous section.</p>
<p>To make the annoying caps lock warning buzzer, I only had to change the pin used to turn the LED on or off from the default in the software to pin RC2, disable sending any pressed keys to the host PC, and recompile.</p>
<h2>Initial Bring Up</h2>
<div id="attachment_1424" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/power-supply.jpg"><img class="wp-image-1424 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/power-supply-1024x683.jpg" alt="power-supply" width="640" height="427" /></a><p class="wp-caption-text">One milliamp with an unprogrammed microcontroller and the buzzer turned off is about right. It&#8217;s now safe to connect the buzzer to the PC without worrying about damaging the PC.</p></div>
<p>For the initial bring up and programming, I used a <a href="https://www.keysight.com/us/en/products/dc-power-supplies/bench-power-supplies/e36300-series-triple-output-power-supply-80-160w.html">Keysight 36312A DC power supply</a> and a <a href="http://luislab.com/99-double-banana-plug-to-usb-a">double-banana plug to USB Type A adapter from Luislab</a> (shown above). I set the DC power supply to 5 Volts and set the current limit to 50 mA. This way if I accidentally shorted power to ground while soldering or there was a defect in the board, the power supply would go into current limit mode at a safe limit rather than causing damage to the board or my PC.</p>
<p>The USB Type A ports on a PC are required by the USB spec to have a self-resetting PTC fuse on them to protect the PC against damage if the connected USB device or cable has a short or draws too much current. The trip point for the thermal fuse is 1 A. In theory, I could plug the board into my PC for the initial bring up but the PC&#8217;s USB port is really not designed to limit current. It&#8217;s a safer option for my design and my PC to use a current-limited DC power supply for the initial bring up than to use one of my PC&#8217;s USB ports or a phone charger.</p>
<h2>Measurements</h2>
<h3>Verifying the Transistor Switch is Operating in the Saturation Region</h3>
<div id="attachment_1422" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/IMG_20190915_094831.jpg"><img class="size-large wp-image-1422" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/IMG_20190915_094831-1024x576.jpg" alt="Using my 34461A to measure V(CE)." width="640" height="360" /></a><p class="wp-caption-text">Using my 34461A to measure V(CE).</p></div>
<p>After bringing up the board and programming the microcontroller, I wanted to verify the transistor in the transistor switch was operating its saturation region. To do this, I used a <a href="https://www.keysight.com/en/pdx-2891615-pn-34461A/digital-multimeter-6-digit-truevolt-dmm?cc=US&amp;lc=eng">Keysight 34461A DMM</a> to measure the voltage between the collector and emitter of the transistor while the buzzer was on. The measurement was 4.1515 mV. The transistor is clearly operating in its saturation region. If it had not been, I would have needed to lower the value of R1 to increase the base-emitter current.</p>
<h3>Current Measurements</h3>
<div id="attachment_1513" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/probe.jpg"><img class="size-large wp-image-1513" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/probe-1024x683.jpg" alt="USB current probe board." width="640" height="427" /></a><p class="wp-caption-text">USB current probe board.</p></div>
<p>To measure the current I built a USB current probe board. This board connects the USB D+, D-, and ground lines directly from input to output. The +5V USB power from the PC is brought out to a red banana jack and the +5 power to the target is brought out to a black banana jack. A DMM in current measuring mode can then be connected to the two binding posts and used to measure the current consumption of the USB device.</p>
<div id="attachment_1512" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/on.jpg"><img class="size-large wp-image-1512" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/on-1024x670.jpg" alt="Current measurement with the buzzer on." width="640" height="419" /></a><p class="wp-caption-text">Current measurement with the buzzer on.</p></div>
<p>To measure the current, I connected the USB Type A plug on the current probe board to my PC using a USB extension. I connected the annoying CAPS LOCK warning buzzer to the the USB Type A receptacle on the current probe board using a USB A to Micro B cable. I then connected the banana jacks on the current probe board to the the low range current measurement inputs on my <a href="https://www.keysight.com/en/pdx-2882338-pn-U1272A/handheld-digital-multimeter-4-digit-ip54?cc=US&amp;lc=eng">Keysight U1272A</a> DMM.</p>
<p>With the buzzer off and the annoying CAPS LOCK warning buzzer enumerated on the USB bus on my PC, I measured a current of 8.062 mA. I then engaged CAPS LOCK on my PC and measured the current with the buzzer on. With the buzzer on, I measured a current of 35.64 mA. Both of these numbers are well below the maximum a USB Type A port on a PC can supply and reasonably match the expected values in the data sheets for the PIC16F1459 microcontroller and the buzzer.</p>
<p>(Disclaimer: I work for Keysight. The E36312A was purchased through our employee discount program. The 34461A and U1272A were purchased at full price before my employment there.)</p>
<h2>Enclosure</h2>
<div id="attachment_1429" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/09/enclosure.jpg"><img class="size-large wp-image-1429" src="https://bikerglen.com/wp/wp-content/uploads/2019/09/enclosure-1024x683.jpg" alt="The one-key USB keyboard enclosure modified for the buzzer." width="640" height="427" /></a><p class="wp-caption-text">The one-key USB keyboard enclosure modified for the buzzer.</p></div>
<p>The enclosure for this project is identical to the enclosure for the one-key USB keyboard project except the rectangular cutout has been replaced by a 10 mm diameter circular hole.</p>
<h2>Future Improvements</h2>
<p>I need to place a button and LED on the board and make them accessible from the bottom of the enclosure so that I can implement a USB bootloader for updating the buzzer firmware. I also need to add a <a href="https://www.nexperia.com/products/esd-protection-tvs-filtering-and-signal-conditioning/low-capacitance-esd-protection-for-high-speed-interfaces/PRTR5V0U2X.html">Nexperia PRTR5V0U2X ESD protection diode</a> to the USB D+ and D- data signals.</p>
<p>Breaking Update: The improvements have been made! They&#8217;re described in <a href="https://bikerglen.com/blog/updates-to-the-annoying-caps-lock-warning-buzzer/">this post</a>.</p>
<h2>BOM</h2>
<p>Here&#8217;s the BOM for this project. This BOM is also present in the design files for this project on Github. See the next section for a link.</p>
<table width="994">
<tbody>
<tr>
<td width="42">Line #</td>
<td width="126">Mfr. #</td>
<td width="126">Manufacturer</td>
<td width="508">Description</td>
<td width="70">Order Qty.</td>
<td width="122">Price (USD)</td>
</tr>
<tr>
<td>1</td>
<td>C1206C474K5RACTU</td>
<td>KEMET</td>
<td>50V 0.47uF X7R 1206 10%</td>
<td>1</td>
<td>$0.23</td>
</tr>
<tr>
<td>2</td>
<td>C1210C105K4PACTU</td>
<td>KEMET</td>
<td>16V 1uF X5R 1210 10%</td>
<td>1</td>
<td>$1.26</td>
</tr>
<tr>
<td>3</td>
<td>C1206C104J4RACTU</td>
<td>KEMET</td>
<td>16V 0.1uF X7R 1206 5%</td>
<td>1</td>
<td>$0.56</td>
</tr>
<tr>
<td>4</td>
<td>629105136821</td>
<td>Wurth Elektronik</td>
<td>USB Micro B</td>
<td>1</td>
<td>$1.21</td>
</tr>
<tr>
<td>5</td>
<td>PIC16F1459-I/SS</td>
<td>Microchip</td>
<td>8-bit MCU</td>
<td>1</td>
<td>$1.66</td>
</tr>
<tr>
<td>6</td>
<td>1N4148W-7-F</td>
<td>Diodes Incorporated</td>
<td>General Purpose Diode</td>
<td>1</td>
<td>$0.16</td>
</tr>
<tr>
<td>7</td>
<td>FMMT619TA</td>
<td>Diodes Incorporated</td>
<td>BJT NPN</td>
<td>1</td>
<td>$0.55</td>
</tr>
<tr>
<td>8</td>
<td>CR0805-JW-102ELF</td>
<td>Bourns</td>
<td>0805 1K 5%</td>
<td>1</td>
<td>$0.10</td>
</tr>
<tr>
<td>9</td>
<td>CX-0905C</td>
<td>CUI Inc.</td>
<td>Buzzer</td>
<td>1</td>
<td>$2.43</td>
</tr>
</tbody>
</table>
<h2>Design Files</h2>
<p>All of the design files for this project can be found in the <a href="https://github.com/bikerglen/caps-lock-buzzer">project&#8217;s repository</a> on Github.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/the-annoying-caps-lock-warning-buzzer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PIC16F1459 USB Stack Light Controller</title>
		<link>https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/</link>
		<comments>https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/#comments</comments>
		<pubDate>Sun, 14 Apr 2019 02:28:34 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>
		<category><![CDATA[USB]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=1165</guid>
		<description><![CDATA[After using the PIC16F1459 to build numerous USB HID input devices including a giant keyboard, a tiny keyboard, and a big red button, it was time to see if the PIC16F1459 could be used to control outputs too. Sticking with &#8230; <a href="https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_1177" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00840-cropped-3.jpg"><img class="size-large wp-image-1177" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00840-cropped-3-1024x683.jpg" alt="    PIC16F1459-based USB industrial stack light controller. Looks pretty but will it work?" width="640" height="427" /></a><p class="wp-caption-text">PIC16F1459-based USB industrial stack light controller. Looks pretty but will it work?</p></div>
<p>After using the PIC16F1459 to build numerous USB HID input devices including a <a href="https://bikerglen.com/blog/building-a-giant-usb-three-key-mechanical-keyboard/">giant keyboard</a>, <a href="https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/">a tiny keyboard</a>, and <a href="https://bikerglen.com/blog/usb-big-red-button/">a big red button</a>, it was time to see if the PIC16F1459 could be used to control outputs too. Sticking with the industrial theme, I chose to build a USB controller for a, um, stack of industrial stack lights.</p>
<p><span id="more-1165"></span></p>
<h2>Industrial Stack Lights</h2>
<div id="attachment_1174" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00814-cropped-resized.jpg"><img class="size-large wp-image-1174" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00814-cropped-resized-1024x683.jpg" alt="A variety of Allen-Bradley 855T industrial stack lights and parts I found on eBay." width="640" height="427" /></a><p class="wp-caption-text">A variety of Allen-Bradley 855T industrial stack lights and parts I found on eBay.</p></div>
<p><a href="https://en.wikipedia.org/wiki/Stack_light">Industrial stack lights</a> are usually used to indicate the status of machines on production lines. Green could indicate all is functioning normally, yellow could mean the machine is running low on input material, and red could indicate the machine jammed and needs intervention.</p>
<p>If you buy them <a href="https://www.automationdirect.com/adc/overview/catalog/stacklights">new</a>, they can be quite expensive&#8211;especially for a project you&#8217;re going to build, most likely use once, and then set on a shelf. Instead, consider eBay. It&#8217;s a great place to find slightly used to new-ish industrial buttons, indicators, and stack lights on the cheap.</p>
<p>The key parameters when searching for stack lights are operating voltage, usually either 24VDC or 120VAC, and bulb type, either incandescent or LED. I recommend the 24VDC LED versions if you can find them.</p>
<h2>Controlling Hardware with USB</h2>
<p>For a simple, quick project such as this one, one does not want to have to write a custom USB driver for a Mac, PC, or Linux box. The best way to avoid writing a custom driver is to use an existing USB device class that lends itself to controlling custom hardware. The USB Human Interface Device (HID) and USB Communication Device Class (CDC) device classes both support controlling custom hardware.</p>
<h3>USB HID Output Reports</h3>
<p><a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/introduction-to-hid-concepts#reports">USB HID output reports</a> are data blobs sent from an application running on a PC or other USB host to a USB HID device such as a keyboard or mouse or game controller. If you have a fancy gaming keyboard with tons of RGB LED lights, the application software on the PC could use USB HID output reports to control the state of the RGB LEDs on the keyboard. As another example, the Sony PS3 SixAxis DualShock controllers use USB HID output reports to activate the shaking of the controller.</p>
<p>The cool part about USB HID output reports is the USD HID device receives complete packets. There&#8217;s no parsing of a data stream required. You get a complete packet, pull the bytes out of the packet, and control the hardware as necessary. The downside is USB HID output reports need application software running on the USB host PC to send them which, of course, requires developing said application software.</p>
<h3>USB CDC</h3>
<p>Another USB device class that is suitable for controlling external hardware is the USB CDC device class. The USB CDC device class is typically used to implement <a href="https://www.ftdichip.com/Products/Cables/USBTTLSerial.htm">USB to serial converters</a> or to implement serial consoles on development boards like the <a href="https://www.adafruit.com/feather">Adafruit Feather</a> series.</p>
<p>The upside with the USB CDC device class is you can launch a serial console and immediately begin interacting with your hardware. No application development required. The downside is you have to have software on your hardware that parses the faux serial data stream to find the bytes that should control your hardware.</p>
<h3>Selected Method</h3>
<p>I decided to go with the USB CDC method for this project. I did not want to have to develop a custom application on my PC to control the hardware. Being able to launch a serial console and immediately interact with the hardware was very appealing. One day I will have to try sending a USB HID output report from a PC. Just not today. I&#8217;ve sent them from numerous embedded USB hosts; just never a PC USB host.</p>
<h2>Enclosure Design</h2>
<p>After thinking about the project some, I decided I wanted a red, amber, and green light, a cap, and the 10cm pole base. The 10cm pole base would mount to the top of an enclosure that holds the USB electronics. I found the stack light parts on eBay, ordered them, found their data sheets and 3D models on the Rockwell Automation / Allen-Bradley website, and set about designing the enclosure for the electronics using Autodesk Fusion 360.</p>
<h3>Parameterized 3D Modeling</h3>
<p>Fusion 360 supports parameterized 3D models. With a parameterized model, you create a bunch of parameters, assign the parameters default values, then use the names of those parameters in place of numeric values as you create the 3D model. It requires some planning ahead but makes changing the height or diameter or wall thickness of your model later almost trivial.</p>
<p>For this enclosure, I knew it&#8217;d have a diameter, a height, a wall thickness, four screw holes, four recesses to hold some M5 nuts, and those screw holes would be a certain distance from the center of the base. Here&#8217;s the parameters I created using the modify -&gt; change parameters command in the model view:</p>
<div id="attachment_1181" style="width: 1003px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/parameters.png"><img class="size-full wp-image-1181" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/parameters.png" alt="USB industrial stack light enclosure parameters." width="993" height="504" /></a><p class="wp-caption-text">USB industrial stack light enclosure parameters.</p></div>
<p>At this point, you&#8217;re ready to create your 3D model. Create a component, create a sketch inside the component, then as you&#8217;re laying out the initial geometry of your model on the sketch, use the parameter names from above instead of a numeric value for each dimension on the sketch. If you come back later and change a parameter, the dimensions on the sketch and the 3D bodies created from the sketch will update automatically.</p>
<p>Of all the parameters shown in the dialog box above, the enclosure height parameter was the most important and the one subject to changing the most. I did not know how tall the enclosure needed to be until I had the PCB designed and the connectors and screws for the project picked out.</p>
<h3>Initial Design of the Enclosure</h3>
<p>After creating the parameters, drawing a sketch based on the parameters, and extruding parts of the sketch, the enclosure looked like the images in the pictures below. This is not the final version of the enclosure, however, because there&#8217;s no place for the USB and power connectors.</p>
<p>Based on the dimensions in the data sheet for the 855T series 10 cm stack light base, the four posts inside the enclosure image below line up with the four screw holes in the stack light 10cm base. M5 screws are threaded through the 10 cm base, into these posts in the enclosure, then secured with a nut in the hexagonal recess in the bottom of the enclosure.</p>
<div id="attachment_1188" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-no-notch.png"><img class="size-large wp-image-1188" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-no-notch-1024x690.png" alt="An early version of the enclosure as viewed from above." width="640" height="431" /></a><p class="wp-caption-text">An early version of the enclosure as viewed from above.</p></div>
<p>Here&#8217;s the same version of the enclosure as viewed from the bottom. The hexagonal recesses each hold an M5 nut that mates with an M5 screw threaded through the stack light 10 cm base and the enclosure. The smaller posts and nut recesses are for 2-56 x 1/4&#8243; screws to hold a circuit board in the bottom of the enclosure. Based on the data sheet and 3D model for the stack light base, I decided to adjust the height of the enclosure to 17mm. This would allow the use of M5 x 20mm socket cap screws to hold everything together.</p>
<div id="attachment_1189" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-bottom-no-notch.png"><img class="size-large wp-image-1189" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-bottom-no-notch-1024x690.png" alt="An early version of the enclosure as viewed from the bottom." width="640" height="431" /></a><p class="wp-caption-text">An early version of the enclosure as viewed from the bottom.</p></div>
<h3>Electrical / Mechanical Codesign</h3>
<p>At this point, I had an enclosure that was sized to mount underneath the stack light&#8217;s base. The enclosure would be secured with four M5 x 20mm screws and M5 nuts. The next step was to design a circuit board to hold the electronics. The circuit board would also need a power connector for +24VDC to power the stack lights and a USB connector to talk to the host PC.</p>
<p>I used the inspect -&gt; measure command in the model view to measure the internal dimensions of the enclosure. The circuit board needed to be 24mm wide to fit between the posts and could be up to about 60mm long. I drew a board outline in Autodesk Eagle with these dimensions and placed a Phoenix 1803277 connector for +24VDC power and a Wurth 629105136821 connector for the USB connection to the PC on the board.</p>
<p>I then used Eagle to export a 3D model of the board into Fusion 360. I placed the board inside the enclosure and looked at the alignment of the square edge of the board, the rounded interior of the enclosure, and the placement of the connectors. They fit vertically but there was no way a USB cable could mate with the USB connector or the power input&#8217;s pluggable screw terminal block could mate with its header connector.</p>
<h3>The Connector Notch</h3>
<p>At this point it became obvious that the outside of the enclosure needed to be flat where the connectors protruded through the enclosure. Also, the inside of the enclosure had to be flat where the circuit board butted up against it. With a bit of work, I created a 1.5mm thick flat wall offset 0.5 mm from the edge of the circuit board.</p>
<p>This almost worked. The problem is that where the stack light base met the enclosure there was now a gap. The final solution was to include a 2mm tall circular portion above and below the flat portion as shown in the image below. This allowed the circuit board to butt up against a flat interior wall, it allowed the connectors to mate without interference, and it had a good fit to the stack light base when the stack light base was mounted to the top of the enclosure. The bottom 2mm circular portion is just for symmetry and aesthetics.</p>
<p>The image below shows the final notched enclosure and the circuit board with connectors mounted inside the enclosure. The cutouts for the connectors were created using the same offset plane, sketch, and extrude technique that I used to create the connector cut outs for the <a href="https://bikerglen.com/blog/homebrew-rgb-led-light/">DMX RGB light project</a>.</p>
<div id="attachment_1187" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-notch.png"><img class="wp-image-1187 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-notch-1024x690.png" alt="stack mount base v22 notch" width="640" height="431" /></a><p class="wp-caption-text">View of the model from the back which shows the notch in the enclosure and the connectors protruding through the notch.</p></div>
<p>The last item to do before ordering a 3D print was to find 3D models of the connectors, stack light base, and USB cable then assemble the stack light and enclosure in Fusion 360 to check that everything fit together without interference. The image below shows everything assembled. If the Phoenix connector had not cleared the circular part of the enclosure directly above it, I would have needed to adjust the height parameter to 19mm and used M5 x 22mm screws to assemble the project.</p>
<div id="attachment_1194" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-base.png"><img class="size-large wp-image-1194" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-base-1024x691.png" alt="Stack light base, enclosure, connectors, and cables." width="640" height="432" /></a><p class="wp-caption-text">Stack light base, enclosure, connectors, and cables.</p></div>
<p>Here&#8217;s how the notch and connectors turned out in real life:</p>
<div id="attachment_1237" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/notch-connectors.jpg"><img class="size-large wp-image-1237" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/notch-connectors-1024x682.jpg" alt="Close up of the notch and connectors." width="640" height="426" /></a><p class="wp-caption-text">Close up of the notch and connectors.</p></div>
<h3>Final Design of the Enclosure</h3>
<p>Here&#8217;s the final design of the enclosure as viewed from the top:</p>
<div id="attachment_1185" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-top.png"><img class="size-large wp-image-1185" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-top-1024x690.png" alt="Base / enclosure as viewed from the top." width="640" height="431" /></a><p class="wp-caption-text">Base / enclosure as viewed from the top.</p></div>
<p>Here&#8217;s the final design of the enclosure as viewed from the bottom:</p>
<div id="attachment_1186" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-bottom.png"><img class="size-large wp-image-1186" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/stack-mount-base-v22-bottom-1024x690.png" alt="Base / enclosure as viewed from the bottom." width="640" height="431" /></a><p class="wp-caption-text">Base / enclosure as viewed from the bottom.</p></div>
<h2>Hardware Design</h2>
<p>Now that the enclosure and PCB size were finalized it was time to design the electronics. One requirement was to be able to fade the stack lights in and out and control their brightness. The PIC16F1459 only has two hardware PWM channels though. To PWM three different colored stack light segments would require external hardware or some crafty software techniques. I decided to throw hardware at the problem.</p>
<p>The <a href="https://www.nxp.com/products/analog/interfaces/ic-bus/ic-led-controllers/16-channel-12-bit-pwm-fm-plus-ic-bus-led-controller:PCA9685">NXP PCA9685</a> is a 16-channel, 12-bit PWM I²C-bus LED controller. It can control 16 channels of 12-bit PWM over an I²C bus. The I²C bus only requires two IO pins on the PIC16F1459. A quick check of the PIC16F1459 data sheet confirms that the PIC supports I²C using two dedicated pins on the package. The I²C SCL clock signal is on pin RB6 and the I²C SDA clock signal is on pin RB4. This design will use four of the PCA9685&#8217;s 16 channels and leave the remaining channels unconnected.</p>
<p>Here&#8217; s the schematic for the design:</p>
<div id="attachment_1199" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/schematic.png"><img class="size-large wp-image-1199" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/schematic-1024x764.png" alt="USB stack light controller schematic. Needs ESD protection. Grrr." width="640" height="478" /></a><p class="wp-caption-text">USB stack light controller schematic. Needs ESD protection. Grrr.</p></div>
<p>Here&#8217;s the finished board layout:</p>
<div id="attachment_1200" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/board.png"><img class="wp-image-1200 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/board-680x1024.png" alt="board" width="640" height="964" /></a><p class="wp-caption-text">USB stack light controller board layout.</p></div>
<p>And some Oshpark renders of the board:</p>
<div id="attachment_1202" style="width: 1010px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/board-renders.png"><img class="size-full wp-image-1202" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/board-renders.png" alt="Oshpark renders of the USB stack light controller board." width="1000" height="913" /></a><p class="wp-caption-text">Oshpark renders of the USB stack light controller board.</p></div>
<p>Here&#8217;s the almost completely assembled board in the finished enclosure:</p>
<div id="attachment_1206" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/IMG_20190403_172044-cropped.jpg"><img class="size-large wp-image-1206" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/IMG_20190403_172044-cropped-1024x683.jpg" alt="Almost completely assembled board." width="640" height="427" /></a><p class="wp-caption-text">Almost completely assembled board.</p></div>
<h2>Software Design</h2>
<p>The software is based on the Microchip Library for Applications CDC Basic PIC16F1459 demonstration code. To this code, I added I²C code based on the example <a href="https://electrosome.com/i2c-pic-microcontroller-mplab-xc8/">here</a>, some PCA9685 configuration code, and a small CLI for interacting with the user in a terminal.</p>
<h3>Controlling the PCA9685</h3>
<p>The PCA9685 code has three functions defined. The first initializes the addressed PCA9685 over the I²C bus and sets all 16 channels to off:</p>
<pre>void PCA9685_Init (uint8_t addr)
{
    I2C_Master_Start ();
    I2C_Master_Write (addr);
    I2C_Master_Write (MODE1);
    I2C_Master_Write (0x30);
    I2C_Master_Stop ();
    
    I2C_Master_Start ();
    I2C_Master_Write (addr);
    I2C_Master_Write (PRESCALE);
    I2C_Master_Write (0x02);
    I2C_Master_Stop ();
    
    I2C_Master_Start ();
    I2C_Master_Write (addr);
    I2C_Master_Write (MODE1);
    I2C_Master_Write (0x20);
    I2C_Master_Stop ();
    
    for (uint8_t channel = 0; channel &lt; 16; channel++) {
        PCA9685_SetPWM (addr, channel, 0);
    }
}</pre>
<p>The second function takes an I²C address, a PCA9685 channel, and a level and converts the level to the on time and off time values needed by the PCA9685. The input level is a value from 0 for completely off to 4095 for completely on:</p>
<pre>void PCA9685_SetPWM (uint8_t address, uint8_t channel, uint16_t v)
{
    v &amp;= 0xFFF;
    if (v == 4095) {
        // fully on
        PCA9685_SetRaw (address, channel, 4096, 0);
    } else if (v == 0) {
        // fully off
        PCA9685_SetRaw (address, channel, 0, 4096);
    } else {
        PCA9685_SetRaw (address, channel, 0, v);
    }
}

</pre>
<p>This above function is based on the Adafruit code <a href="https://learn.adafruit.com/16-channel-pwm-servo-driver/downloads">here</a>.</p>
<p>The last function takes the values computed by the previous functions and sets the channel of the addressed PCA9685 to the specified levels:</p>
<pre>void PCA9685_SetRaw (uint8_t address, uint8_t channel, uint16_t on, uint16_t off)
{
    I2C_Master_Start ();
    I2C_Master_Write (PCA9685_I2C_ADDRESS);
    I2C_Master_Write (LED0_ON_L + 4 * channel);
    I2C_Master_Write (on);
    I2C_Master_Write (on &gt;&gt; 8);
    I2C_Master_Write (off);
    I2C_Master_Write (off &gt;&gt; 8);
    I2C_Master_Stop ();
}</pre>
<p>As a side note, the I²C address of the PCA9685 is really 0x40. These I²C communication routines though require the address to be in the upper 7 bits of the address byte. This is why the address is #defined as 0x80 instead of 0x40.</p>
<h3>The Command Line Interface</h3>
<p>Remember the desire to interact directly with the hardware using a serial console window? This requires that the CDC device have a command line interface (CLI). I added a very simple CLI to the APP_DeviceCDCBasicDemoTasks function inside the demo code. The CLI accepts up to 72 characters per line. It supports the printable ASCII characters, backspace, and return.</p>
<p>When the user hits the return key, the CLI attempts to parse a decimal channel number and decimal level value from the entered command line. If successful, the CLI sets the specified channel of the PCA9685 to the specified level and returns &#8220;Ok&#8221; to the user. If not successful, the CLI returns &#8220;Err&#8221; to the user. Here&#8217;s an example terminal session with the stack light controller:</p>
<div id="attachment_1212" style="width: 832px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/RGU_T3aw.png"><img class="size-full wp-image-1212" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/RGU_T3aw.png" alt="CLI Terminal Session" width="822" height="667" /></a><p class="wp-caption-text">CLI Terminal Session</p></div>
<p>The first successful command sets channel 0 to 1. The next one sets channel 0 to 4095. The last one sets channel 15 to 2000. A future improvement to the CLI would be to add commands to support blinking and fading the stack lights on and off.</p>
<h3> Testing the Software</h3>
<p>Before completely assembling everything, I did test the software with a single light:</p>
<div id="attachment_1208" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/vlcsnap-2019-04-13-19h32m28s836.png"><img class="size-large wp-image-1208" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/vlcsnap-2019-04-13-19h32m28s836-1024x576.png" alt="Another example of my most excellent ESD precautions while I test the I2C and PCA9685 software." width="640" height="360" /></a><p class="wp-caption-text">Another example of my most excellent ESD precautions while I test the I2C and PCA9685 software.</p></div>
<p>This verified the CLI, I2C, and PCA9685 were all operational.</p>
<h2>Assembly</h2>
<div id="attachment_1180" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00850-cropped.jpg"><img class="size-large wp-image-1180" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00850-cropped-1024x683.jpg" alt="Well, that's inconvenient. Next build gets a pluggable terminal block." width="640" height="427" /></a><p class="wp-caption-text">Well, that&#8217;s inconvenient. Next build gets a pluggable terminal block.</p></div>
<p>The final step was to assemble everything. The first time I assembled everything, I forgot the rubber gasket. It&#8217;s not really needed in my non-industrial home workshop environment it but does provide a better transition between the base and the enclosure. In a future version of this project, I should replace the screw terminal strip with a small pluggable terminal block to make assembly and disassembly easier. Here are a few more photos of the project in various stages of completion. Thanks for reading!</p>

<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/dsc00856-1/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00856-1-150x150.jpg" class="attachment-thumbnail" alt="Green" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/dsc00858-1/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00858-1-150x150.jpg" class="attachment-thumbnail" alt="Red" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/dsc00859-1/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00859-1-150x150.jpg" class="attachment-thumbnail" alt="All" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/dsc00860-1/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00860-1-150x150.jpg" class="attachment-thumbnail" alt="None" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/bench/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/bench-150x150.jpg" class="attachment-thumbnail" alt="On the bench" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/dsc00863-1/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/DSC00863-1-150x150.jpg" class="attachment-thumbnail" alt="Base / enclosure interface" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/1-3/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/1-150x150.jpg" class="attachment-thumbnail" alt="Board" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/2-3/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/2-150x150.jpg" class="attachment-thumbnail" alt="Board and enclosure" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/3-2/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/3-150x150.jpg" class="attachment-thumbnail" alt="Board and enclosure" /></a>
<a href='https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/4-2/'><img width="150" height="150" src="https://bikerglen.com/wp/wp-content/uploads/2019/04/4-150x150.jpg" class="attachment-thumbnail" alt="Board and enclosure and light" /></a>

<h2>Code and Models</h2>
<p>Code and models are available upon request. They&#8217;ll most likely end up on github.com/bikerglen at some point.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/pic16f1459-usb-stack-light-controller/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>Piggybacking USB onto an Industrial Push Button</title>
		<link>https://bikerglen.com/blog/usb-big-red-button/</link>
		<comments>https://bikerglen.com/blog/usb-big-red-button/#comments</comments>
		<pubDate>Wed, 13 Mar 2019 19:08:09 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[USB Human Interface Device (HID)]]></category>

		<guid isPermaLink="false">https://bikerglen.com/blog/?p=963</guid>
		<description><![CDATA[In this project, I mount the electronics from my single-key USB keyboard project to the back of an industrial mushroom push button switch. The finished big red button now activates my screensaver with a single overly-large button press. The biggest &#8230; <a href="https://bikerglen.com/blog/usb-big-red-button/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_966" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105700.jpg"><img class="size-large wp-image-966" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105700-1024x576.jpg" alt="The completed USB-connected big red button." width="640" height="360" /></a><p class="wp-caption-text">The completed USB-connected big red button.</p></div>
<p>In this project, I mount the electronics from my <a href="https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/">single-key USB keyboard</a> project to the back of an industrial mushroom push button switch. The finished big red button now activates my screensaver with a single overly-large button press. The biggest issues in this project were where to mount the USB electronics and how to connect the USB cable between the button and my computer.</p>
<p><span id="more-963"></span></p>
<h2>A Few Words About Industrial Controls</h2>
<p>Industrial push buttons and indicators are the exact opposite of today&#8217;s sleek capacitive touchscreens. They&#8217;re tactile, bulky, single-purpose, take some force to operate, and are built to take abuse from both the environment and users. When a button fails after years of abuse, they&#8217;re modular to facilitate quick repairs and get whatever process they&#8217;re controlling back online quickly. (They do make industrial-rated touchscreen controllers if you really do need to have a touchscreen, e.g., to show / control process parameters.)</p>
<div id="attachment_1038" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/buttons.jpg"><img class="size-large wp-image-1038" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/buttons-1024x669.jpg" alt="Random Omron switch parts including a shrouded red non-illuminated push button, illuminated mushroom button, a mounting collar, LED, NO contacts, illumination unit, NC contacts, and an assembled non-illuminated mushroom button." width="640" height="418" /></a><p class="wp-caption-text">Random Omron switch parts including a shrouded red non-illuminated push button, illuminated mushroom button, a mounting collar, LEDs, NO contacts, illumination unit, NC contacts, and an assembled non-illuminated mushroom button.</p></div>
<p>In the photo above are a few disassembled Omron 22mm push button switches. The typical switch consists of an actuator, a mounting collar or frame, contact blocks, and, if illuminated, an illumination unit. The actuator is the part that mounts to the panel and is exposed to the user. These vary in shape and color often depending on if they&#8217;re designed to be easy to press (emergency power off) or hard to press (start self-destruct sequence).</p>
<p>The part immediately behind the actuator is a frame that connects the contact blocks to the actuator. The contact blocks do the electrical switching and are available in a variety of configurations such as normally open, normally closed, screw terminals, quick connect terminals, etc.</p>
<p>On these Omron controls, the contact blocks snap to the frame and a plunger on the actuator presses a plunger on the contact block to change the state of the contacts. In other designs, they mount using screws. Finally, if the switch is illuminated, there&#8217;s an illumination unit that can hold an LED or incandescent bulb. Below is a page from an <a href="http://www.ia.omron.com/data_pdf/cat/a22n_m22n_a30n_a254-e1_4_5_csm1045427.pdf?id=3443.">Omron Industrial Automation catalog</a> showing some of the available configurations and how they fit together.</p>
<div id="attachment_1022" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/omron-catalog-page1.jpg"><img class="wp-image-1022 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/omron-catalog-page1-724x1024.jpg" alt="" width="640" height="905" /></a><p class="wp-caption-text">A page from the Omron industrial controls catalog.</p></div>
<p>By splitting the switch into so many pieces, the exact switch needed for a job can be built from its component parts. Also repairs can be performed quickly. For example if the actuator is broken, one can disconnect the frame, replace the actuator, reconnect the frame, and be back in business without any rewiring.</p>
<h2>Where to Mount the Electronics</h2>
<p>The immediate goals for this project were (1) to use a big red button and (2) to connect it to a computer using USB. Like any engineering project, there&#8217;s tons of ways to get to a solution and it&#8217;s my job to pick the optimum solution (where optimum is open to debate).</p>
<p>My first thought was to build a small box that had screw terminals for a contact closure input on one side and a USB connector on the other side. This box would sit between the big red button&#8217;s enclosure and the computer. A small circuit board would hold the USB electronics and I&#8217;d 3D print a case for it.</p>
<p>My second thought was to just let a loose circuit board float between the contact blocks inside the big red button&#8217;s enclosure. Things are pretty well insulated so it would be unlikely to short out. But I didn&#8217;t want this thing rattling inside my switch. Then it finally came to me, what if I could mount the electronics to the switch just like a contact block mounts to the switch?</p>
<h2>Mechanical Design</h2>
<div id="attachment_1005" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/lid-and-button.jpg"><img class="size-large wp-image-1005" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/lid-and-button-1024x576.jpg" alt="Raw materials. The lid of the enclosure and pushbutton switch with mushroom operator." width="640" height="360" /></a><p class="wp-caption-text">Raw materials. The lid of the enclosure and pushbutton switch with mushroom operator.</p></div>
<p>Omron Industrial Automation makes some relatively inexpensive industrial push buttons that are available from the usual distributors. They also make a nice bright yellow enclosure specifically for emergency stop / emergency power off / big red button mushroom switches. I went to Digi-Key and ordered an Omron A22NN-BMM-NRA-G100-NN mushroom switch for $10.97 and to Arrow and ordered an OmronA22NZ-A-B01Y single button enclosure for $12.74. These are shown in the photo above.</p>
<div id="attachment_994" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/A22NZ_S_G1A-v1.png"><img class="wp-image-994 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/A22NZ_S_G1A-v1-1024x709.png" alt="Stock Omron Contact Block 3D Model." width="640" height="443" /></a><p class="wp-caption-text">The stock Omron normally open contact block 3D model with a bit of additional color.</p></div>
<p>I needed a starting point for my PCB holder. Fortunately, Omron and most of the other industrial controls vendors publish 3D models of their devices. These models are primarily used during design of industrial control panels to make sure everything fits without interference. I downloaded Omron&#8217;s 3D model of their contact block, shown above, then used Fusion 360 to carve out an area to hold a small PCB. This most likely violates Omron&#8217;s terms of use for their models but since this is a one-off, personal, non-commercial project (aka a hack), I&#8217;m going to call it fair use and not lose any sleep over it.</p>
<div id="attachment_1001" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/contact-block-clip-in-board-knubs-v2-b.png"><img class="size-large wp-image-1001" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/contact-block-clip-in-board-knubs-v2-b-1024x709.png" alt="A render of the contact block circuit board holder and circuit board. Sometimes renders don't work out in real life." width="640" height="443" /></a><p class="wp-caption-text">A render of the contact block circuit board holder and circuit board. Sometimes renders don&#8217;t work out in real life.</p></div>
<p>With a bit of work, I carved out an area to hold the circuit board, fit the board into the model, and added some tabs to hold the board in place without screws. Be sure to scrape off the switch plunger too otherwise you&#8217;ll end up with a fixed piece of plastic on top of the contact block frame that blocks the operation of the button.</p>
<div id="attachment_1004" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/failures.jpg"><img class="size-large wp-image-1004" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/failures-1024x576.jpg" alt="Failure is good as long as you learn from it, right?" width="640" height="360" /></a><p class="wp-caption-text">Failure is good as long as you learn from it, right?</p></div>
<p>This design took a few iterations to get right. I printed the PCB holder in different materials at different 3D printing places. The SLS PA nylon process at Shapeways had different dimensions than the SLS PA nylon process at Sculpteo. The HP JetFusion process at Sculpteo had different dimensions than the SLS PA nylon process at Sculpteo. In addition, the HP JetFusion nylon is more brittle / less flexible than the SLS PA nylon. I finally got a print of a holder that would work in the SLS PA nylon process from Sculpteo.</p>
<div id="attachment_997" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/boards.jpg"><img class="size-large wp-image-997" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/boards-1024x464.jpg" alt="Three failed boards and one good board. Fails: 1) screws rather than tabs. 2) header strip hits holder. 3) slots too small to accommodate tabs. Success: slots and header strip work!" width="640" height="290" /></a><p class="wp-caption-text">Three failed boards and one good board. Fails: 1) screws rather than tabs. 2) header strip hits holder. 3) slots too small to accommodate tabs. Success: slots and header strip work!</p></div>
<p>Unfortunately, I broke the tabs off the holder trying to fit the circuit board into the holder. Rather than redesign the holder, I redesigned the circuit board to have slightly bigger notches that wouldn&#8217;t stress the tabs as much during insertion. I went through a total of four revisions of the circuit board. The post office even lost two revisions of the boards for two weeks before finally finding them and delivering them.</p>
<div id="attachment_986" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_104835.jpg"><img class="size-large wp-image-986" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_104835-1024x576.jpg" alt="The finished circuit board and 3D printed holder next to the back parts of an Omron switch." width="640" height="360" /></a><p class="wp-caption-text">The finished circuit board and 3D printed holder next to the back parts of an Omron switch.</p></div>
<p>Success. After many more weeks and iterations than it should have taken, I finally got things right. With a bit of finesse and luck, I was able to place the finished circuit board into the 3D printed holder. I didn&#8217;t test the electronics before putting the board in the holder. Luckily, they did work.</p>
<p>Finally, I did a bit of assembly in Fusion 360 to see if there was any hope of a USB cable mating with the USB connector on the PCB. I couldn&#8217;t get section analysis to work in the render view of Fusion 360 so I just lopped the bottom of the enclosure off for the render.</p>
<div id="attachment_1019" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/A22NZ_A_B01Y-v6-b.jpg"><img class="wp-image-1019 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/A22NZ_A_B01Y-v6-b-1024x709.jpg" alt="" width="640" height="443" /></a><p class="wp-caption-text">Will a USB cable connect to the board inside the enclosure? That&#8217;s a definite maybe.</p></div>
<h2>Electrical Design</h2>
<div id="attachment_987" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105314.jpg"><img class="wp-image-987 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105314-1024x576.jpg" alt="Board assembled into holder. i had access to isopropyl alchohol and lint-free cleaning swabs so the board is a bit cleaner than my usual boards." width="640" height="360" /></a><p class="wp-caption-text">Board assembled into holder. I had access to isopropyl alcohol and lint-free cleaning swabs during assembly so the board is a bit cleaner than my usual boards.</p></div>
<p>The electrical design on this project was easy. It&#8217;s the same electronics as on the <a href="https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/">single-key USB keyboard</a> project except I added a Texas Instruments TPD2E2U06QDBZRQ1 ESD protection device to the USB data lines and replaced the Cherry MX keyboard switch with a two pin 0.1&#8243; right angle header. Next time I might try a Nexperia PRTR5V0U2X that can protect both the USB power line and USB data lines.</p>
<h2>Software Design</h2>
<div id="attachment_1007" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190310_162519.jpg"><img class="size-large wp-image-1007" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190310_162519-1024x576.jpg" alt="Programming the bootloader is a bit of a pain but thankfully it only has to be done once." width="640" height="360" /></a><p class="wp-caption-text">Programming the bootloader is a bit of a pain but thankfully it only has to be done once.</p></div>
<p>The software is divided into two parts, a bootloader and the application software. These are the same as on the <a href="https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/">single-key USB keyboard</a> project too. The USB bootloader is programmed into the part using any PIC programmer such as a REAL ICE or MPLAB ICD 4. It&#8217;s a bit awkward holding the programmer adapter on the board as shown in the photo above but it only has to be done once. The bootloader then enables the application software to be updated over USB without disassembling the completed project.</p>
<p>Once the bootloader is programmed, the application software may be updated by holding down the big red button while connecting the USB cable to the computer. This action enables the bootloader then the bootloader utility from the Microchip Libaries for Applications may be run to load new application software onto the PIC16F1459.</p>
<p>Currently I have two versions of the application software. One inserts a poop emoji into Microsoft documents. The other hits right-ctrl to escape Oracle&#8217;s VirtualBox&#8217;s keyboard capture then left-ctrl &amp; left-alt &amp; l to invoke the RHEL screensaver / screen lock on my Linux box at work.</p>
<h2>Final Touches</h2>
<p>Now the only thing left to do was to assemble everything. It took a bit of finesse to get the board mounted into the holder without breaking anything.</p>
<div id="attachment_987" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105314.jpg"><img class="size-large wp-image-987" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105314-1024x576.jpg" alt="Board assembled into holder." width="640" height="360" /></a><p class="wp-caption-text">Board assembled into holder.</p></div>
<p>Next was a dry fit test of the assembled push button.</p>
<div id="attachment_1033" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/dry-fit.jpg"><img class="size-large wp-image-1033" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/dry-fit-1024x683.jpg" alt="Yep, everything fits!" width="640" height="427" /></a><p class="wp-caption-text">Yep, everything fits!</p></div>
<p>I used some jumper wires with a two position 0.1&#8243; socket header attached to connect the contact block to the circuit board.</p>
<div id="attachment_986" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_104835.jpg"><img class="size-large wp-image-986" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_104835-1024x576.jpg" alt="The finished circuit board and 3D printed holder next to the back parts of an Omron switch." width="640" height="360" /></a><p class="wp-caption-text">The finished circuit board and 3D printed holder next to the back parts of an Omron switch.</p></div>
<p>Then I snapped the contact block and holder into place on the switch frame and mounted the switch frame to the actuator. Sliding the little yellow lever below the USB cable locks the frame to the actuator.</p>
<div id="attachment_988" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105452.jpg"><img class="wp-image-988 size-large" title="Assembled Switch and USB Board" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105452-1024x576.jpg" alt="IMG_20190224_105452" width="640" height="360" /></a><p class="wp-caption-text">Here&#8217;s a view with everything assembled and mounted to the top half of the enclosure.</p></div>
<p>And voila! The finished project!</p>
<div id="attachment_966" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105700.jpg"><img class="size-large wp-image-966" src="https://bikerglen.com/wp/wp-content/uploads/2019/03/IMG_20190224_105700-1024x576.jpg" alt="The completed USB-connected big red button." width="640" height="360" /></a><p class="wp-caption-text">The completed USB-connected big red button.</p></div>
<h2>Design Files</h2>
<p>If you&#8217;re interested in the mechanical design files for the project, let me know via Twitter and I&#8217;ll post them to github. In the meantime, check out the software and schematic for my single-key keyboards on <a href="https://github.com/bikerglen/small-keyboards">github</a>.</p>
<h2>An Important Safety Note</h2>
<p>As fun as this project may have been, please do NOT use USB for an actual safety-related emergency stop or emergency power off. USB is just not reliable enough for safety-related devices.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/usb-big-red-button/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Presenting the Single ESC Key USB Keyboard!</title>
		<link>https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/</link>
		<comments>https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/#comments</comments>
		<pubDate>Tue, 15 May 2018 20:51:25 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Microchip]]></category>
		<category><![CDATA[PIC18]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[USB Human Interface Device (HID)]]></category>

		<guid isPermaLink="false">http://bikerglen.com/blog/?p=878</guid>
		<description><![CDATA[After building the “awesomely impractical” giant three-key keyboard, I decided it was time to build something a bit more practical—presenting the single ESC key USB keyboard! This keyboard has exactly one function which is to provide an optimal ESCing experience &#8230; <a href="https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_948" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00651_crop2.jpg"><img class="size-large wp-image-948" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00651_crop2-1024x682.jpg" alt="The single ESC key USB keyboard." width="640" height="426" /></a><p class="wp-caption-text">The single ESC key USB keyboard.</p></div>
<p>After building the “<a href="https://blog.hackster.io/ginormous-3-switch-keyboard-is-awesomely-impractical-748b79e471b3">awesomely impractical</a>” giant <a href="http://bikerglen.com/blog/building-a-giant-usb-three-key-mechanical-keyboard/">three-key keyboard</a>, I decided it was time to build something a bit more practical—presenting the single ESC key USB keyboard! This keyboard has exactly one function which is to provide an optimal ESCing experience regardless of whatever keyboard you normally use. In exchange for giving up a USB port, you get a dedicated tactile, clicky Cherry MX blue ESC key.</p>
<p><span id="more-878"></span></p>
<p>The only possible target demographics for this keyboard are vi/vim users on touch strip MacBooks or those who like wasting USB ports on needless functions. On the slightly more practical side, there’s a three-key version too. With a bit of programming, these three keys can be assigned whatever functions are needed. On mine, the first key does CTRL-ALT-DEL, the second key locks the screen (META-L), and the third key is an escape key.</p>
<div id="attachment_949" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00658_crop.jpg"><img class="wp-image-949 size-large" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00658_crop-1024x683.jpg" alt="The three key USB keyboard." width="640" height="427" /></a><p class="wp-caption-text">The three key USB keyboard. The LEDs underneath the keycaps are really only useful for debugging.</p></div>
<h2>Goals</h2>
<p>The only real goal with this keyboard was to see how small I could build a functional USB keyboard with a Cherry MX key switch. The keyboard needed to have an enclosure and the enclosure needed to be easy to assemble and disassemble which meant using screws to hold it together versus snapping together.</p>
<h2>Selecting Parts</h2>
<h3>Picking a USB Microcontroller</h3>
<p>I chose a PIC16F1459 in an SSOP-20 package for the microcontroller. The PIC16F145x family provides a minimal parts count solution to implementing the USB 2.0 standard. No external oscillator is required because this micro has an internal 48MHz oscillator and uses active clock tuning to fine-tune the internal oscillator frequency to the recovered clock from the USB host. This micro, a USB connector, and three capacitors are all that are needed to implement a fully-functional USB 2.0 device.</p>
<div id="attachment_930" style="width: 1012px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/min-sch.png"><img class="size-full wp-image-930" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/min-sch.png" alt="Minimal PIC16F1459 schematic for USB 2.0 operation." width="1002" height="351" /></a><p class="wp-caption-text">Minimal PIC16F1459 schematic for USB 2.0 operation.</p></div>
<p>Once I selected the microcontroller, I needed to pick a package for the microcontroller. The PIC16F1459 is available in DIP, SOIC, SSOP, and QFN packages. I chose the SSOP-20 package. The two larger packages were too big to fit in the allocated board space and the QFN package, though smaller, would be considerably more difficult to hand solder.</p>
<h3>The USB Connector</h3>
<p>Next up was to find a suitable USB Micro-B connector. Since the entire board was to be hand soldered, I wanted a connector with locating pins to position the connector on the board while I soldered it and with enough room between the connector housing and the five signals pins that I could easily see what I was doing with a microscope. I ordered a bunch of USB Micro-B connectors, examined each of them, and finally found a Wurth Electronics connector that met my needs.</p>
<div id="attachment_937" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC_2096_crop.jpg"><img class="wp-image-937 size-large" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC_2096_crop-1024x681.jpg" alt="DSC_2096_crop" width="640" height="426" /></a><p class="wp-caption-text">Wurth Electronics USB Micro-B Receptacle part number 629105136821. It has little black plastic posts to keep the connector centered while soldering and plenty of room between the shell and pins for the soldering iron, flux, solder, and inevitably, wick.</p></div>
<h3>The Other Electrical Components</h3>
<p>The rest of the electrical components weren&#8217;t super critical—a 0.47uF capacitor on the VUSB pin, a 0.1uF capacitor on the VDD pin, 1uF of bulk capacitance on the board, an LED, and a resistor. I used 1206 packages for the caps and resistor and a 3528 package for the LED because these were parts I had on hand.</p>
<div id="attachment_932" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/final-sch.png"><img class="size-large wp-image-932" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/final-sch-1024x264.png" alt="Complete one key USB keyboard schematic." width="640" height="165" /></a><p class="wp-caption-text">Complete one key USB keyboard schematic.</p></div>
<h2>The PCB</h2>
<p>Cherry MX key switches nominally occupy a 3/4” by 3/4” square area on the PCB. I decided to try to make the PCB 1” by 1”. It would have to be double sided with the key switch and LED on one side and the rest of the components on the other.</p>
<p>I drew a 1” x 1” board outline with 0.05” radius corners then placed a 0.1” diameter hole in each of the four corners. The holes are 0.1” from the edges of the board. I also tried to keep a 0.2” square keep out in each corner, but I ended up putting one cap, C2, a bit closer to the hole than I should have. The board turned out fine, but it significantly complicated the design of the enclosure. More on that later.</p>
<p>I found Eagle PCB libraries for the PIC, the USB connector, and the Cherry MX key switch. Links to these are in the Useful Resources section at the end of the blog post. I placed these components, wired everything up, made the gerbers, and ordered boards.</p>
<div id="attachment_926" style="width: 1017px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/one-key-top-and-bottom.png"><img class="size-full wp-image-926" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/one-key-top-and-bottom.png" alt="One key USB right keyboard PCB top and bottom views." width="1007" height="501" /></a><p class="wp-caption-text">One key USB right keyboard PCB top and bottom views.</p></div>
<h2>The Enclosure</h2>
<p>While the boards were being manufactured, I turned to the design of the enclosure.</p>
<h3>PCB 3D Model</h3>
<p>The first step was to use ecad.io to turn my PCB design into a 3D model that I could use to test the fit of the enclosure.</p>
<div id="attachment_911" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/one-key-model.png"><img class="size-large wp-image-911" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/one-key-model-1024x733.png" alt="3D model of the PCB." width="640" height="458" /></a><p class="wp-caption-text">3D model of the PCB.</p></div>
<h3>Critical Dimensions</h3>
<p>The second step was to gather a list of critical dimensions. These are based on past experience and reading specs:</p>
<ul>
<li>Wall thickness: 1.5mm.</li>
<li>Space between PCB edges and walls: 0.5mm.</li>
<li>Board thickness: 1.6mm but allow 1.65mm.</li>
<li>2-56 screw free fit hole diameter: 2.54mm.</li>
<li>2-56 screw countersink diameter and angle: 5.30mm and 82 degrees.</li>
<li>2-56 nut cavity: 5mm across flats, 2mm deep.</li>
<li>Maximum USB Micro-B overmold dimensions: 10.6 by 8.5mm.</li>
<li>Minimum USB Micro-B mated clearance: 1.3mm</li>
<li>3D printer minimum wall thickness: 0.6mm, ideally 1mm.</li>
</ul>
<h3>Enclosure Bottom</h3>
<p>I started with the enclosure bottom. The PCB is 25.4mm x 25.4mm so the enclosure needed to be 29.4mm x 29.4mm to allow for the 1.5mm wall thickness and 0.5mm space around the board edges. I added screw holes and recesses for the nuts on underside of the bottom of the enclosure.</p>
<div id="attachment_913" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/enclosre-bottom-2.png"><img class="wp-image-913 size-large" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/enclosre-bottom-2-1024x682.png" alt="enclosre bottom 2" width="640" height="426" /></a><p class="wp-caption-text">Enclosure bottom (exterior view).</p></div>
<div id="attachment_912" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/enclosre-bottom.png"><img class="wp-image-912 size-large" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/enclosre-bottom-1024x682.png" alt="Enclosure Bottom" width="640" height="426" /></a><p class="wp-caption-text">Enclosure bottom (interior view).</p></div>
<p>Here I hit the first snag. I needed at least 0.6mm and, ideally, 1mm of material around the top and sides of the hex nut recesses on the bottom of the enclosure to meet my 3D printer&#8217;s minimum wall specs. If I added this material all the way to the top of the enclosure, it would have necessitated a 6mm square keepout area in each corner of the PCB. Unfortunately capacitor C2 was already in this keepout area (see illustration below).</p>
<p>Since C2 was in the way, I only brought the material up 1.5 mm from the interior of the enclosure (which is 3mm from the exterior of the enclosure). This left a 1mm wall between the top of the nut recess and the interior of the enclosure. This was was within specs for printing and provided plenty of clearance for C2. Problem solved but next time I would have tried to move the capacitor over a bit on the PCB!</p>
<div id="attachment_905" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/nut-recess-clearance.png"><img class="size-large wp-image-905" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/nut-recess-clearance-1024x666.png" alt="C2 is in the upper left hand corner. Dark blue is a face of the 6mm x 6mm cube around the nut recess. Light blue is the nut recess. The arrow indicates the 1mm wall thickness between the cube face and nut recess." width="640" height="416" /></a><p class="wp-caption-text">C2 is in the upper left hand corner. Dark blue is a face of the 6mm x 6mm cube around the nut recess. Light blue is the nut recess. The arrow indicates the 1mm wall thickness between the cube face and nut recess.</p></div>
<p>The second snag involved the the overall height of the enclosure. Initially the bottom was 5mm high making the enclosure 11.65mm high overall. I planned on using 7/16&#8243; screws to assemble the enclosure. Unfortunately, my 7/16” screws were 0.020” short and barely reached the nuts. Also, the maximum USB plug overmold thickness is 8.5mm so for thick USB plugs the keyboard could be resting on the bottom of the USB plug versus resting on its own bottom.</p>
<p>Increasing the bottom height to 6.05mm and the overall enclosure height to 12.7mm solved both these issues. First, I could use 0.5” screws to assemble everything which more than adequately reached the recessed nuts. Second, this increased the distance from the center of the USB receptacle to the bottom of the housing to 4.7mm which is greater than the 4.25mm required by the USB Micro-B max overmold dimension specification.</p>
<div id="attachment_907" style="width: 838px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/overmold-clearance.png"><img class="size-full wp-image-907" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/overmold-clearance.png" alt="6.05 mm bottom height meets 4.25mm USB overmold clearance requirement." width="828" height="439" /></a><p class="wp-caption-text">6.05 mm bottom height meets 4.25mm USB overmold clearance requirement.</p></div>
<p>The last critical dimension is the minimum mated clearance of a USB Micro-B receptacle and USB Micro-B plug. This dimension is listed as 1.3mm in the USB Micro-B connector specification. When a USB cable is plugged into the connector on the USB keyboard, they need to be fully mated. In order to support this requirement, the distance from the exterior face of the enclosure to the metal guides on the USB receptacle needs to be less than 1.3mm. In my design, they&#8217;re 0.7mm which will work.</p>
<div id="attachment_909" style="width: 889px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/mated-clearance.png"><img class="wp-image-909 size-full" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/mated-clearance.png" alt="0.7mm clearance between receptacle guides and exterior face of enclosure." width="879" height="714" /></a><p class="wp-caption-text">0.7mm clearance between receptacle guides and exterior face of enclosure.</p></div>
<h3>Enclosure Top</h3>
<div id="attachment_916" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/enclosure-top-2.png"><img class="wp-image-916 size-large" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/enclosure-top-2-1024x683.png" alt="enclosure top 2" width="640" height="427" /></a><p class="wp-caption-text">Enclosure top (exterior view).</p></div>
<div id="attachment_915" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/enclosure-top-1.png"><img class="wp-image-915 size-large" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/enclosure-top-1-1024x682.png" alt="enclosure top 1" width="640" height="426" /></a><p class="wp-caption-text">Enclosure top (interior view).</p></div>
<p>The enclosure top was significantly less challenging to design. The height needed to be the board height (1.65mm) plus the height to the bottom of the depressed key cap (about 5mm). I drew the exterior walls of the enclosure, added some cylinders around the screws, drew the countersink holes, cut out a square for the key switch, and added a bit of a notch around the USB connector. The cylinders are 1.65mm shorter than the enclosure so that the board fits completely recessed into the top of the enclosure.</p>
<div id="attachment_918" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/recessed-board.png"><img class="size-large wp-image-918" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/recessed-board-1024x682.png" alt="PCB fits recessed into the bottom of the top half of the enclosure." width="640" height="426" /></a><p class="wp-caption-text">PCB fits recessed into the bottom of the top half of the enclosure.</p></div>
<h3>Manufacturing the Enclosure</h3>
<p>I still don&#8217;t own a 3D printer. Instead, I opted to have my enclosures 3D printed at a service bureau on a selective laser sintering (SLS) 3D printer in black PA12 nylon. They turned out great. 3D prints on these machines are accurate and consistent from print to print.</p>
<h2>Three Key Stretch</h2>
<p>The three key version of the keyboard is a stretch of the one key version of the keyboard.</p>
<h3>PCB</h3>
<div id="attachment_928" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/3keypcb.png"><img class="size-large wp-image-928" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/3keypcb-1024x824.png" alt="Three key USB keyboard PCB top and bottom views." width="640" height="515" /></a><p class="wp-caption-text">Three key USB keyboard PCB top and bottom views.</p></div>
<h3>Enclosure</h3>
<div id="attachment_920" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/three-key-enclosure-rear.png"><img class="size-large wp-image-920" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/three-key-enclosure-rear-1024x683.png" alt="Rear view of the three key enclosure." width="640" height="427" /></a><p class="wp-caption-text">Rear view of the three key enclosure.</p></div>
<h2>Building the Keyboard</h2>
<div id="attachment_951" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00674_crop.jpg"><img class="wp-image-951 size-large" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00674_crop-1024x682.jpg" alt="DSC00674_crop" width="640" height="426" /></a><p class="wp-caption-text">Three variations of the small USB keyboards: single key with USB top, single key with USB right and optional LED and light pipe, and finally the three key version.</p></div>
<p>The keyboard has three variations:</p>
<ol>
<li>Single key with USB top. There&#8217;s a hidden red LED on the right hand side of the key.</li>
<li>Single key with USB right. There&#8217;s an LED on the top side of the key. Whether to expose the LED, keep the LED hidden, or use a light pipe to direct the LED light is up to you.</li>
<li>Three key with USB top. This board has a provision for a 3MM through-hole LED under each key. These three LEDs really don&#8217;t add much to the project but having them to indicate the USB status is helpful when bringing up the board.</li>
</ol>
<p>To build the keyboard, pick one of three basic variations then select the the PCB, enclosure, parts, and software for your board from the downloads section below. The one key USB right and one key USB top keyboards use the same 3D printed enclosure. To program the microcontroller, you need a PIC programmer such as a PICkit, ICD, or Real ICE.</p>
<div id="attachment_943" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00650.jpg"><img class="size-large wp-image-943" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00650-1024x683.jpg" alt="The parts and pieces required to build the single-key keyboard." width="640" height="427" /></a><p class="wp-caption-text">The parts and pieces required to build the single-key keyboard.</p></div>
<p>When assembling the PCB, I recommend soldering the USB connector first then soldering the PIC16F1459 next. After those two parts are soldered to the board, check the pins and traces for solder bridges very carefully then move on to soldering the rest of the surface mount components. Lastly, solder the Cherry MX key switch to the board. Do not solder a connector to the programming header on the PCB.</p>
<p>To program the micro, open the project in MPLAB X. Build the project. Connect the keyboard and programmer to USB ports on the PC. Finally program the micro while holding the programmer&#8217;s connector and a header in the holes of the programming of the header on the PCB.</p>
<p>When programming is complete, the red LED should flash quickly and the keyboard should begin working immediately. If it doesn&#8217;t, the most likely issue is solder bridges between the pins of the USB connector or PIC. To change what the key does, modify the key codes sent by the software on lines 359 to 372 of the function <span class="pl-en">APP_KeyboardTasks</span> in the file app_device_keyboard.c.</p>
<p>Once you&#8217;re happy with the operation of the keyboard, unplug it and assemble the case around the PCB. Finally, select a key cap and place the key cap on the key switch.</p>
<h2>More Photos</h2>
<p>Here are a few more photos.</p>
<div id="attachment_954" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00678_crop.jpg"><img class="size-large wp-image-954" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00678_crop-1024x683.jpg" alt="One key with USB top." width="640" height="427" /></a><p class="wp-caption-text">One key with USB top.</p></div>
<div id="attachment_953" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00680_crop.jpg"><img class="size-large wp-image-953" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00680_crop-1024x683.jpg" alt="Three key." width="640" height="427" /></a><p class="wp-caption-text">Three key.</p></div>
<div id="attachment_955" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00679_crop.jpg"><img class="size-large wp-image-955" src="http://bikerglen.com/wp/wp-content/uploads/2018/05/DSC00679_crop-1024x683.jpg" alt="One key USB right with optional LED and light pipe." width="640" height="427" /></a><p class="wp-caption-text">One key USB right with optional LED and light pipe.</p></div>
<p>Have fun! I hope you enjoyed this project!</p>
<h2>Downloads</h2>
<h3>PCB</h3>
<p>Pick one of the following PCB designs depending on which version of the keyboard you’d like to make. These link to directories on github containing both Eagle PCB files for modifying and Gerbers for manufacturing:</p>
<ul>
<li><a href="https://github.com/bikerglen/small-keyboards/tree/master/boards/one%20key%20usb%20right">Single key version with USB port on the right side</a></li>
<li><a href="https://github.com/bikerglen/small-keyboards/tree/master/boards/one%20key%20usb%20top">Single key version with USB port on the top</a></li>
<li><a href="https://github.com/bikerglen/small-keyboards/tree/master/boards/three%20key%20usb%20top">Three key version with USB port on the top</a></li>
</ul>
<h3>Enclosure</h3>
<p>Pick an enclosure to match the selected PCB. The single-key USB right and single-key USB top keyboards both use the same single-key enclosure. These link to directories on github containing both STEP files for modifying and STL files for printing:</p>
<ul>
<li><a href="https://github.com/bikerglen/small-keyboards/tree/master/enclosures/one%20key%20by%20half%20inch">Single key version for use with 2-56 x 1/2” screws</a></li>
<li><a href="https://github.com/bikerglen/small-keyboards/tree/master/enclosures/one%20key%20by%20short">Single key version for use with 2-56 x 7/16” screws</a> (not recommended, see note below)</li>
<li><a href="https://github.com/bikerglen/small-keyboards/tree/master/enclosures/three%20key%20by%20half%20inch">Three key version for use with 2-56 x 1/2” screws</a></li>
</ul>
<p>Note: the 7/16&#8243; screws I ordered from McMaster-Carr were approximately 0.020” short of 7/16”. They worked but it took some finagling to get the screw threads to catch the nuts. For this reason, I’d recommend the 1/2” version of the enclosure. Also 2-56 x 1/2” screws are much more common, easier to find, and less expensive than 2-56 x 7/16” screws.</p>
<h3>Software</h3>
<p>Pick a software version. All software versions support from one to three keys. The default configuration is for key 1 to type an <em>a</em>, key 2 to type a <em>b</em>, and key 3 to type a <em>c</em>. The Non-USB bootloader version is the easiest to work with but it gets old disassembling and re-assembling the keyboard to update the firmware. If you select the USB bootloader version, you will also need the USB bootloader and the Microchip USB hex bootloader app.</p>
<p>These link to directories on github containing both the MPLAB X projects and pre-built .hex files that may be directly programmed into the part without opening or building the projects:</p>
<ul>
<li><a href="https://github.com/bikerglen/small-keyboards/tree/master/software/tkk-pic16f1459.X">Non-USB bootloader version</a>. Requires disassembling keyboard to update firmware.</li>
<li>USB bootloader version. After bootloader is programmed, firmware may be updated over USB without disassembling keyboard.</li>
<li>USB bootloader. Bootloader for the USB bootloader version of the keyboard software.</li>
</ul>
<p>If you selected the USB bootloader version, you’ll also need the Microchip USB hex bootloader app. This app is distributed as part of the Microchip Library for Applications (MLA) and may be downloaded <a href="http://www.microchip.com/mplab/microchip-libraries-for-applications">here.</a></p>
<h2>Bill of Materials</h2>
<h3>Electrical Parts</h3>
<p>Part numbers in parenthesis are <a href="https://www.digikey.com/">Digi-Key</a> part numbers. Part numbers in brackets are <a href="https://www.mouser.com/">Mouser</a> part numbers.</p>
<ul>
<li>N=1 PIC16F1459-I/SS USB microcontroller. Microchip part # PIC16F1459-I/SS (PIC16F1459-I/SS-ND)</li>
<li>N=1 USB Micro-B PCB mount jack. Wurth part # 629105136821 (732-3155-1-ND)</li>
<li>N=1 0.47µF 50V 1206 capacitor. Similar capacitors with voltage ratings down to 16V may be substituted. Kemet # C1206C474K5RACTU (399-3498-1-ND)</li>
<li>N=1 0.1µF 50V 1206 capacitor. Similar capacitors with voltage ratings down to 16V may be substituted. Kemet # C1206C104K5RAC7867 (399-1249-1-ND)</li>
<li>N=1 1µF 16V 1206 capacitor. Similar capacitors may be substituted. Kemet # C1210C105K4PACTU [80-C1210C105K4P]</li>
<li>N=1  or N=3 Cherry MX blue key switch or similar. Cherry # MX1A-E1NW (CH197-ND)</li>
<li>N=1 or N=3 1kΩ 1206 resistors depending on if you selected the single key or three version of the keyboard. (optional, only needed if you add LEDs to your keyboard) Bourns # CR1206-JW-102ELF (CR1206-JW-102ELFCT-ND)</li>
<li>N=1 Red 3528 surface mount LED (optional, for the single key version of the keyboard). Kingbright # AA3528ES (754-1531-1-ND)</li>
<li>N=3 Red 3mm through hole LED (optional, for the three key version of the keyboard). Kingbright # WP710A10ID (754-1606-ND)</li>
</ul>
<h3>Mechanical Parts</h3>
<ul>
<li>N=4 2-56 x 1/2” or 7/16” black oxide socket cap flat head screws. McMaster-Carr part # 91253A081 (1/2”) or 91253A080 (7/16”) depending on the version of the enclosure selected above.</li>
<li>N=4 2-56 black oxide hex nuts. McMaster-Carr part #96537A110.</li>
<li>An assortment of Cherry MX compatible key caps. I ordered mine from <a href="http://www.maxkeyboard.com/products/cherry-mx-keycap/backlight-novelty-keycap/">Max Keyboard</a>.</li>
</ul>
<h3>Challenge Parts</h3>
<p>The single key version with USB port on the right side contains a single red LED above the key switch. A suggested challenge would be to open a hole in the enclosure and use a light pipe to pipe the LED’s light to the top of the enclosure. If you want to attempt this challenge, I recommend Visual Communications Company’s round 3mm x .125” diffuse light pipe, part # LFB012CTP (LFB012CTP-ND at Digi-Key). A possible solution to this challenge is located <a href="https://github.com/bikerglen/small-keyboards/tree/master/enclosures/top%20with%20light%20pipe%20opening">here</a>.</p>
<h2>Useful Resources</h2>
<p>Here is a list of resources I found useful during the construction of this project:</p>
<ul>
<li>SparkFun Cherry MX Eagle PCB <a href="https://github.com/sparkfun/SparkFun-Eagle-Libraries/blob/master/SparkFun-Switches.lbr">footprint</a>.</li>
<li>PIC16F1459-I/SS Eagle PCB <a href="http://digikey.ultralibrarian.com/?customers=RycPF1rrFAfHhx1FKbDMvyIhfAaVpfojYtrMkEWUzmMQdSfcVO7y%2blSpZPdVwobWTDvUSYygHvldEcommnlKY74M1oqx1amo9RHpyTg76aUim0tW8Ixasn2vKKgF2HxKUqAC9sXJVfIVyvnE2QxaAMefuQ97QukV0%2bx2GaAAxXHaw2RROBbtuzW8EoEJ8BRB6maVzCgLHexQO7mi4z8iPKxQyioAUo3ABSeiKMMsjE4DYwGW8SRk4qw2NtZx8cG%2fo1HtREBRFClZPrpxKvuPhMjIDjuW%2bDQrnAnzjzaiol2T3xYDM4m6c0PpWtamCw9D30myp3N%2brt%2bnBANG7Gkl3g%3d%3d&amp;parts=PIC16F1459-I%2fSS-ND&amp;submit">footprint</a>.</li>
<li>Wurth part 629105136821 <a href="http://katalog.we-online.de/en/em/COM_MICRO_SMT_TYPE_B_HORIZONTAL/629105136821?m=n&amp;sp=http%3A%2F%2Fwww.we-online.com%2Fweb%2Fen%2Fwuerth_elektronik%2Fsearchpage.php%3Fsearch%3D629105136821">Eagle PCB footprint and STEP 3D model</a>.</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/presenting-the-single-esc-key-usb-keyboard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Custom 3D Printed LED Bar Graphs</title>
		<link>https://bikerglen.com/blog/custom-3d-printed-led-bar-graphs/</link>
		<comments>https://bikerglen.com/blog/custom-3d-printed-led-bar-graphs/#comments</comments>
		<pubDate>Sat, 29 Apr 2017 19:17:04 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Fusion 360]]></category>
		<category><![CDATA[Matlab]]></category>

		<guid isPermaLink="false">http://bikerglen.com/blog/?p=644</guid>
		<description><![CDATA[While building my zombie containment unit, I decided I wanted some LED displays or bar graphs to complement the containment status video running on the smaller secondary video monitor. Some other containment units used LED air pressure gauges from eBay. &#8230; <a href="https://bikerglen.com/blog/custom-3d-printed-led-bar-graphs/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_647" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2017/04/01.banner.DSC_1663.jpg"><img class="wp-image-647 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2017/04/01.banner.DSC_1663-1024x682.jpg" alt="Three different bar graphs built using Matlab, Eagle, Fusion 360, and 3D printing." width="640" height="426" /></a><p class="wp-caption-text">Three different bar graphs built using Matlab, Eagle, Fusion 360, and 3D printing.</p></div>
<p>While building my <a href="https://youtu.be/48f4Io2PyE8">zombie containment unit</a>, I decided I wanted some LED displays or bar graphs to complement the containment status video running on the smaller secondary video monitor. Some other containment units used LED air pressure gauges from eBay. I wanted to achieve a similar look, but I also wanted my gauge to be software controllable so I could change the number of segments lit in response to events in the playback of the two videos. I decided it was time to build my own LED bar graphs.</p>
<p><span id="more-644"></span></p>
<p>My initial thought was to buy some <a href="http://www.lumex.com/content/files/ProductAttachment/SSA-LXB10SUGW-CUR.pdf">pre-made curved bar graph segments</a> and build my own board to hold them. Unfortunately, no distributors stocked these bar graphs and I  didn’t want to purchase the minimum order quantity of 500.</p>
<p>I decided to build a board to hold a bunch of discrete LEDs arranged in a circle and at the correct angles. Soldering them by hand and keeping everything perfectly aligned, however, was going to be problem. I also did not want light from the lit LEDs to bleed into the unlit LEDs. Fortunately 3D printing could solve both of these problems: a 3D printed holder could hold the LEDs while soldering them and act as a separator to prevent light bleed.</p>
<p><strong>Picking LEDs and a Driver IC</strong></p>
<div id="attachment_659" style="width: 650px" class="wp-caption alignnone"><a href="https://bikerglen.com/wp/wp-content/uploads/2017/04/02.leds_and_driver.DSC_1667.jpg"><img class="wp-image-659 size-large" src="https://bikerglen.com/wp/wp-content/uploads/2017/04/02.leds_and_driver.DSC_1667-1024x682.jpg" alt="1 x 5 mm LEDs, MAX6954 driver IC, and 2 x 5 mm LEDs." width="640" height="426" /></a><p class="wp-caption-text">1 x 5 mm LEDs, MAX6954 driver IC, and 2.5 x 5 mm LEDs.</p></div>
<p>The first step is to pick some LEDs and a driver IC to drive them. I searched Kingbright’s <a href="http://www.kingbrightusa.com/">website</a> and settled on two possible LED candidates in three different colors.</p>
<p>The first LED was a 1 x 5 mm rectangular LED with a 2.8 x 5 mm base. I settled on the <a href="http://www.kingbrightusa.com/product.asp?catalog_name=LED&amp;product_id=WP1053IDT">625nm red version of this LED</a>, part number WP1053IDT. Finding this LED in stock in green and yellow proved to problematic but I still wanted to do a display that used red, yellow, and green LEDs so I decided to build a second display with another LED too.</p>
<p>The second LED was a 2.5 x 5 mm rectangular LED. This LED’s dimensions are constant throughout its height. This LED was stocked in <a href="http://www.kingbrightusa.com/product.asp?catalog_name=LED&amp;product_id=WP513IDT">red</a> (WP513IDT), <a href="http://www.kingbrightusa.com/product.asp?catalog_name=LED&amp;product_id=WP513YDT">yellow</a> (WP513YDT), and <a href="http://www.kingbrightusa.com/product.asp?catalog_name=LED&amp;product_id=WP513GDT">green</a> (WP513GDT) by a <a href="http://www.mouser.com/Search/Refine.aspx?Keyword=WP513">distributor</a> too.</p>
<p>After searching for quite some time for a suitable driver IC, I finally settled on a <a href="https://www.maximintegrated.com/en/products/power/display-power-control/MAX6954.html">Maxim MAX6954 common cathode LED display driver</a> in a 36-pin SSOP package. This driver IC can drive up to 128 discrete LEDs, sixteen 7-segment dispays, eight alphanumeric displays, or some combination in between. It requires very little external circuitry and has a simple SPI interface for controlling the attached LEDs. Then I looked at the cost—about $20 each in single quantities. Ouch! But board space was at a premium and I wanted to add a few 7-segment displays to the graphs too so this IC was the perfect fit for the job.</p>
<p><strong>Trigonometry Time<br />
</strong></p>
<p>After picking out the basic components, the next step is to decide on a board size, the number of LEDs on the board, and the radius and length of the arc that encompasses the LEDs. The 3D printing process imposes a constraint on these decisions: the minimum wall thickness in the selected 3D printing process is about 1.5 to 2mm so the LEDs can be no closer to each other at their closest points than about 1.5mm.</p>
<p>I settled on a 50.8mm (2”) diameter board with the LEDs arranged in a 270 degree arc with a radius of 18.5mm. For the smaller 1 x 5mm LEDs, I placed 24 LEDs on this arc and for the larger 2.5 x 5mm LEDs, I placed 18 LEDs on this arc.</p>
<p>For the first three LEDs on the first board, I did the calculations by hand then moved and rotated the LEDs using the Eagle PCB command line. This quickly became monotonous and error prone.</p>
<p><strong>Matlab to the Rescue</strong></p>
<div id="attachment_665" style="width: 636px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/matlab-dimensions.png"><img class="size-full wp-image-665" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/matlab-dimensions.png" alt="Variables used by the Matlab script and their relationship to the final board layout." width="626" height="605" /></a><p class="wp-caption-text">Variables used by the Matlab script and their relationship to the final board layout.</p></div>
<p>To simplify these calculations, I wrote a <a href="https://github.com/bikerglen/circular-bar-graphs/blob/master/bar_graph_blog_post.m">Matlab script</a>. When executed, the Matlab script sets a bunch of variables that control the spacing and position of the LEDs on the bar graph board, calculates the position and rotation of each LED, then generates an <a href="https://github.com/bikerglen/circular-bar-graphs/blob/master/bar_graph_blog_post.scr">Eagle PCB script</a> that will place the LEDs, draw a board outline, and draw some informational lines that show where each LED and the 3D printed LED holder will be located on the board.</p>
<p>The variables are as follows (see the diagram above for their relationship to the completed board):</p>
<ul>
<li><strong>nLedPos</strong>: the number of LEDs in a complete circle.</li>
<li><strong>nLeds</strong>: the number of LEDs used on the bar graph.</li>
<li><strong>r</strong>: the radius of the arc containing the LEDs in millimeters.</li>
<li><strong>xOffset</strong> and <strong>yOffset</strong>: the x and y offsets to the center of the board in millimeters. It’d be nice to keep the bar graph centered at the origin but my Eagle PCB license will only permit components to be placed in a small area northeast of the origin.</li>
<li><strong>keepout</strong>: the width of the region occupied by the 3D printed holder in millimeters. This is measured normal to the arc containing the LEDs. For example with r = 18.5mm, a keep out region will be created between arcs at a radius of 14mm and a radius of 23mm.</li>
<li><strong>radius</strong>: radius of the board for the board outline layer.</li>
<li><strong>ledw</strong> and <strong>ledh</strong>: the width and height of the LED plus any margin for the hole in the 3D printed holder.</li>
</ul>
<p>With the Matlab script and generated Eagle PCB script, it’s pretty quick and easy to iterate through multiple designs in Eagle PCB and see how the LEDs will be spaced and placed on the board.</p>
<p><strong>Designing the Board</strong></p>
<p>With all the design decisions completed, it‘s time to run the Matlab script and note the location of the generated Eagle PCB script. Open Eagle PCB and generate <a href="https://github.com/bikerglen/circular-bar-graphs/blob/master/bar_graph_blog_post.sch">a schematic containing the number of required LEDs</a>. These should be labeled D1 … Dn where n is the number of LEDs (nLeds) from the Matlab script. See the figure below as an example.</p>
<div id="attachment_667" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_sch_0.png"><img class="size-large wp-image-667" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_sch_0-1024x764.png" alt="Schematic with just the LEDs." width="640" height="478" /></a><p class="wp-caption-text">Schematic with just the LEDs.</p></div>
<p>Select switch to board to generate a board from the schematic. It’ll look something like the picture below.</p>
<div id="attachment_668" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_brd_0.png"><img class="size-large wp-image-668" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_brd_0-1024x516.png" alt="Default layout after generating the board from the schematic." width="640" height="323" /></a><p class="wp-caption-text">Default layout after generating the board from the schematic.</p></div>
<p>Delete the default board outline from the dimension layer then run the <a href="https://github.com/bikerglen/circular-bar-graphs/blob/master/bar_graph_blog_post.scr">generated Eagle PCB script</a> using the File…Execute Script… menu option in the PCB layout tool. The board should now look something like this with all the LEDs, board outline, and dimensions placed:</p>
<div id="attachment_669" style="width: 614px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_brd_1.png"><img class="size-full wp-image-669" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_brd_1.png" alt="Board after LEDs, dimensions, and keep outs have been placed by the generated Eagle PCB script." width="604" height="604" /></a><p class="wp-caption-text">Board after LEDs, dimensions, and keep outs have been placed by the generated Eagle PCB script.</p></div>
<p>At this point, if you don’t like the placement of the LEDs, change the parameters in Matlab and repeat the process.</p>
<p>The final step is to add the rest of the components required by the design to the schematic and finish the board layout. Here’s my <a href="https://github.com/bikerglen/circular-bar-graphs/blob/master/bar%20graph%20meter%202in%20clip%20in%20w%2047uF.sch">final schematic</a>:</p>
<div id="attachment_670" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_sch_1.png"><img class="size-large wp-image-670" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_sch_1-1024x764.png" alt="Final schematic." width="640" height="478" /></a><p class="wp-caption-text">Final schematic.</p></div>
<p>And my <a href="https://github.com/bikerglen/circular-bar-graphs/blob/master/bar%20graph%20meter%202in%20clip%20in%20w%2047uF.brd">final board layout</a>:</p>
<div id="attachment_671" style="width: 613px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_brd_2.png"><img class="size-full wp-image-671" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/bar_graph_blog_post_brd_2.png" alt="Final board layout." width="603" height="603" /></a><p class="wp-caption-text">Final board layout.</p></div>
<p>And the boards fabbed from the above files:</p>
<div id="attachment_672" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/03.boards.jpg"><img class="size-large wp-image-672" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/03.boards-1024x768.jpg" alt="The fabbed board for a 270 degree arc with 24 1 x 5mm LEDs." width="640" height="480" /></a><p class="wp-caption-text">The fabbed board for a 270 degree arc with 24 1 x 5mm LEDs.</p></div>
<p>I added some notches to the board outline to allow the boards to snap into a holder for either surface or panel mounting the finished displays:</p>
<div id="attachment_680" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/04.board_and_holder.DSC_1675.jpg"><img class="size-large wp-image-680" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/04.board_and_holder.DSC_1675-1024x683.jpg" alt="Snap-in board holder." width="640" height="427" /></a><p class="wp-caption-text">Board placed into a 3D printed plastic snap-in bracket for surface mounting.</p></div>
<p><strong>Designing the LED Holder</strong></p>
<p>I used Autodesk Fusion 360 to design the LED holder. The first step in creating the holder is to create a sketch matching the dimensions of the LED holder keep out area from the PCB board and with a hole for a single LED. We’ll duplicate the LED hole to all the required positions after extruding the sketch into a 3D body.</p>
<p>Some reminders of the required dimensions:</p>
<ul>
<li>The radii of the keep out area are 18.5mm ± (9mm/2) = 14mm and 23mm. These arcs extend 270 degrees from -45° to 225°.</li>
<li>The center of one of the LEDs (D20) is at r = 18.5mm and θ = (360/32/2) = 5.625°.</li>
<li>From printing a rectangular piece with different sizes of LED holes, I learned the LED hole needs to be 0.2mm larger than the LED so for a 1 x 5mm LED, the hole needs to be 1.2 x 5.2mm.</li>
</ul>
<p>To create the sketch:</p>
<ol>
<li>As always in Fusion 360, first things first: create a new component to hold your design.</li>
<li>Create a new sketch.</li>
<li>Create two circles centered at the origin, one with a radius of 14mm and the second with a radius of 23mm.</li>
<li>Create two lines radiating outward from the origin to the edge of the outermost circle. One line should be at an angle of 225°; the second at an angle of -45°. Both lines should have a length of 23mm.</li>
</ol>
<p>It should look something like this now:</p>
<div id="attachment_684" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.02.23-PM.png"><img class="size-large wp-image-684" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.02.23-PM-1024x584.png" alt="Circles and lines complete." width="640" height="365" /></a><p class="wp-caption-text">Circles and lines complete.</p></div>
<ol start="5">
<li>Now use the trim tool to delete the unneeded lines.</li>
</ol>
<p>It’ll look something like this now:</p>
<div id="attachment_685" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.04.19-PM.png"><img class="size-large wp-image-685" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.04.19-PM-1024x584.png" alt="Trim complete." width="640" height="365" /></a><p class="wp-caption-text">Trim complete.</p></div>
<p>Now add the hole for the LED:</p>
<ol start="6">
<li>Create a line from the origin with a length of 18.5mm and an angle of 5.625°.</li>
<li>Create a 3 point rectangle. The first point is at the end of the line drawn in the previous step. The second point is 2.6mm (1/2 of 5.2mm) back along the same line. The third point is up 0.6mm (1/2 of 1.2mm) from the same line.</li>
<li>Create two more 3 point rectangles so that you end up with a final rectangle that is 1.2 x 5.2mm. It’ll be divided up into four regions.</li>
</ol>
<div id="attachment_686" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.11.57-PM.png"><img class="size-large wp-image-686" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.11.57-PM-1024x584.png" alt="Location of rectangular cut out for one LED." width="640" height="365" /></a><p class="wp-caption-text">Location of rectangular cut out for one LED.</p></div>
<ol start="9">
<li>Now use the trim tool to get rid of the excess lines leaving just a single rectangle for the LED hole.</li>
</ol>
<div id="attachment_687" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.16.35-PM.png"><img class="size-large wp-image-687" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.16.35-PM-1024x584.png" alt="Finished sketch." width="640" height="365" /></a><p class="wp-caption-text">Finished sketch.</p></div>
<p>Now create the 3D body and the required LED holes:</p>
<ol start="10">
<li>Exit the sketch and use the press pull tool to extrude the sketch up 3.5mm. This is the height of the portion of the led that is 1 x 5mm (4mm) minus 0.5mm.</li>
<li>Select the four faces of the LED hole.</li>
<li>Select Pattern…Circular Pattern from the Create menu.</li>
<li>Click Axis in the popup dialog box and select the Y axis to rotate the pattern about the Y axis.</li>
<li>For quantity, enter 32.</li>
<li>Uncheck the holes outside the body of the LED holder.</li>
<li>Click OK.</li>
</ol>
<div id="attachment_688" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.23.23-PM.png"><img class="size-large wp-image-688" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.23.23-PM-1024x584.png" alt="Creating the circular pattern." width="640" height="365" /></a><p class="wp-caption-text">Creating the circular pattern.</p></div>
<div id="attachment_689" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.24.45-PM.png"><img class="size-large wp-image-689" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.24.45-PM-1024x584.png" alt="Circular pattern complete." width="640" height="365" /></a><p class="wp-caption-text">Circular pattern complete.</p></div>
<p>Next I created a shroud on the bottom of the LED holder to mask light escaping from the bottom. This shroud is 4mm tall and 1.5mm thick on both the inside out side radius of the LED holder.</p>
<ol start="17">
<li>Select the bottom of the LED holder and select create a new sketch.</li>
<li>Create two center point arcs located at the origin with a radius of 15.5 and 21.5mm on the bottom face of the LED holder.</li>
<li>Stop the sketch.</li>
<li>Select the two faces between the arcs and the outside edges of the LED holder.</li>
<li>Use the push pull tool to extrude these two faces down 4mm.</li>
</ol>
<div id="attachment_692" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.30.55-PM.png"><img class="size-large wp-image-692" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.30.55-PM-1024x584.png" alt="Arcs on bottom of LED holder." width="640" height="365" /></a><p class="wp-caption-text">Arcs on bottom of LED holder.</p></div>
<div id="attachment_693" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.34.03-PM.png"><img class="size-large wp-image-693" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.34.03-PM-1024x584.png" alt="LED holder with shroud extruded." width="640" height="365" /></a><p class="wp-caption-text">LED holder with shroud extruded.</p></div>
<p>At this point the LED holder is complete. Since I opted to mount my board using a board holder with snap-in tabs, I creating a cutting tool out of the tabs on the board holder and used the cutting tool to remove any plastic on the LED holder that might interfere with the snap-in tabs. My finished LED holder looked like this on the bottom:</p>
<div id="attachment_694" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.40.21-PM.png"><img class="size-large wp-image-694" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.40.21-PM-1024x584.png" alt="LED holder with plastic removed to prevent interference with snap-in board holder." width="640" height="365" /></a><p class="wp-caption-text">LED holder with plastic removed to prevent interference with snap-in board holder.</p></div>
<p><strong>Verifying the Fit</strong></p>
<div id="attachment_695" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.48.34-PM.png"><img class="size-large wp-image-695" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-12.48.34-PM-1024x584.png" alt="Verifying the fit of the circuit board, board holder, and LED holder in Fusion 360." width="640" height="365" /></a><p class="wp-caption-text">Verifying the fit of the circuit board, board holder, and LED holder in Fusion 360.</p></div>
<p>The final step before manufacturing the LED holder is to make sure the LED holder and the LEDs on the circuit board will fit together properly. To do this, I used <a href="https://www.ecad.io/">ecad.io</a>. After logging into the website, I uploaded my Eagle PCB board file and 3D models of the LEDs and other components obtained from the component manufacturers’ websites. Once everything was placed in ecad.io, I created a STEP AP214 Part File containing a 3D mechanical model of the board and components. Once the file was created, I downloaded the resulting .step file to my computer.</p>
<p>Back in Fusion 360, I uploaded the .step file and added the LED holder and board holder components to the model. I visually checked for interference but I could have also used the Inspect…Interference command in Fusion 360. Once I was satisfied with the fit, I selected the LED holder component and selected Make…3D Print. I set mesh refinement to fine and opted to save the .stl file to my computer rather than use the 3D Print Utility. Finally, I uploaded the .stl files to a 3D printing service and printed the models.</p>
<div id="attachment_696" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/05.led_holder.DSC_1685.jpg"><img class="size-large wp-image-696" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/05.led_holder.DSC_1685-1024x683.jpg" alt="Finished 3D printed LED holders for the 24 LED bar graph." width="640" height="427" /></a><p class="wp-caption-text">Finished 3D printed LED holders for the 24 LED bar graph.</p></div>
<p><strong>Final Assembly</strong></p>
<p>To assemble the bar graphs, I soldered all the surface mount components to the board. After these were done, I stuffed the LEDs into their pads and placed the 3D printed LED holder over the LEDs. I then very carefully soldered the LEDs in place. After soldering all the LEDs, I removed the LED holder to see how they looked:</p>
<div id="attachment_697" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/06.no-holders.DSC_1684.jpg"><img class="size-large wp-image-697" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/06.no-holders.DSC_1684-1024x683.jpg" alt="No way the soldering job would be this neat without the use of a 3D printed part to hold the LEDs in place during assembly." width="640" height="427" /></a><p class="wp-caption-text">No way the soldering job would be this neat without the use of a 3D printed part to hold the LEDs in place during assembly.</p></div>
<p>Here’s the assembled LED bar graph with the LED holder and board holder in place:</p>
<div id="attachment_698" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/07.assembled.DSC_1689.jpg"><img class="size-large wp-image-698" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/07.assembled.DSC_1689-1024x683.jpg" alt="Assembled LED bar graph." width="640" height="427" /></a><p class="wp-caption-text">Assembled LED bar graph.</p></div>
<p><strong>More Ideas and Options</strong></p>
<p>In addition to the surface mount snap-in mounting bracket, I made a panel mount for the LED bar graphs:</p>
<div id="attachment_699" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/08.panel_mount.DSC_1678.jpg"><img class="size-large wp-image-699" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/08.panel_mount.DSC_1678-1024x682.jpg" alt="Panel mount. With a circular diffused gray translucent acrylic cover, this would look even better." width="640" height="426" /></a><p class="wp-caption-text">Panel mount. With a circular diffused gray translucent acrylic cover, this would look even better.</p></div>
<p>One of the coolest things about 3D printing your own bar graphs is that you’re no longer limited to mass produced bar graph displays in stock shapes. You can make your own displays in any shape you want. For my <a href="https://youtu.be/48f4Io2PyE8">zombie containment unit</a>, I made one circular red display and a 2nd display in the shape of a squiggle. I mounted both of these to an aluminum panel and stuck it to the front of the prop:</p>
<div id="attachment_702" style="width: 650px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-1.02.44-PM.png"><img class="size-large wp-image-702" src="http://bikerglen.com/wp/wp-content/uploads/2017/04/Screen-Shot-2017-04-29-at-1.02.44-PM-1024x574.png" alt="A circular bar graph and a randomly shaped bar graph on my zombie containment unit Halloween prop." width="640" height="359" /></a><p class="wp-caption-text">A circular bar graph and a randomly shaped bar graph on my zombie containment unit Halloween prop.</p></div>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/custom-3d-printed-led-bar-graphs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building an Enclosure using SketchUp and 3D Printing</title>
		<link>https://bikerglen.com/blog/building-an-enclosure-using-sketchup-and-3d-printing/</link>
		<comments>https://bikerglen.com/blog/building-an-enclosure-using-sketchup-and-3d-printing/#comments</comments>
		<pubDate>Sun, 01 Jun 2014 17:08:32 +0000</pubDate>
		<dc:creator><![CDATA[Glen]]></dc:creator>
				<category><![CDATA[3D CAD/CAM]]></category>
		<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[SketchUp]]></category>

		<guid isPermaLink="false">http://bikerglen.com/blog/?p=168</guid>
		<description><![CDATA[The image above shows two enclosures for a printed circuit board design. These were designed using the inexpensive hobbyist version of CadSoft Eagle and the free maker version of Trimble SketchUp. The free version NetFabb Basic was used to check &#8230; <a href="https://bikerglen.com/blog/building-an-enclosure-using-sketchup-and-3d-printing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div id="attachment_169" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/enclosure2.jpg"><img class="size-large wp-image-169" title="3D Printed Enclosures" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/enclosure2-1024x683.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">3D printed enclosures designed using SketchUp</p></div>
<p>The image above shows two enclosures for a printed circuit board design. These were designed using the inexpensive hobbyist version of CadSoft Eagle and the free maker version of Trimble SketchUp. The free version NetFabb Basic was used to check the design for manufacturing. The enclosures were finally 3D printed at shapeways.com using their EOS Formiga P110 SLS 3D printers. Read on to see some of the lessons I learned while designing and printing these enclosures.</p>
<p><span id="more-168"></span></p>
<h2>Find or Design a Board</h2>
<p>The first step is to find or design a board. The board I used is a quad RS-422 differential transmitter board. It has a Digilent PMOD connector for connecting to an FPGA board and four TI differential transmitters chips that connect to Phoenix Contact terminal blocks. There’s a fifth terminal block for a +5V power input and a power supply on the board as well.</p>
<div id="attachment_172" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/board.jpg"><img class="size-large wp-image-172" title="Differential Transmitter Board" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-1024x392.jpg" alt="" width="640" height="245" /></a><p class="wp-caption-text">The board to be enclosed. The board uses through-hole components and has 1206 resistors on the reverse side so room for the pins and resistors is needed between the board and the bottom of the enclosure.</p></div>
<p>At this point, open up the board file in Eagle and note some key measurements.</p>
<div id="attachment_175" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-eagle.jpg"><img class="size-full wp-image-175" title="The Board in Eagle" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-eagle.jpg" alt="" width="640" height="489" /></a><p class="wp-caption-text">The board to be enclosed as seen in the Eagle PCB editor.</p></div>
<p>The board measures 1800 by 1350 mil. The holes are 125 mil diameter and are inset 125 mil from each board edge.</p>
<h2>Export the Board from Eagle and Import into SketchUp</h2>
<p>To export the board from Eagle and import the board into SketchUp requires the set of <a href="http://eagleup.wordpress.com/">EagleUp</a> plugins for Eagle PCB and SketchUp. The EagleUp Export ULP script is used from within the Eagle PCB editor to export the board geometry, bill of materials, and component placement information to a .eup file. The .eup file is then imported into SketchUp using the EagleUp Import plugin. Once the plugins are installed, the steps required to perform the export and import are as follows:</p>
<ol>
<li>Open the board in Eagle PCB.</li>
<li>Run the eagleUp_Export.ulp ULP. I’m only interested in the board geometry and parts so I selected the no silk layers and no image options at export. Click OK and the .eup file will be created.</li>
<li>Launch SketchUp and open a new file. Run the EagleUp Import plugin from the SketchUp Plugins menu on the .eup file created in Eagle. I could only get the EagleUp import plugin to run successfully if I set the model units to decimal millimeters with a precision of 0.001mm.</li>
<li>Set the model units to the same units used in Eagle. I used decimal inches with a resolution of 1 mil since the board design was done in mils. Measure the board to make sure it is the same dimensions as in Eagle.</li>
</ol>
<div id="attachment_176" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-skp-1.jpg"><img class="size-full wp-image-176" title="Board Missing Key Components" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-skp-1.jpg" alt="" width="640" height="427" /></a><p class="wp-caption-text">The board as initially imported into SketchUp. A lot of components are missing.</p></div>
<p>At this point, you’ll have a 3D model of your board in SketchUp but a lot of the parts may be missing depending on the parts on your board versus the parts in your 3D component library.</p>
<h2>Add Missing Parts</h2>
<p>Now to add the missing parts to the board. Search the internet for 3D models of any missing components. You’ll need the components in either .skp or .stl format. Some manufacturers provide 3D models directly on their website. Others you’ll have to find on 3rd party websites. Key components to include are things that impact the dimensions of the enclosure such as the tallest component on either side of the board, and connectors, switches, or indicators that will pierce a wall of the enclosure.</p>
<p>In the case of my board, I added the missing Samtec terminal strip and the five missing Phoenix connectors to the board. I judged the rest of the parts to be inconsequential to the design of the enclosure. After I found the components, I imported the STL for each component and used the move and rotate tools to place the components on the board.</p>
<div id="attachment_177" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-skp-2.jpg"><img class="size-full wp-image-177" title="Board with All Key Components" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-skp-2.jpg" alt="" width="640" height="427" /></a><p class="wp-caption-text">The board with all key components properly located and sized.</p></div>
<h2>Design the Bottom of the Enclosure</h2>
<p>Here are the dimensions used to design the bottom of the enclosure:</p>
<table>
<tbody>
<tr>
<th>Description</th>
<th>Size</th>
<th>Notes</th>
</tr>
<tr>
<td>Bottom Height</td>
<td>0.350&#8243;</td>
<td>Somewhat arbitrary but at least sum of bottom thickness and PCB bottom clearance.</td>
</tr>
<tr>
<td>Bottom Thickness</td>
<td>0.100&#8243;</td>
<td>Chosen so an M3 nut can be completely recessed into bottom of enclosure.</td>
</tr>
<tr>
<td>Edge Thickness</td>
<td>0.050&#8243;</td>
<td>Chosen based on capabilities of 3D printer.</td>
</tr>
<tr>
<td>PCB Edge Clearance:</td>
<td>0.045&#8243;</td>
<td>Somewhat arbitrary but at least 0.005&#8243; on each edge.</td>
</tr>
<tr>
<td>PCB Bottom Clearance:</td>
<td>0.075&#8243;</td>
<td>Needs to clear pins on through-hole parts, SMD resistors on back of board.</td>
</tr>
<tr>
<td>PCB Thickness:</td>
<td>0.063&#8243;</td>
<td>From the board vendor.</td>
</tr>
<tr>
<td>M3 Nut Dimensions:</td>
<td>5.5mm (0.217&#8243;) across flats, 2.4mm (.095&#8243;) thick.</td>
<td>From the nut vendor.</td>
</tr>
</tbody>
</table>
<p>Use the tape measure tool to draw some guides to indicate the outline of the PCB board. Remember that this board is 1.800&#8243; by 1.350&#8243; with a 0.100&#8243; corner radius and four 0.125&#8243; diameter holes in the corners inset 0.125&#8243; from each edge.</p>
<div id="attachment_205" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-guides1.png"><img class="size-large wp-image-205" title="PCB Board Guides" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/board-guides1-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Guides indicating the edges of the PCB.</p></div>
<p>The enclosure will have 0.050&#8243; thick side walls 0.045&#8243; from the edge of the PCB board. The outside corner radius of the enclosure wall will be 0.125&#8243;. The inside corner radius will be 0.075&#8243;. These radii will give a wall thickness of 0.050&#8243; in the corners and clear the rounded corners of the PCB. Create guides at the outside wall edges, the inside wall edges, and centers of the corner radii. The picture below shows the upper left corner once the guides are created. Repeat for the remaining corners.</p>
<div id="attachment_206" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-guides.png"><img class="size-large wp-image-206" title="Bottom Guides" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-guides-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Upper left corner of the guides indicating the enclosure edges. Lines and arcs are for illustration only. Don’t create them yet.</p></div>
<p>Draw lines and arcs for the outside edges of the enclosure. Use the push/pull tool to pull the resultant plane down into a 0.100&#8243; thick solid.</p>
<p><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-bottom-extruded.png"><img class="alignleft size-large wp-image-207" title="Bottom Extruded" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-bottom-extruded-1024x594.png" alt="" width="640" height="371" /></a></p>
<p>Now create guides, lines, and arcs for the features on the inside of the bottom of the case. These include the holes for the M3 bolts that will run through both the enclosure and the PCB as well as supports for the bottom of the PCB. I made my supports 0.345&#8243; by 0.335&#8243;. These need to clear any components or pins located on the bottom of the PCB.</p>
<div id="attachment_209" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-inside-features.png"><img class="size-large wp-image-209" title="Bottom Inside Features" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-inside-features-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Create guides then draw lines and circles for the features inside the bottom of the case.</p></div>
<p>Use the push/pull tool to extrude the side wall up 0.250&#8243;. Use the push/pull tool to extrude each of the PCB supports up 0.075&#8243;. After moving the first PCB support up 0.075&#8243;, you can double click the remaining three supports to extrude them up by the same amount.</p>
<p><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-inside-extruded.png"><img class="alignleft size-large wp-image-211" title="Inside Features Extruded" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-inside-extruded-1024x594.png" alt="" width="640" height="371" /></a></p>
<p>Now that we know where the PCB needs to rest in the enclosure, unhide the PCB and move the bottom face of the PCB to rest on the top face of the PCB supports. Unhiding the PCB will also let you check clearances on the bottom and sides of the board.</p>
<div id="attachment_215" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-inside-clearances.png"><img class="size-large wp-image-215" title="Board Placement" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-inside-clearances-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Board properly placed inside bottom of enclosure.</p></div>
<p>Hide the board and add the nut recesses to the bottom of the enclosure. The nuts are 0.217&#8243; across their flats. If we make the nut recesses 0.270&#8243; across their corners, that will give the recess a distance of 0.234&#8243; across the flats and a clearance on each side of the nut of 0.0085&#8243;. The nuts are 0.095&#8243; thick. A recess depth of 0.100&#8243; will allow the nuts to sit flush with the bottom of the enclosure.</p>
<p>The hex extrusions should be centered at 0.220&#8243; from each outside edge to center them on the holes in the PCB and the PCB supports. Lastly, delete the circular planes at the bottom of the hex extrusions to create the 0.125&#8243; holes completely through the bottom of the enclosure.</p>
<div id="attachment_216" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-hex-extruded.png"><img class="size-large wp-image-216" title="Hex Extrusions" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/bottom-hex-extruded-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Extrusions for hex nuts on bottom of enclosure.</p></div>
<p>Group the bottom of the enclosure into its own group. This will prevent the bottom and top of the enclosure from merging into a single blob as we create the top of the enclosure in the next step. The bottom of the enclosure is now complete except for the connector cut outs. We’ll design the top of the enclosure first then make cut outs for the connectors at the end of the design process.</p>
<h2>Design the Top of the Enclosure</h2>
<p>Here are the dimensions used to design the top of the enclosure:</p>
<table>
<tbody>
<tr>
<th>Description</th>
<th>Size</th>
<th>Notes</th>
</tr>
<tr>
<td>Top Height</td>
<td>0.300&#8243;</td>
<td>Chosen to accommodate height of all components and nearest available M3 bolt length.</td>
</tr>
<tr>
<td>Top Thickness</td>
<td>0.100&#8243;</td>
<td>Chosen to be same as the bottom of the enclosure.</td>
</tr>
<tr>
<td>Edge Thickness</td>
<td>0.050&#8243;</td>
<td>Chosen based on capabilities of 3D printer.</td>
</tr>
<tr>
<td>PCB Top Clearance:</td>
<td>0.312&#8243;</td>
<td>Needs to clear all components on top of board.<br />
Top clearance is overall enclosure height minus thickness of top and bottom, PCB thickness, and PCB bottom clearance:<br />
(0.350+0.300) &#8211; (0.100+0.100+0.063+0.075) = 0.312&#8243;.</td>
</tr>
<tr>
<td>Available M3 Bolt Lengths:</td>
<td>12mm, 15mm (less common), 16mm</td>
<td>Threaded length excluding bolt head; from bolt vendor.</td>
</tr>
</tbody>
</table>
<p>Double click into the bottom enclosure group, orbit to view the bottom of the enclosure, and select the plane forming the bottom of the enclosure. Right clock and select the bounding edges. Copy the bottom plane and connected edges to the clipboard then exit the group. Paste the edges 0.200&#8243; above the top of the bottom of the enclosure.</p>
<div id="attachment_225" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step01.png"><img class="size-large wp-image-225" title="Duplicate Bottom Plane" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step01-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Duplicate the bottom of the enclosure to 0.1&quot; below the top of the enclosure.</p></div>
<p>Delete the hexagonal holes and extrude the plane up 0.100&#8243; to form the top of the enclosure.</p>
<div id="attachment_226" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step02.png"><img class="size-large wp-image-226" title="Beginnings of the Enclosure Top" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step02-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Extrude the top plane up to the desired thickness of the enclsoure top.</p></div>
<p>Hide the enclosure bottom and orbit the camera to view the bottom of the enclosure’s top. Add the outline of the inside wall to the enclosure. This wall is 0.050&#8243; thick and has a corner radius of 0.075&#8243;.</p>
<div id="attachment_227" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step03.png"><img class="size-large wp-image-227" title="Inside Wall Outline" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step03-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Add the outline of the inside wall to the bottom of the top of the enclosure.</p></div>
<p>Extrude the enclosure wall down (up in the camera view) 0.200&#8243;.</p>
<div id="attachment_228" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step04.png"><img class="size-large wp-image-228" title="Inside Wall Extruded" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step04-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Use the push/pull tool to extrude the inside wall down 0.200&quot; toward the enclosure bottom.</p></div>
<p>Add the internal PCB supports. These are 0.250&#8243; in diameter and centered on the holes in the PCB. Draw guides 0.170&#8243; from each interior edge wall to locate the center of the PCB holes on the lid of the enclosure. Draw a circle with a radius of 0.125 at each of the four intersections and extrude the circle down by the PCB top clearance, 0.312&#8243;.</p>
<div id="attachment_229" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step05.png"><img class="size-large wp-image-229" title="Intenal PCB Supports" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step05-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Extrude the internal PCB supports down from the top toward the PCB.</p></div>
<p>Orbit the view back to the top of the enclosure to add the screw head recesses to the top of the top of the enclosure. These are centered above the holes in the PCB. Draw guides at 0.220&#8243; from the outside edge. Center a circle 0.250&#8243; in diameter on these guides in each corner then extrude the circle downward 0.050&#8243;. The diameter of the head of the bolt is just under 0.250&#8243; and will fit inside the recess. The bolt head is slightly thicker than 0.050&#8243; and will protrude very slightly from the top of the enclosure.</p>
<div id="attachment_231" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step06.png"><img class="size-large wp-image-231" title="M3 Bolt Head Recesses" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step06-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Add 0.050&quot; deep recesses for the heads of the M3 bolts.</p></div>
<p>Add 0.125&#8243; diameter holes all the way through the PCB supports and enclosure top. This is easier to do from the bottom. Draw a 0.125&#8243; diameter circle in the center of each PCB support. Extrude the circle up to the bottom of the recess in the top of the enclosure to from a hole all the way through the PCB support and the top of enclosure.</p>
<div id="attachment_232" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step07.png"><img class="size-large wp-image-232" title="Extrude Bolt Holes" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step07-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Extrude bolt holes through the PCB supports and top of the enclosure. This is easiest to do from the bottom of the PCB supports.</p></div>
<p>Group the enclosure top into its own group so that it other entities can be added to the drawing without affecting the geometry of the enclosure top. The top is now complete except for the enclosure cut outs which we will add in a later step. Unhide the bottom of the enclosure and the PCB board.</p>
<div id="attachment_236" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step08.png"><img class="size-large wp-image-236" title="Enclosure Top and Bottom" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/top-step08-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Enclosure top and bottom are complete except for connector cut outs. Verify available bolt lengths will fit your enclosure.</p></div>
<p>At this point, verify that bolts are available that will extend from the bottom of the recess in the enclosure top to the bottom of the enclosure. This distance is 0.600&#8243;. It’s the height of the enclosure (0.350&#8243; + 0.300&#8243;) minus the bolt head recess depth (0.050&#8243;). 0.600&#8243; is 15.24mm. M3x15mm bolts (which are less common than M3x16mm bolts) can be used to hold the enclosure together. If you are unable to obtain M3x15mm bolts, adjust the top enclosure height to be 1mm taller.</p>
<h2>Make Cut Outs for Connectors</h2>
<p>Let’s start with the five Phoenix Contact connectors and the bottom of the enclosure. Hide the top of the enclosure but leave the enclosure bottom and PCB visible. I usually leave a clearance of 0.005&#8243; to 0.010&#8243; around each edge of connector depending on the precision of the printing/machining, machine assembly vs hand assembly, etc. For 3D printed plastic with a hand-assembled PCB, I’m going to use a clearance of 0.010&#8243; on each edge to be on the safe side.</p>
<p>Use the measuring tape tool to put guide points on both the inside edges and outside edges of the enclosure bottom. These guide points should be 0.010&#8243; from the intersection of each connector with the top edge of the enclosure bottom and along the enclosure edge. When you’re done, you’ll have 20 of these guide points. Connect each pair with lines perpendicular to the enclosure edges. Remember to make the lines inside the group with the enclosure bottom. As tedious as this process is, at least we can use the snap to intersection feature of SketchUp versus using a calculator to calculate these points from the connector data sheet and PCB layout.</p>
<div id="attachment_243" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/cutouts-step-01.png"><img class="size-large wp-image-243" title="Mark Locations for Cut Outs" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/cutouts-step-01-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Mark the location of the cut outs for the connectors 0.010&quot; from the edge of each connector.</p></div>
<p>Draw a guide line on all sides about 0.010 below the connectors. I made my guide line 0.225&#8243; from the bottom edge of the enclosure. Use the push/pull tool to lower the side walls to the guide lines underneath each of the five connectors.</p>
<div id="attachment_245" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-02.png"><img class="size-large wp-image-245" title="Sides Lowered" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-02-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Use the push/pull tool to lower the sides below the connectors.</p></div>
<p>Let’s move to the 6 position, 0.100&#8243; pitch, single row header. I want this cut out to be 0.700&#8243; wide and centered on the header. I also want the bottom of the cut out to be inline with the bottom of the Phoenix Contact connectors. I drew a guide up 0.225&#8243; from the bottom of the enclosure then centered two lines 0.700&#8243; apart on the top edge of the enclosure bottom.</p>
<div id="attachment_246" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-03.png"><img class="size-large wp-image-246" title="Header Guides" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-03-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Guides used to lower the side wall around the header connector.</p></div>
<p>I then used the push/pull tool to lower the side wall to the guide line.</p>
<p><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-04.png"><img class="alignleft size-large wp-image-247" title="Cut Out for Header" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-04-1024x594.png" alt="" width="640" height="371" /></a></p>
<p>That completes the enclosure bottom. Time to move to the enclosure top. Use the unhide command to unhide the enclosure top. Double click into the enclosure top group and create guide lines at the edge of each lowered wall on the enclosure bottom. We’ll use these guides to transfer the dimensions and cut outs from the bottom of the enclosure to the top of the enclosure. This is probably easiest done with the PCB hidden. Now create a guide line 0.120&#8243; from the top of the enclosure on each side with a Phoenix Contact connector. This will be the height of the cut outs for the Phoenix Contact connectors. On the single row header side, create a guide 0.280 down from the top of the enclosure.</p>
<div id="attachment_249" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-06.png"><img class="size-large wp-image-249" title="Top Cut Out Guides" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-06-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">The guides for the cut outs in the enclosure top.</p></div>
<p>Hide the bottom of the enclosure and orbit the camera to view the top of the enclosure. Use the guides to draw lines across the enclosure edge for each cut out then use the push/pull tool to lower the side walls for each connector.</p>
<div id="attachment_250" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-07.png"><img class="size-large wp-image-250" title="Top Cut Outs Completed" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/cutouts-step-07-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">Complete the top cut outs by drawing lines across the edges and using the push/pull tool to lower each side wall.</p></div>
<p>Delete the guides and unhide the PCB. The enclosure design is done.</p>
<div id="attachment_251" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/completed.png"><img class="size-large wp-image-251" title="The Completed Enclosure" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/completed-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">The completed enclosure.</p></div>
<p>Now would be a good time to use the orbit tool to admire your work / check  your work for mistakes. Check clearances around the board edges, the top of the board, the bottom of the board, the connectors, where the enclosure top and enclosure bottom meet, etc.</p>
<h2>Designing a Mounting Bracket for the Enclosure</h2>
<p>I designed a bracket for mounting the enclosure to a flat surface. The bracket has 0.010&#8243; clearances to each edge of the enclosure as well as 0.010&#8243; clearance to the top and bottom surfaces of the enclosure. All bracket walls are 0.100&#8243; thick. Across the four legs on the bottom are DIN74A countersinks for M3 screw heads.</p>
<div id="attachment_253" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/holder-1.png"><img class="size-large wp-image-253" title="Holder" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/holder-1-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">The mounting bracket for the enclosure.</p></div>
<p>The bracket works by bolting it to a flat surface then snapping the enclosure into the bracket.</p>
<div id="attachment_258" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/holder-21.png"><img class="size-large wp-image-258" title="Enclosure and Mounting Bracket" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/holder-21-1024x594.png" alt="" width="640" height="371" /></a><p class="wp-caption-text">The enclosure mounted in the mounting bracket.</p></div>
<p>The bracket design is a bit more complicated than the enclosure design but the techniques outlined in this tutorial still apply. The important parts to remember are the clearances and wall thicknesses. Again all walls are 0.100&#8243; and the clearance from any surface of the bracket to any surface of the enclosure is 0.010&#8243;. The inside corner radius is 0.150&#8243; and the outside corner radius is 0.225&#8243;.</p>
<h2>Exporting the STL</h2>
<p>To 3D print the model, you will need an STL file. To generate the STL file, you’ll need the <a href="http://extensions.sketchup.com/en/content/sketchup-stl">Export STL plugin</a> for SketchUp. Once the plugin is installed, you’ll need to export the different pieces of the enclosure in separate files. Open the SketchUp file for the enclosure. Select the top half of the enclosure then select Export STL… from the File menu.</p>
<p>Make sure “Export Selected Geometry Only” is checked, export unit is “Model Units,” and File Format is “ASCII.” Click “Export” and save the exported STL with a recognizable filename and in a convenient location.</p>
<p>Repeat the above process except this time select only the bottom half of the enclosure. If you designed a mounting bracket or want to print the mounting bracket from the tutorial example files, select the mounting bracket and repeat the process a third time.</p>
<p>Once the three files are exported, move on to the next step to check the manufacturability of your design.</p>
<h2>Checking the STL for Errors</h2>
<p><a href="http://www.netfabb.com/downloadcenter.php?basic=1">Netfabb Basic </a>is a free version of Netfabb. Netfabb is a tool for checking the manufacturability of STL designs using the 3D additive printing processes. Download, install, and register the tool. Once it’s setup, launch the tool.</p>
<p>For each STL file to be printed, repeat the following process:</p>
<ol>
<li>Select Project -&gt; Add Part.</li>
<li>Select the STL file using the open file dialog box.</li>
<li>If you don’t see a large exclamation mark inside a triangle in the lower right hand corner of the screen next to your part, your part is ready to go.</li>
<li>If you do see a large exclamation mark, you’ll need to run the design analysis tools to find out what is wrong.</li>
<li>Repeat the above process for each STL file.</li>
</ol>
<p>To run a design analysis, select Extras -&gt; New Analysis -&gt; Standard Analysis. The analysis will run and a box in the lower right hand corner of the screen will list some information about your design.</p>
<div id="attachment_263" style="width: 306px" class="wp-caption alignnone"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/Screen-Shot-2014-06-01-at-10.21.49-AM.png"><img class="size-full wp-image-263 " title="Netfabb Basic Part Analysis Output" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/Screen-Shot-2014-06-01-at-10.21.49-AM.png" alt="" width="296" height="390" /></a><p class="wp-caption-text">Netfabb Basic part analysis output for an STL file that is ready for manufacturing.</p></div>
<p>For your part to be manufacturable, the number of shells needs to be equal to 1 (assuming you only have one part in the STL file), the surface must be closed, and there should be no flipped triangles.</p>
<p>If there’s a problem with your design, you can let Netfabb Basic attempt to repair your STL file automatically or you can fix the design in SketchUp, re-export the STL, and check the STL file again.</p>
<p>Generally speaking, one of three things happens to make your design fail manufacturability checks:</p>
<ol>
<li>Reversed faces. The back sides of the faces in SketchUp are drawn in a purplish color. Any exposed purple face is a reversed face. To fix reversed faces in SketchUp, select any faces that appear purplish and select Edit -&gt; Face -&gt; Reverse Faces. The faces should appear grayish now.</li>
<li>Missing external wall. Missing external walls can be found by orbiting the module and looking for holes in the external surface. To fix a missing external walls, use the line tool to draw a line from one existing point to another existing point along the surface where the face should be. SketchUp will draw the missing face as soon as the line is completed.</li>
<li>Internal walls. Internal walls are the most difficult problems to locate because they are internal to the model and are completely hidden by the model’s exterior walls. They can be found using a combination of the SketchUp Section Plane tool and by viewing the model using the X-ray style (View -&gt; Face Style -&gt; X-ray). Generally speaking, you’re looking for any faces that are internal to the model. These faces need to be deleted once they’re found.</li>
</ol>
<p>For more details on repairing a model, Shapeways has a <a href="http://www.shapeways.com/tutorials/how_to_use_meshlab_and_netfabb">great tutorial</a> on using Netfabb Basic to repair a part’s geometry.</p>
<h2>Ordering the Enclosure Parts</h2>
<p>Once the parts are fixed, it’s time to 3D print them either using your own printer or using a service bureau. Since I don’t own a 3D printer (yet), I have to use a service bureau to print my models. The two services that I have used are <a href="http://www.shapeways.com/">Shapeways</a> and <a href="http://www.sculpteo.com/en/">Sculpteo</a>. They both print models out of PA2200 nylon using a selective laser sintering process (SLS) on EOS Formiga P110 printers. They both are relatively affordable and offer a variety of colors and finishes for your designs. Sculpteo tends to be a little faster (3 days for basic white) than Shapeways (up to 10 days for basic white).</p>
<p>Sculpteo offers the option of printing in colored plastic without surface polishing. When printing in color with Shapeways, the surfaces are always polished. Polishing can knock down fine edges on a model. For example, the small thin walls between the two Phoenix Contact connectors in this design run the risk of being broken during the polishing process. Also the enclosure walls may be a bit thinner at the top than they are at the bottom after polishing.</p>
<p>I’d recommend creating an account on both services, uploading the STL for the designs to both services, then experimenting with different materials and finishes on each to find the optimum combination of material, color, shipping times, and cost.</p>
<p>Be sure the model units and dimensions on the printing service match the units and dimensions in SketchUp! Uploading a file exported in inches and selecting millimeters at the service bureau can result in a much smaller 3D print than expected! Sculpteo has an option to download a blueprint of the model with the dimensions called out. I recommend taking advantage of this to verify the dimensions of your model before printing.</p>
<p>At Shapeways, I’ve successfully printed these models out of their Strong &amp; Flexible Plastic and their Polished Strong &amp; Flexible Plastic materials. When using the polished material, you may need to submit designs with thin / small pieces with the ”Print it anyways!” option. This will cause them to skip their manufacturability checks and print your model regardless of any design rule violations.</p>
<p>At Sculpteo, I’ve successfully printed these models out of white plastic and colored plastic. I have not used the polished plastic option.</p>
<h2>The Results</h2>
<p>I’m happy with the results of designing and printing this enclosure. Below are some photographs of the enclosure in both white and red plastic with the mounting bracket printed in black plastic.</p>
<div id="attachment_169" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/05/enclosure2.jpg"><img class="size-large wp-image-169" title="3D Printed Enclosures" src="http://bikerglen.com/wp/wp-content/uploads/2014/05/enclosure2-1024x683.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">3D printed enclosures designed using SketchUp</p></div>
<div id="attachment_270" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/1.jpg"><img class="size-large wp-image-270" title="Red Bits and Pieces" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/1-1024x681.jpg" alt="" width="640" height="425" /></a><p class="wp-caption-text">The enclosure printed in red polished plastic and black plastic at Shapeways.</p></div>
<div id="attachment_271" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/2.jpg"><img class="size-large wp-image-271" title="Enclosure Parts and Pieces" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/2-1024x681.jpg" alt="" width="640" height="425" /></a><p class="wp-caption-text">The enclosure printed in red polished plastic and black plastic at Shapeways.</p></div>
<div id="attachment_276" style="width: 650px" class="wp-caption alignleft"><a href="http://bikerglen.com/wp/wp-content/uploads/2014/06/enclosures.jpg"><img class="size-large wp-image-276" title="Two Enclosures" src="http://bikerglen.com/wp/wp-content/uploads/2014/06/enclosures-1024x682.jpg" alt="" width="640" height="426" /></a><p class="wp-caption-text">Same two enclosures. White versus polished red PA2200 nylon.</p></div>
<h2>Resources</h2>
<p>These designs are part of the my led-pixels BeagleBone Black project. I’ve uploaded the SketchUp and STL files for this tutorial to my Github repository for this project. Note that the tutorial files were purpose built for the tutorial after printing my design. As such, I’ve not actually printed these files. Use them at your own risk. The enclosure tutorial files are located inside the mechanical/enclosure-tutorial folder of <a href="https://github.com/bikerglen/beagle/tree/master/projects/led-pixels/">this project repository directory on github</a>. I’ve also uploaded the exact files used to order the 3D prints of the enclosure shown in the photos to the mechanical/enclosure-as-built folder of the same repository.</p>
]]></content:encoded>
			<wfw:commentRss>https://bikerglen.com/blog/building-an-enclosure-using-sketchup-and-3d-printing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
