<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.emsley.ca/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.emsley.ca/" rel="alternate" type="text/html" /><updated>2026-10-03T17:37:10-04:00</updated><id>https://www.emsley.ca/feed.xml</id><title type="html">Interesting Things</title><subtitle>This is a brain dump of things I learn at work and home, various projects I&apos;ve worked on, etc. It&apos;s mostly for my own reference, but if other people find it interesting or helpful, great!
</subtitle><author><name>Grant Emsley</name></author><entry><title type="html">A DIY CO2 Monitor for the Basement Office</title><link href="https://www.emsley.ca/hardware/diy-co2-monitor" rel="alternate" type="text/html" title="A DIY CO2 Monitor for the Basement Office" /><published>2026-10-03T00:00:00-04:00</published><updated>2026-10-03T00:00:00-04:00</updated><id>https://www.emsley.ca/hardware/diy-co2-monitor</id><content type="html" xml:base="https://www.emsley.ca/hardware/diy-co2-monitor"><![CDATA[<p>My office is in the basement, and the only outside air it gets comes through one tiny window. It doesn’t take long for it to feel stuffy in there, and I wanted to see if it’s getting bad enough to actually affect me. High CO2 doesn’t really hurt you at typical office levels, but it does make you tired and foggy, which isn’t great when you’re trying to think.</p>

<p>There are plenty of CO2 monitors out there, but most of the cheap ones aren’t really measuring CO2 at all, and the good ones are expensive for something that only needs to report one number to Home Assistant. So I built one with a real sensor for under C$30 in parts with a nice 3D printed case.</p>

<figure class="image">
  <a href="/images/diy-co2-monitor/finished-wall-bracket.jpg">
    <img src="/images/diy-co2-monitor/finished-wall-bracket.jpg" alt="The finished monitor on the office wall" style="max-width: 300px" />
    <figcaption>The finished monitor on the office wall</figcaption>
  </a>
</figure>

<h2 id="why-not-just-buy-one">Why not just buy one?</h2>

<p>A few things ruled out the off the shelf options:</p>

<ul>
  <li>A lot of cheap “CO2” sensors (SGP30, CCS811, ENS160) don’t measure CO2. They measure VOCs and <em>estimate</em> CO2 from them, which they call “eCO2”. It’s a guess, and not a good one. A real sensor uses NDIR or photoacoustic sensing - something like the Sensirion SCD4x, SCD30, or Senseair S8.</li>
  <li>Almost every real CO2 sensor has automatic self calibration turned on. It assumes the sensor sees fresh outdoor air (about 400 ppm) once a week or so, and quietly treats the lowest reading it sees as 400. In my basement, it’s unlikely it sees enough fresh air to calibrate properly, so it would slowly drift towards incorrectly lower readings. Few ready made CO2 monitors let you control the calibration, but ESPHome does.</li>
  <li>I went with the SCD41 over the cheaper SCD40 because its accuracy is rated up to 5000 ppm instead of 2000. A stuffy basement can go over 2000, and the difference was a few dollars.</li>
</ul>

<p>What I looked at before deciding to build one (prices from September 2026):</p>

<ul>
  <li><strong>IKEA ALPSTUGA</strong> (C$49.99) has a real Sensirion sensor in it, but it’s Matter over Thread, and I don’t have a Thread border router yet. It’s not quite as accurate or configurable, but for the price it’s quite tempting.</li>
  <li><strong>SwitchBot Meter Pro CO2</strong> (about C$68 on sale) - I couldn’t confirm what sensor it actually uses, and it’s Bluetooth.</li>
  <li><strong>Apollo AIR-1</strong> (about US$110 plus duties) is a great ESPHome device, but it uses an SCD40 at 4-5 times the cost of building one.</li>
  <li><strong>Aranet4</strong> (C$239) and the <strong>AirGradient ONE</strong> (C$320 kit) are both good, but overkill for just CO2.</li>
  <li><strong>Airthings View Plus</strong> - close to C$400, and cloud based. They seem to make nice hardware, but I’m definitely not their target audience.</li>
</ul>

<p>The original plan was to put the sensor on a spare Cheap Yellow Display (an ESP32 with a touchscreen) and show a colour coded number on my desk. That display ended up getting used for something else, so I switched to a plain D1 mini with no display. The readings show up on the screens I already have through Home Assistant, which is honestly fine.</p>

<h2 id="parts">Parts</h2>

<ul>
  <li>A Sensirion SCD41 breakout board from AliExpress, about C$27. It’s tiny - 21.7 x 15.8mm. The sensor is laser marked SCD41 with a DataMatrix code like Sensirion’s own parts, so it looked genuine. More on how to check that below.</li>
  <li>A Wemos D1 mini (ESP8266) MCU I’ve had lying in a drawer for years, with no headers soldered on.</li>
  <li>4 wires, soldered straight into both boards: 3V3, GND, D2 for SDA and D1 for SCL.</li>
  <li>A USB wall adapter and a micro USB cable.</li>
  <li>A 3D printed case.</li>
</ul>

<figure class="image">
  <a href="/images/diy-co2-monitor/scd41-ruler.jpg">
    <img src="/images/diy-co2-monitor/scd41-ruler.jpg" alt="The SCD41 breakout. The metal can is the sensor." style="max-width: 300px" />
    <figcaption>The SCD41 breakout. The metal can is the sensor.</figcaption>
  </a>
</figure>

<p>There’s no perfboard on purpose. Mounting both boards on one piece of perfboard would conduct the ESP’s heat straight to the sensor, which is the exact problem the case is designed to avoid.</p>

<p>An important tip for the sensor - that white sticker on the top might look like a protective cover you’re supposed to remove. That was my first thought, and I’m glad I looked it up first. It’s not a removable cover - it’s a filter that protects the sensor from dust and contaminants while letting air flow through. Remove it and the sensor is trashed.</p>

<h2 id="the-heat-problem">The heat problem</h2>

<p>The MCU runs a few degrees warm with Wi-Fi on, and how warm changes as the Wi-Fi activity changes. That doesn’t really affect the CO2 reading itself - the SCD41 compensates internally with its own temperature and humidity sensor, and Sensirion’s datasheet says the temperature offset setting doesn’t impact the accuracy of the CO2 output. But it does throw off the temperature and humidity it reports, and those are useful readings too. A steady offset can be calibrated out. One that fluctuates depending on the activity of another device can’t.</p>

<p>Sensirion publishes a design-in guide for the SCD4x that covers this, and boils down to:</p>

<ul>
  <li>Put a large opening right at the sensor, with as little dead air inside as possible, and keep the sensor’s air sealed off from the rest of the device.</li>
  <li>Put the sensor in the lowest, coldest part of the device, as far from the microcontroller and Wi-Fi as possible.</li>
  <li>Keep it out of drafts and sun, and don’t cover the membrane.</li>
</ul>

<p>Most DIY builds I’ve seen stick the sensor right on top of the ESP in a little box, which is about the worst case on every one of those points.</p>

<p>Sealing the sensor’s air off matters, because drafts will throw off the reading. With the D1 sitting above the sensor, its warm air rising could turn the whole thing into a little chimney, making a constant draft over the sensor. This case solves that by leaving only a small hole for the wires, and sealing that with hot glue.</p>

<h2 id="designing-the-case-with-ai">Designing the case with AI</h2>

<p>I didn’t design this case. At least not in the traditional sense.</p>

<p>I described what I needed to Claude Code and it wrote the OpenSCAD. OpenSCAD is awesome for this kind of part because the whole model is just code with parameters, and it turns out that also makes it about the perfect CAD tool for an AI. It can’t drag things around with a mouse, but it can write and rewrite code all day.</p>

<p>The part that makes it actually work is that it can see what it made. It runs OpenSCAD headless to render PNGs from whatever angle it wants, looks at them, and fixes things before I ever see them. Each render takes under a second. When it needs to check how two parts fit, it cuts the model in half in a scratch file and renders the cross section. All I had to give it was a photo of the sensor next to a ruler, Sensirion’s design-in guide, and what I wanted. Claude came back with a list of caliper measurements to take and got to work.</p>

<h3 id="three-options-to-start">Three options to start</h3>

<p>A few minutes later it came back with three concepts, each with a render:</p>

<ul>
  <li><strong>A</strong> - one stick, with the sensor in a pod at the bottom, an open gap for room air, and the ESP in a chamber at the top.</li>
  <li><strong>B</strong> - two separate boxes joined only by the wires. The best thermal isolation, but two loose things to mount.</li>
  <li><strong>C</strong> - one compact box. The neatest looking, but it has the same problem many designs share where the MCU is too close to the sensor.</li>
</ul>

<div class="gallery">
<figure class="image">
  <a href="/images/diy-co2-monitor/render-concept-a-wall.png">
    <img src="/images/diy-co2-monitor/render-concept-a-wall.png" alt="Option A" style="max-width: 300px" />
    <figcaption>Option A</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/diy-co2-monitor/render-concept-b-wall.png">
    <img src="/images/diy-co2-monitor/render-concept-b-wall.png" alt="Option B" style="max-width: 300px" />
    <figcaption>Option B</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/diy-co2-monitor/render-concept-c-wall.png">
    <img src="/images/diy-co2-monitor/render-concept-c-wall.png" alt="Option C" style="max-width: 300px" />
    <figcaption>Option C</figcaption>
  </a>
</figure>

</div>

<p>I picked A. Then I wanted the USB cable to come out the bottom, and its first attempt at that decided the best way to do that would be to still have the D1’s USB facing the side, but make the case bigger and tell me to buy a right angled cable.</p>

<p>Instead, I pointed out to Claude that things can rotate, and it might get better results with the USB port facing down. Once it rotated the MCU, everything lined up better and Claude added a channel down the back for the cable to run through, with plenty of space for almost any USB cable. Its rendering of the cable is…interesting, but it works nicely.</p>

<figure class="image">
  <a href="/images/diy-co2-monitor/render-concept-a3-wall.png">
    <img src="/images/diy-co2-monitor/render-concept-a3-wall.png" alt="The vertical D1 version, with the cable running down the back" style="max-width: 300px" />
    <figcaption>The vertical D1 version, with the cable running down the back</figcaption>
  </a>
</figure>

<h3 id="printable-version">Printable version</h3>

<p>Under an hour after I first asked, it had a printable model: the body (printed on its back, so the flat back can take double sided tape), a lid for the sensor pod and a lid for the D1, both sliding down into 45 degree tongue and groove rails, and no supports needed. It also made small test slices of each critical fit so I could check them before printing the whole thing.</p>

<p>It listed the things it couldn’t tell from photos - whether the ESP-12’s antenna was flush with the end of the D1, whether the back of the D1 was clear where a stop pushed on it, whether the USB socket overhung the board edge, and whether anything stuck out of the back of the sensor board. I answered all four just by looking at the boards and it made any necessary adjustments.</p>

<figure class="image">
  <a href="/images/diy-co2-monitor/render-preview-assembly.png">
    <img src="/images/diy-co2-monitor/render-preview-assembly.png" alt="The OpenSCAD model of the body" style="max-width: 300px" />
    <figcaption>The OpenSCAD model of the body</figcaption>
  </a>
</figure>

<h3 id="where-i-had-to-catch-it">Where I had to catch it</h3>

<p>It’s not magic, and it got some things wrong.</p>

<p>The first one was easy to catch before printing. The lid for the sensor has ribs that push down on the top edge of the PCB, so the sensor is held in place. The lid slides on from the center into rails. Which is a great design, except for the solid wall the ribs have to pass through on the way. Claude was smart enough to check for interference in the middle where you put the lid to start sliding it on, and in its final resting place, but not the path in between.</p>

<p>When I pointed that out, it came up with a different and worse design by simply removing the material that got in the way. That left a wall held only by its bottom edge that broke off easily on the first print. I had to tell it to make that wall part of the lid itself. That also made the soldering easier, since the wires have to pass through holes in the case before soldering, and that moves one hole to the lid where it can be slid out of the way. Now that we’ve done that in one project, it’s saved instructions to check for that next time, so it just keeps improving as we encounter issues like that.</p>

<p>I also didn’t like the wires and plug just dangling in the open gap between the two halves, so it added a cover for that section that snaps in with little flex fins, a pattern from an earlier project.</p>

<p>The first full print was a test that everything fit and worked well. It found a few issues:</p>

<ul>
  <li>The previously mentioned sensor wall breaking off easily. To be fair to Claude, I missed the issue too before hitting print.</li>
  <li>The sensor board sat 0.7mm further out than the model, so it got recessed.</li>
  <li>The grilles printed messy, with stringing and blobs around the narrow strips between the slots. Wider bars fixed it, and the front slots on the D1 lid weren’t needed anyways.</li>
  <li>The wire holes became 5mm circles - less airflow between the chambers, and stronger walls.</li>
  <li>The cable groove got a rounded top to get rid of a stress point and a big flat overhang.</li>
</ul>

<p>Each round of changes took only a few minutes. The next print fit perfectly. The only quirk is that the D1 lid pops off pretty easily, but it faces up so it can’t slide off on its own, so I’m fine with that.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/diy-co2-monitor/open-d1-wiring.jpg">
    <img src="/images/diy-co2-monitor/open-d1-wiring.jpg" alt="The D1 mini standing USB down, with the wires running down to the sensor pod" style="max-width: 300px" />
    <figcaption>The D1 mini standing USB down, with the wires running down to the sensor pod</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/diy-co2-monitor/neck-open.jpg">
    <img src="/images/diy-co2-monitor/neck-open.jpg" alt="ESP lid on, neck cover off. Hot glue seals the wire hole into the pod." style="max-width: 300px" />
    <figcaption>ESP lid on, neck cover off. Hot glue seals the wire hole into the pod.</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/diy-co2-monitor/pod-closeup.jpg">
    <img src="/images/diy-co2-monitor/pod-closeup.jpg" alt="The sensor pod. The sensor can sits right behind the grille." style="max-width: 300px" />
    <figcaption>The sensor pod. The sensor can sits right behind the grille.</figcaption>
  </a>
</figure>

</div>

<p>From first request to a case that fits was less than a day, and most of that was happening in the background while I did other things. I didn’t write a line of OpenSCAD. My time went into deciding what I wanted and looking critically at what came off the printer, and none of it into fighting with CAD.</p>

<h3 id="my-own-mistake">My own mistake</h3>

<p>The plan was to stick the flat back to the wall with double sided tape or 3M Command strips. A day after the case was done, I realized that doesn’t work. Calibrating the sensor means taking it outside, and that isn’t a one time job.</p>

<p>I didn’t want to reprint the case, because it would require desoldering the wires and pulling out the hot glue. Instead, I had Claude design a bracket for it. Literally all it took to fix was a single prompt:</p>

<blockquote>
  <p>For the co2 sensor case, I just realized an oversight I made. It needs to go outside once in awhile to be calibrated. Which means mounting it with 2 sided tape or stickers isn’t great, and I still want it on the wall. It’s too late to change the case without having to desolder and rewire everything. Can you design a bracket I can attach to the wall with 2 sided tape that the case will snap into?</p>
</blockquote>

<p>I left Claude alone for a little bit, and it spit out a bracket that the existing case can clip into, making sure to avoid blocking any air vents and using the wider top to its advantage to support the weight there. It fit perfectly on the first try, and the clips have just the right pressure to easily pull out without falling out.</p>

<figure class="image">
  <a href="/images/diy-co2-monitor/bracket-beside-case.jpg">
    <img src="/images/diy-co2-monitor/bracket-beside-case.jpg" alt="The bracket next to the case. The clips at the top hold the case in, and the angled blocks below them carry its weight under the wide top." style="max-width: 300px" />
    <figcaption>The bracket next to the case. The clips at the top hold the case in, and the angled blocks below them carry its weight under the wide top.</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/diy-co2-monitor/back-groove.jpg">
    <img src="/images/diy-co2-monitor/back-groove.jpg" alt="The back of the case, with the open groove the cable runs in. The bracket covers it, so the cable stays put." style="max-width: 300px" />
    <figcaption>The back of the case, with the open groove the cable runs in. The bracket covers it, so the cable stays put.</figcaption>
  </a>
</figure>

<div class="gallery">
<figure class="image">
  <a href="/images/diy-co2-monitor/bracket-wall.jpg">
    <img src="/images/diy-co2-monitor/bracket-wall.jpg" alt="The bracket on the wall" style="max-width: 300px" />
    <figcaption>The bracket on the wall</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/diy-co2-monitor/bracket-seated.jpg">
    <img src="/images/diy-co2-monitor/bracket-seated.jpg" alt="The case clipped into it" style="max-width: 300px" />
    <figcaption>The case clipped into it</figcaption>
  </a>
</figure>

</div>

<p>If you want to build one, the OpenSCAD files for the <a href="/files/diy-co2-monitor/co2_sensor_case.scad">case</a> and the <a href="/files/diy-co2-monitor/co2_case_wall_bracket.scad">bracket</a> are free to use under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>. Put both in the same folder, since the bracket takes all its measurements from the case file. Measure your boards first, because clones vary, and print the test slices before the full case.</p>

<h2 id="firmware">Firmware</h2>

<p>The firmware is ESPHome. Here’s the sensor part of the config (Wi-Fi, API and OTA are the usual boilerplate):</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">esp8266</span><span class="pi">:</span>
  <span class="na">board</span><span class="pi">:</span> <span class="s">d1_mini</span>

<span class="na">i2c</span><span class="pi">:</span>
  <span class="na">sda</span><span class="pi">:</span> <span class="s">GPIO4</span>   <span class="c1"># D2</span>
  <span class="na">scl</span><span class="pi">:</span> <span class="s">GPIO5</span>   <span class="c1"># D1</span>
  <span class="na">frequency</span><span class="pi">:</span> <span class="s">100kHz</span>

<span class="na">sensor</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">platform</span><span class="pi">:</span> <span class="s">scd4x</span>
    <span class="na">id</span><span class="pi">:</span> <span class="s">scd41</span>
    <span class="na">measurement_mode</span><span class="pi">:</span> <span class="s">periodic</span>
    <span class="na">automatic_self_calibration</span><span class="pi">:</span> <span class="no">false</span>
    <span class="na">altitude_compensation</span><span class="pi">:</span> <span class="s">100m</span>     <span class="c1"># set to your own elevation</span>
    <span class="na">update_interval</span><span class="pi">:</span> <span class="s">60s</span>
    <span class="na">co2</span><span class="pi">:</span>
      <span class="na">name</span><span class="pi">:</span> <span class="s">CO2</span>
    <span class="na">temperature</span><span class="pi">:</span>
      <span class="na">name</span><span class="pi">:</span> <span class="s">Temperature</span>
    <span class="na">humidity</span><span class="pi">:</span>
      <span class="na">name</span><span class="pi">:</span> <span class="s">Humidity</span>

<span class="na">button</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">platform</span><span class="pi">:</span> <span class="s">template</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Calibrate CO2 to 427 ppm</span>
    <span class="na">entity_category</span><span class="pi">:</span> <span class="s">config</span>
    <span class="na">on_press</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">scd4x.perform_forced_calibration</span><span class="pi">:</span>
          <span class="na">value</span><span class="pi">:</span> <span class="m">427</span>
          <span class="na">id</span><span class="pi">:</span> <span class="s">scd41</span>
</code></pre></div></div>

<p>Automatic calibration is off, so the only thing correcting the baseline is the calibrate button. Altitude compensation matters because the sensor is measuring a concentration and air pressure changes with elevation.</p>

<h2 id="first-power-up">First power up</h2>

<p>The first flash over USB worked first time. An I2C scan found the sensor at <code class="language-plaintext highlighter-rouge">0x62</code>, which is the SCD4x address.</p>

<p>To check it was really an SCD41 and not an SCD40 sold as one (a common listing trick), I set the first build to <code class="language-plaintext highlighter-rouge">measurement_mode: single_shot</code>. That command only exists on the SCD41 - an SCD40 rejects it. It returned readings, so it’s the real thing. After that I switched it to <code class="language-plaintext highlighter-rouge">periodic</code> mode over OTA, which is how it runs normally, and the mode the datasheet says to calibrate in.</p>

<p>The first readings in the office were 725 ppm, 25.1C and 63.8% humidity.</p>

<p>Then, for fun, I held it up and breathed on it. The next reading jumped from about 700 to about 9000 ppm. That sounds alarming but it’s normal - exhaled breath is around 40,000 ppm. It’s an easy way to make sure it’s actually responding.</p>

<h2 id="calibrating-it">Calibrating it</h2>

<p>Out of the box, these sensors can be off by a fair bit, and soldering stresses the sensor and shifts the baseline. Since I’ve turned off the automatic calibration, that’s up to me now. It’s easy - grab a battery bank to power it, take it outside, let it settle in fresh air, and tell it what the outdoor CO2 level is. Outdoor background is about 425-430 ppm these days (it was 400 not that long ago, and it keeps going up), so I used 427.</p>

<p>It took about 10 minutes to clear the indoor air out of the sensor:</p>

<figure class="image">
  <a href="/images/diy-co2-monitor/calibration-settle.png">
    <img src="/images/diy-co2-monitor/calibration-settle.png" alt="Readings once a minute after taking it outside" style="max-width: 300px" />
    <figcaption>Readings once a minute after taking it outside</figcaption>
  </a>
</figure>

<p>The datasheet says 3 minutes is the minimum. In practice, wait until the readings stop falling. Mine settled at 413-419 ppm, so it was reading about 10 ppm low out of the box, assuming typical outdoor levels. That’s a pretty small, normal offset, and the best I’m going to get without a very expensive professionally calibrated reference to compare it to.</p>

<p>Then I pressed the calibrate button and nothing obvious happened, because I wasn’t watching the device log. There was no way to know if it actually worked. Pressed it again with the log open:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Setting forced calibration Co2 level 427 ppm
Forced calibration complete
</code></pre></div></div>

<p>The next readings were 439 and 432, settling toward 427. <strong>Watch the log when you press the button if you want to be sure it worked.</strong></p>

<p>Two things I wondered about that the datasheet answers:</p>

<ul>
  <li><strong>Does the calibration survive unplugging it?</strong> Yes. ESPHome has a <code class="language-plaintext highlighter-rouge">persist_settings</code> option, but that’s only for settings like the temperature offset and altitude. The calibration history is automatically stored in a separate EEPROM on the sensor.</li>
  <li><strong>When should you calibrate?</strong> No sooner than 5 days after the sensor is soldered in. The soldering stress shifts the baseline and it takes a while to settle. That catches most DIY builds, since everyone (including me) calibrates it the day they build it. So my first calibration is provisional, and I’ll redo it after the 5 days are up.</li>
</ul>

<h2 id="whats-left">What’s left</h2>

<p>The temperature offset is done. I left my most accurate thermometer about 15 cm from it overnight, in still air with the AC off and nobody in the room, and compared the two between 1 and 6 am. On ESPHome’s default 4C offset it read 1.1C warm, and very steadily (between 0.9 and 1.2C the whole time). So the offset went up to 5.1C, and after the update it read 24.64C against the thermometer’s 24.70C.</p>

<p>That leaves the second calibration, once the 5 days are up on October 6th. Sensirion’s sanity check for a finished build is temperature within 0.5C of a reference, CO2 noise under 20 ppm between readings, and a response to breath in under 60 seconds. It already passes the temperature and breath checks now, so the next check is just to make sure the soldering stress didn’t affect anything.</p>]]></content><author><name>Grant Emsley</name></author><category term="Hardware" /><summary type="html"><![CDATA[My office is in the basement, and the only outside air it gets comes through one tiny window. It doesn’t take long for it to feel stuffy in there, and I wanted to see if it’s getting bad enough to actually affect me. High CO2 doesn’t really hurt you at typical office levels, but it does make you tired and foggy, which isn’t great when you’re trying to think.]]></summary></entry><entry><title type="html">ChillSaver - A Fridge and Freezer Temperature Alarm</title><link href="https://www.emsley.ca/hardware/chillsaver" rel="alternate" type="text/html" title="ChillSaver - A Fridge and Freezer Temperature Alarm" /><published>2026-09-23T00:00:00-04:00</published><updated>2026-09-23T00:00:00-04:00</updated><id>https://www.emsley.ca/hardware/chillsaver</id><content type="html" xml:base="https://www.emsley.ca/hardware/chillsaver"><![CDATA[<p>I’ve got a fridge, the freezer on top of it, and a chest freezer beside them. That’s a lot of food, and sometimes even medications that need refrigeration. Power failures, a bad fan or compressor, or even just someone not closing the door tightly can ruin food or cause food poisoning.</p>

<p>Besides food safety, the data can also be used to help tune the temperature controls to the ideal range, and help with monitoring energy efficiency of the appliance.</p>

<p>There are plenty of options out there for monitoring a fridge or freezer temperature. But none had the exact feature set I wanted, at least not at a reasonable price. Especially if I have to buy 3 of them to monitor each zone. I already had all the parts on hand, so the ChillSaver was born.</p>

<figure class="image">
  <a href="/images/chillsaver/installed.jpg">
    <img src="/images/chillsaver/installed.jpg" alt="ChillSaver on the side of the fridge" style="max-width: 300px" />
    <figcaption>ChillSaver on the side of the fridge</figcaption>
  </a>
</figure>

<h2 id="features-i-wanted">Features I wanted</h2>

<ul>
  <li>Three probes: fridge, freezer, chest freezer, all on one device.</li>
  <li>A loud local alarm that doesn’t need the network or Home Assistant for anything.</li>
  <li>Fully local connection to Home Assistant, no reliance on cloud services.</li>
  <li>The alarm should tell me <em>which</em> unit has the problem without having to go look at a screen.</li>
  <li>A dead or unplugged probe must never look like a happy fridge.</li>
  <li>Limits adjustable from Home Assistant, but stored on the device so it can be tuned easily without having to do a firmware update every time.</li>
  <li>Probes that can be swapped without opening the case.</li>
</ul>

<h2 id="parts">Parts</h2>

<p>Almost all of this came out of my parts drawer.</p>

<ul>
  <li>ESP8266 NodeMCU (LoLin V3)</li>
  <li>3x waterproof DS18B20 probes</li>
  <li>4.7k pull-up for the 1-Wire bus</li>
  <li>A passive buzzer salvaged from an old motherboard’s speaker header (11 ohm coil)</li>
  <li>NPN transistor, 1k base resistor, 22 ohm series resistor, 1N4148 diode across the buzzer</li>
  <li>A panel mount push button for mute</li>
  <li>A BMP180 shield for room temperature, because I had one</li>
  <li>3 RJ45 keystone jacks, some Cat5, and a piece of stripboard</li>
  <li>A 3D printed case</li>
</ul>

<h2 id="why-wired-probes">Why wired probes?</h2>

<p>The obvious approach is battery powered sensors inside each unit. I didn’t want that for two reasons. Coin cells sag badly at freezer temperatures, and 2.4 GHz trying to get out of a metal box isn’t great either.</p>

<p>A thin cable through the door gasket on the hinge side shouldn’t leak any noticeable amount. That’s how most commercially available ones work. The DS18B20 probe cable is about 3.75mm though, which is thicker than I wanted squished in a seal, so each probe gets its own run of Cat5 from a keystone jack on the bottom of the case. The Cat5 is joined to the probe cable a few inches inside the unit (soldered, sleeved, hot glue under heat shrink), and the thin flat conductors are what cross the gasket. They get held flat and taped down with thin kapton tape. I put a flashlight in the fridge with the door closed to make sure there was no visible light coming out around the seal.</p>

<p>I’ve used Cat5 and keystones like this before and I like it a lot. Ethernet can carry lots of types of signals well, and handle a decent amount of power too. And I’ve always got plenty of ethernet cabling and parts available. A probe can be unplugged and swapped in seconds (not including the time to solder the cable itself up), and every run is wired the same so they’re all interchangeable:</p>

<ul>
  <li>Pin 4 (blue) is data, pin 5 (white/blue) is ground, so data is twisted with its return</li>
  <li>Pin 2 (orange) is 3.3V, pin 1 (white/orange) is ground</li>
  <li>The rest are unused</li>
</ul>

<p>The Cat5 I had on hand is solid core. If it cracks from movement in the cold, I’ll redo that run with stranded.</p>

<figure class="image">
  <a href="/images/chillsaver/probe-harness.png">
    <img src="/images/chillsaver/probe-harness.png" alt="One probe run, from keystone to probe" style="max-width: 300px" />
    <figcaption>One probe run, from keystone to probe</figcaption>
  </a>
</figure>

<div class="gallery">
<figure class="image">
  <a href="/images/chillsaver/fridge-gasket.jpg">
    <img src="/images/chillsaver/fridge-gasket.jpg" alt="Cat5 conductors taped flat across the fridge gasket" style="max-width: 300px" />
    <figcaption>Cat5 conductors taped flat across the fridge gasket</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/chillsaver/chest-freezer.jpg">
    <img src="/images/chillsaver/chest-freezer.jpg" alt="Chest freezer run, in at the lid hinge" style="max-width: 300px" />
    <figcaption>Chest freezer run, in at the lid hinge</figcaption>
  </a>
</figure>

</div>

<h2 id="the-alarm-lives-on-the-device">The alarm lives on the device</h2>

<p>The firmware is ESPHome. The three probes share one 1-Wire bus, and every 5 seconds the ESP itself checks each one:</p>

<ul>
  <li><strong>Too warm</strong> - a probe has been over its limit for longer than the alarm delay (30 minutes by default). The delay rides out door openings and other short lived temperature swings.</li>
  <li><strong>Probe fault</strong> - no valid reading from a probe for 3 minutes. The DS18B20 reports 85C when it powers up without finishing a conversion, and -127C when a read fails, so both of those get thrown out and count as no reading.</li>
</ul>

<p>The limits, alarm delay and mute duration show up in Home Assistant as number entities, so they’re easy to change, but they’re stored in the ESP’s flash. Home Assistant doesn’t evaluate anything.</p>

<p>The one trap here is that ESPHome, by default, reboots the device if it loses its connection to Home Assistant for 15 minutes. That sounds harmless until you realize a reboot resets the too-warm timer. If Home Assistant is down for a few hours, the device would reboot every 15 minutes and a 30 minute alarm would never fire. So both of those get turned off:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">api</span><span class="pi">:</span>
  <span class="na">reboot_timeout</span><span class="pi">:</span> <span class="s">0s</span>

<span class="na">wifi</span><span class="pi">:</span>
  <span class="na">reboot_timeout</span><span class="pi">:</span> <span class="s">0s</span>
</code></pre></div></div>

<h2 id="making-the-alarm-say-which-unit">Making the alarm say which unit</h2>

<p>Instead of having to add a display to it, every alarm starts with 1, 2 or 3 short beeps for the fridge, the freezer or the chest freezer. Then:</p>

<ul>
  <li><strong>Too warm</strong> - about 5 seconds of rapid pulsing, repeated back to back until someone deals with it.</li>
  <li><strong>Probe fault</strong> - just the beeps, then silence, once a minute. Like a smoke detector with a low battery.</li>
</ul>

<p>The button mutes it for 2 hours (adjustable), and it re-arms after that if the problem is still there. Holding the button for 2 seconds plays a test alarm.</p>

<p>Getting the sound right took more fiddling than I expected. The buzzer is a passive magnetic one pulled off an old motherboard, driven through a transistor from a PWM pin using ESPHome’s RTTTL player. I added a button in Home Assistant that plays a sweep of six notes, and it turned out the buzzer is only really loud at two of them - B6 and C7, around 2 kHz. Everything else was noticeably quieter.</p>

<p>Then there was what the alarm should sound like. Two tone and warbling patterns sounded musical, not like a problem. The classic smoke alarm triple beep was out too, because that’s what my UPSes sound like, and I’ve learned to ignore those. What I ended up with is C7 pulsed on and off about 7 times a second. It’s obnoxious, which is the point.</p>

<h2 id="building-it">Building it</h2>

<p>I prototyped it on a breadboard first, then soldered the real one onto stripboard with a second NodeMCU. That’s where most of the fun was.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/chillsaver/schematic.png">
    <img src="/images/chillsaver/schematic.png" alt="Schematic" style="max-width: 300px" />
    <figcaption>Schematic</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/chillsaver/stripboard.png">
    <img src="/images/chillsaver/stripboard.png" alt="Stripboard layout" style="max-width: 300px" />
    <figcaption>Stripboard layout</figcaption>
  </a>
</figure>

</div>

<p>The first power up looked great. Wi-Fi connected, Home Assistant found it, all the probes were reading. The buzzer was completely silent.</p>

<p>The buzzer’s 5V came from the NodeMCU’s VIN pin, simply because VIN was next to the free strips. It measured 1.2V. On this LoLin board VIN isn’t fed from the micro USB port - it’s only useful when you power the board from an external supply. The breadboard version used the VU pin, which <em>is</em> the USB 5V, and I’d moved it when laying out the stripboard. One cut and one wire to VU later, it was… still silent. Turned out there were two broken wires to the speaker. I fixed the first one and it was still silent. Fixed the second one and it finally made noise.</p>

<p>Then the mute button showed as permanently pressed. The switch, wiring and cuts all tested fine. The pin itself (D7) sat at 0V with nothing connected to it at all. I’m pretty sure it died during the buzzer troubleshooting, perhaps it got shorted to 5v. Rather than replace the NodeMCU, the button moved to the RX pin. That only works if serial logging is turned off, which is fine since the board is soldered down and I use OTA and the network logs anyways:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">logger</span><span class="pi">:</span>
  <span class="na">baud_rate</span><span class="pi">:</span> <span class="m">0</span>
</code></pre></div></div>

<p>Before installing everything, the probes were put in a dish of ice water to make sure they were all working and returning reasonable numbers. All 3 read within 0.2C of zero after less than a minute.</p>

<h2 id="the-case">The case</h2>

<p>The case was designed in OpenSCAD and printed as three flat pieces. The bottom panel has the micro USB opening, the mute button, the three keystones and some vent slots, so all the cords come out the bottom. The front is just a plate with the ChillSaver logo raised 1mm, printed in one go with a colour change partway up so the letters come out white. The third piece is the back, top and both sides all in one, with rails the stripboard and the front plate slide into, the buzzer glued into a ring behind sound holes in the right side, magnet pockets in the back, two screw tabs on top in case I ever want it on a wall, and bosses for M3 heat-set inserts.</p>

<p>To put it together, the board stands on the bottom panel, the front drops into its slot, the shell slides down over both, and four screws go up through the bottom into the inserts. Nothing pulls apart to open it, so the wires to the button and jacks don’t need any slack. Since the speaker is attached to the case, the wires from the board are soldered to a pin header so the case half can be unplugged from the board.</p>

<p>It took a few rounds to get there:</p>

<ul>
  <li>The first keystone test print used plain rectangular openings, and the jacks’ latches had nothing to catch on. I ended up borrowing the keystone socket block from spuder’s open source 10 inch rack OpenSCAD project, which clipped in perfectly on the next try. It made the case about 6mm deeper.</li>
  <li>Then test prints to make sure the USB opening was lined up right.</li>
  <li>It started as two halves, with the front and bottom as one piece, but the tall thin front wobbled on the printer’s moving bed. Splitting it into three flat prints fixed that.</li>
  <li>The front originally slid into a tongue and groove, and the thin lip beside the groove snapped off. Full rails, the same as the board rails, are much stronger.</li>
  <li>The first insert bosses were thin rings that softened and warped under the soldering iron. Solid blocks tied into the walls took the inserts perfectly.</li>
</ul>

<p>The magnets weren’t quite strong enough to hold it up with three Cat5 cables and a USB cord hanging off it, so it kept slowly sliding down. A couple of small, strong magnets stuck to the fridge just under its bottom edge fixed that. The BMP180 shield was a late addition that the case wasn’t designed for, so it just hangs loose inside. It reads about 3 degrees high from the NodeMCU’s own heat and the sensor itself being not great, so there’s a -3 offset on it. It’s only there for comparison, nothing alarms on it.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/chillsaver/inside.jpg">
    <img src="/images/chillsaver/inside.jpg" alt="Board and front panel before closing it up" style="max-width: 300px" />
    <figcaption>Board and front panel before closing it up</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/chillsaver/case-back.jpg">
    <img src="/images/chillsaver/case-back.jpg" alt="The shell (back, top and sides), with the buzzer and heat-set inserts" style="max-width: 300px" />
    <figcaption>The shell (back, top and sides), with the buzzer and heat-set inserts</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/chillsaver/keystones.jpg">
    <img src="/images/chillsaver/keystones.jpg" alt="Power, mute button and the three probe jacks along the bottom" style="max-width: 300px" />
    <figcaption>Power, mute button and the three probe jacks along the bottom</figcaption>
  </a>
</figure>

</div>

<h2 id="home-assistant-on-top">Home Assistant on top</h2>

<p>Home Assistant is the second layer. It sends a push notification to my phone when any of the Too Warm sensors turn on, repeating every 30 minutes while it’s still warm. A probe fault or the device going offline gets checked hourly. There’s no extra delay on the too warm notification - the device already waited 30 minutes, so when that sensor turns on it means it.</p>

<p>These are driven by polling instead of a loop with delays inside the automation. A running automation dies when Home Assistant restarts, and then the nagging just stops without anyone noticing.</p>

<h2 id="the-probe-was-in-the-wrong-place">The probe was in the wrong place</h2>

<p>Once everything was installed, the fridge read -1.9C. That’s below freezing in the fresh food side of the fridge. The history showed it swinging about 5 degrees every time the compressor cycled. The fridge was fine. The probe was just on the back wall, right where the cooling happens, where things sometimes freeze anyways. It was measuring the coldest spot in the fridge. I moved it so it dangles above the bottom shelf, in the middle of the compartment, and within minutes it read 4.9C.</p>

<p>This also settled something I’d been going back and forth on. The standard advice for this kind of monitoring is a buffered probe: the sensor sitting in a small bottle of glycol, so it responds more like the food does instead of the air. That’s a good idea, but my 30 minute alarm delay does the same job of ignoring short blips. If it was buffered, everything would be smoothed out so we don’t notice the swings - fine for food safety, but less useful for things like detecting if the door was left open in a timely manner, or any more detailed analysis of how efficiently the units are running. Easy to add later if it turns out to be useful.</p>

<h2 id="what-im-doing-with-the-data">What I’m doing with the data</h2>

<p>This wasn’t only about alarms. I’ve got data from my utility meter, and the house’s always-on baseline load has been creeping up in steps. It looks seasonal. The fridge and the chest freezer are obvious suspects, since they work harder when the house is warm, and neither was being measured. So along with ChillSaver, the fridge got a Zigbee smart plug that meters power. It’s locked in metering-only mode so nothing - an automation, a voice command, or someone poking the button - can ever turn the fridge off.</p>

<p>One night of data already turned up a few things:</p>

<ul>
  <li>The fridge (a top freezer model) draws about 105W with the compressor running. Left alone overnight it ran about 27% of the time, averaging about 29W. That’s right in line with its Energy Star rating.</li>
  <li>It caught a defrost cycle: about 430W for 12 minutes, followed by a 2.5 hour compressor run to recover.</li>
  <li>The compressor kicks in when the fridge probe hits about 4.8-4.9C, so the probe and the power line up nicely.</li>
  <li>The light in the fridge is a 40W incandescent bulb. Should probably swap that for an LED just for the heat savings.</li>
  <li>The chest freezer doesn’t have a plug on it yet, but the temperature alone tells a story. It was cycling like clockwork every 31-34 minutes: about 19 minutes cooling and 15 warming, so running about 55% of the time, at -24.6 to -19.4C. The dial was on MAX. It also doesn’t have the 8” of clearance the manual asks for, which doesn’t help.</li>
</ul>

<p>So the chest freezer dial went from MAX down to 4, and I’ll know if that’s too warm. On the fridge, the freezer slider isn’t really a freezer temperature control - it balances the cold air between the two compartments, and it has to be tuned together with the main temperature dial to get both sides right. I moved it to its coldest setting as a starting point. That’s always been guesswork before, and it’ll be a lot easier now that I can actually see what each compartment is doing.</p>

<h2 id="whats-next">What’s next</h2>

<p>What’s left is mostly fine tuning - after it’s gathered a week or so of data, I’ll have a better idea where to set the limits, and also be able to adjust all the controls to keep them in the right temperature ranges.</p>]]></content><author><name>Grant Emsley</name></author><category term="Hardware" /><summary type="html"><![CDATA[I’ve got a fridge, the freezer on top of it, and a chest freezer beside them. That’s a lot of food, and sometimes even medications that need refrigeration. Power failures, a bad fan or compressor, or even just someone not closing the door tightly can ruin food or cause food poisoning.]]></summary></entry><entry><title type="html">Tronxy X5SA Pro - Initial Setup</title><link href="https://www.emsley.ca/3d-printing/tronxy-initial" rel="alternate" type="text/html" title="Tronxy X5SA Pro - Initial Setup" /><published>2021-12-10T00:00:00-05:00</published><updated>2021-12-10T00:00:00-05:00</updated><id>https://www.emsley.ca/3d-printing/tronxy-initial</id><content type="html" xml:base="https://www.emsley.ca/3d-printing/tronxy-initial"><![CDATA[<p>I already have a Monoprice Maker Select 3D printer (a clone of the Wanhao I3) that I’ve been using for almost 5 years. It works well, and I’ve done a ton of upgrades and tuning to it. But my biggest complaints are that even with all the upgrades in the world, it’s still pretty slow if you want decent print quality, and the build area is too small for some of the things I want to build.</p>

<p>Enter the Tronxy X5SA Pro, which I got for about CAD$570 from Amazon. I read and watched plenty of reviews about it online, and most said the same thing - it’s an alright printer stock, far from the best option, but with some upgrades and modifications it can be a really good printer. It features a 330x330mm build plate, with 400mm height limit, and is a CoreXY motion design which if properly tuned should be able to go faster than the old I3 design.</p>

<h2 id="building">Building</h2>

<p>The build process took about 5 hours, but I was taking my time doing it. The manual has quite a few errors in it, places where they list the wrong parts to use, wrong size screws, or just don’t explain the step very well. There’s a few videos online I skimmed through when I was confused, but I managed to muddle my way through it.</p>

<p>A few things that weren’t well explained:</p>

<ul>
  <li>Some of the belts do go with the teeth facing into the smooth pulleys. Seems like that would wear out the belts faster or damage the teeth, but it seems to work fine so far. Perhaps replacing them with toothed pulleys in the future would be a good idea. I think I have some in my printer parts bin.</li>
  <li>The Y axis endstop plate mounts to the front right, on the inside of the upright 40x20 extrusion. The pictures were very confusing.</li>
  <li>The extruder stepper wiring on mine was VERY short. It wouldn’t reach if things were mounted where they were shown in the manual. But moving the wiring box a little closer made it just reach.</li>
  <li>They give you at <em>lot</em> of extra screws. As in it seems like there’s enough left over to build an entire second machine. Not that I’m complaining, I’m really happy to have extras. It just threw me that there were so many left over.</li>
</ul>

<div class="gallery">
<figure class="image">
  <a href="/images/tronxy/unpack1.jpg">
    <img src="/images/tronxy/unpack1.jpg" alt="It's here!" style="max-width: 300px" />
    <figcaption>It's here!</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/tronxy/unpack2.jpg">
    <img src="/images/tronxy/unpack2.jpg" alt="Everything well packaged" style="max-width: 300px" />
    <figcaption>Everything well packaged</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/tronxy/unpack3.jpg">
    <img src="/images/tronxy/unpack3.jpg" alt="Lots of parts to assemble" style="max-width: 300px" />
    <figcaption>Lots of parts to assemble</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/tronxy/controller1.jpg">
    <img src="/images/tronxy/controller1.jpg" alt="Control box" style="max-width: 300px" />
    <figcaption>Control box</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/tronxy/assembled1.jpg">
    <img src="/images/tronxy/assembled1.jpg" alt="Assembly is complete for now" style="max-width: 300px" />
    <figcaption>Assembly is complete for now</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/tronxy/assembled2.jpg">
    <img src="/images/tronxy/assembled2.jpg" alt="Front view" style="max-width: 300px" />
    <figcaption>Front view</figcaption>
  </a>
</figure>

</div>

<h2 id="stock-system-information">Stock system information</h2>

<p>Some specs of the machine, mostly so I remember them.</p>

<p>The motherboard is a CXY-V6-191017 with TMC2225 drivers. There is actually room on the board for a 5th driver, but none of the components are soldered in.</p>

<p>The system runs as 24v. Great for reducing current requirements for the heaters, but means I’ll need 24v fans if I replace them.</p>

<p>According to <a href="https://angryadmin.sesc.dev/posts/tronxy-marlin/#replace-pl-08n-inductive-promixity-sensor-with-bl-touch">this guide</a>, I should be able to backup all the settings using some special gcode commands, but it doesn’t seem to work for me. Nothing gets saved to the SD card. You can however download a gcode file full of settings from TronXY’s website, and decide them with <a href="http://www.customize-3d.com/chitu-g-code-explained.html">this guide to Chitu G code</a>. Here’s what I decoded:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Resume on power lose enabled
Z stepper direction reversed, rest are normal
Speed set to 100mm/s
Z max speed 20mm/s
Extruder max speed 120mm/s
Jerk set to 20
Acceleration 100mm/s^2
X and Y steps per millimeter 0.0127
Z steps per mm 0.00125
Extruder 0.0013085


&gt;&gt;&gt; M503
SENDING:M503
echo:  G21    ; Units in mm (mm)
echo:; Filament settings: Disabled
echo:  M200 S0 D1.75
echo:; Steps per unit:
echo: M92 X160.00 Y160.00 Z800.00 E824.00
echo:; Maximum feedrates (units/s):
echo:  M203 X150.00 Y150.00 Z5.00 E25.00
echo:; Maximum Acceleration (units/s2):
echo:  M201 X1200.00 Y1200.00 Z100.00 E10000.00
echo:; Acceleration (units/s2): P&lt;print_accel&gt; R&lt;retract_accel&gt; T&lt;travel_accel&gt;
echo:  M204 P1200.00 R3000.00 T1200.00
echo:; Advanced: B&lt;min_segment_time_us&gt; S&lt;min_feedrate&gt; T&lt;min_travel_feedrate&gt; X&lt;max_x_jerk&gt; Y&lt;max_y_jerk&gt; Z&lt;max_z_jerk&gt; E&lt;max_e_jerk&gt;
echo:  M205 B20000.00 S0.00 T0.00 X10.00 Y10.00 Z0.30 E5.00
echo:; Home offset:
echo:  M206 X0.00 Y0.00 Z0.00
echo:; Auto Bed Leveling:
echo:  M420 S0 Z0.00
echo:; PID settings:
echo:  M301 P22.20 I1.08 D114.00
; Controller Fan
echo:  M710 S255 I0 A1 D60 ; (100% 0%)
echo:; Power-Loss Recovery:
echo:  M413 S1
echo:; Z-Probe Offset (mm):
echo:  M851 X-38.50 Y-10.00 Z-5.01
echo:; Filament load/unload lengths:
echo:  M603 L0.00 U100.00
echo:; Filament runout sensor:
echo:  M412 S1
</code></pre></div></div>

<h2 id="initial-thoughts">Initial thoughts</h2>

<p>Pros:</p>
<ul>
  <li>The build plate is huge compared to my old printer!</li>
  <li>The glass build plate it comes with looks pretty cool, it’s textured to improve grip. Hopefully won’t have to use gluestick with it.</li>
  <li>The induction sensor actually works ok with the included glass plate. I’m not convinced it works as well as a BL touch though, so I’m probably still replacing it. But it works far better than I thought it would!</li>
  <li>The Pro version of the X5SA has sort of linear rails instead of V wheels. They are square metal bars with a slot cut into them and smooth rods press fit in. Hopefully that gives it a smoother ride and can move faster. Probably not as good as high quality linear rails, but still a big upgrade from the non pro version.</li>
</ul>

<p>Neutral:</p>
<ul>
  <li>I’m ok with it being a bowden setup. Hopefully that means without the weight of the extruder motor on the print carriage I can get this thing flying. And I have my direct drive printer for things where it won’t work well.</li>
  <li>The nuts you use to attach things to aluminum extrusion (not sure what they are called, I’ve seen hammerhead nuts, boat nuts and T nuts used) are magic - when they work. But sometimes they won’t turn and it’s hard to tell if they are fully engaged.</li>
</ul>

<p>Cons:</p>
<ul>
  <li>The firmware that comes with the controller is terrible. Just really, really terrible. The way the menus are laid out makes it really hard to see what’s going on with the printer or adjust things. There are very few things you can adjust from it anyways - a lot of the settings you’d need to tune the printer just aren’t there.</li>
  <li>Tightening the belts is a pain.</li>
  <li>Having the extruder and filament at the center of the back is <em>really</em> a pain. I don’t want to have to pull the machine out to get at the filament.</li>
  <li>It’s not as solid as I’d like. You can flex the entire frame by pressing opposite corners. But we can print some parts to stiffen that up.</li>
  <li>It’s very easy for the two Z steppers to get out of sync and the bed to tilt. People have made their own mods to tie them together with a belt, and Tronxy even <a href="https://www.tronxyonline.com/Tronxy-Z-axis-timing-belt-adjuster-with-Z-axis-synchronous-wheel-belt-Only-For-X5SA-Series-X5SA-400-Series-X5SA-500-Series-3D-Printer-p1413964.html">sells their own kit to do it</a></li>
</ul>

<h2 id="hardware-modifications">Hardware Modifications</h2>

<h3 id="corner-braces">Corner Braces</h3>

<p>The first modifications I started printing on the old printer - braces for the corners to stiffen the frame.  There’s two different braces I used.</p>

<p>The first is <a href="https://www.myminifactory.com/object/3d-print-tronxy-x5s-corner-brackets-reinforcement-frame-fix-69740">Tronxy X5S corner brackets</a>, which go in most of the corners. On the corner where the Y endstop is mounted I cut out a little piece with a chisel so it would fit. I put them in all 4 corners in the front, and 2 in each side at the bottom.</p>

<p>Those don’t work for the sides at the top, because the pro version has rails there instead of aluminum extrusion. For that I used <a href="https://www.thingiverse.com/thing:4601135">Tronxy X5SA Pro Top Corner Bracket</a>. This mounts in the extrusion at the sides, and an extra hole in the rails. I assume those holes are there because some models have the smooth rods for the Z axis spread out more and they just manufactured one kind of rail for everything? In any case, they fit perfectly. I used some M3 bolts and hammerhead nuts to attach them. I really have to get a supply of M4 and M5 bolts now since that’s what fits most of the things on this printer.</p>

<figure class="image">
  <a href="/images/tronxy/corner1.jpg">
    <img src="/images/tronxy/corner1.jpg" alt="Corner brackets" style="max-width: 300px" />
    <figcaption>Corner brackets</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/tronxy/corner2.jpg">
    <img src="/images/tronxy/corner2.jpg" alt="Brackets on rails" style="max-width: 300px" />
    <figcaption>Brackets on rails</figcaption>
  </a>
</figure>

<h3 id="toothbrush-nozzle-cleaner">Toothbrush Nozzle Cleaner</h3>

<p>Filament tends to leak out of extruders while they heat up, and this one leaks a lot. I don’t want to have to manually remove it before the print starts. Thankfully the X5SA can move a bit outside of it’s print area, probably so that the probe can reach the edge of the bed. raabi91 on thingiverse designed this <a href="https://www.thingiverse.com/thing:4087860">brush holder for nozzle cleaning</a> which screws to some of the extra holes on the rails of the printbed and lets you attach a brush there for nozzle wiping. I had to put a couple washers under it to raise it ot the right height, and I didn’t have the exact wire brush they used, so I cut the handle off a toothbrush and shoved that in there. Probably not going to last as long as a metal wire brush, but it does the job for now.</p>

<p>To make use of it, I use this start gcode:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>G90 ; use absolute coordinates
M83 ; extruder relative mode
M104 S{first_layer_temperature[0] - 50} ; set extruder temp for auto bed leveling
M140 S[first_layer_bed_temperature] ; set bed temp
M190 S[first_layer_bed_temperature] ; wait bed temp
G28 ; home all

; nozzle cleaning
G0 Z10 ; make sure we're well above print bed
G0 X340
G0 Y80 ; move past the end of the brush to heat up
M109 S[first_layer_temperature] ; wait for extruder temp
G0 Z2 ; raise printbed to reach brush
G1 E10 F1500 ; extrude 10mm filament
G92 E0 ; reset filament position
G0 Y30 ; run extruder over brush
G0 Y70
G0 Y30
G0 Y70
G0 Z15 ; lower printbed
G0 X165 Y165 ; return to center before starting
</code></pre></div></div>

<figure class="image">
  <a href="/images/tronxy/toothbrush.jpg">
    <img src="/images/tronxy/toothbrush.jpg" alt="Toothbrush nozzle cleaner" style="max-width: 300px" />
    <figcaption>Toothbrush nozzle cleaner</figcaption>
  </a>
</figure>

<h2 id="future-modifications">Future Modifications</h2>

<p>I’ve already bought some parts to upgrade it…probably too many parts. Some upgrades I intend to do are:</p>

<ul>
  <li>Replace the firmware with Klipper. I’ve always used Marlin and Octoprint in the past, but I hear lots of great things about Klipper, especially when it comes to printing faster. So I’m going to give that a try.</li>
  <li>Replace the entire motherboard with a <a href="https://www.biqu.equipment/products/bigtreetech-skr-pro-v1-1-32-bit-control-board">BigTreeTech SKR Pro 1.2 board</a>. It probably won’t be any faster than the current board, but the main reason for upgrading to that specific board is it’s support for 6 stepper motors. That will let me run the two Z steppers independently so it can level itself. Bought it on Amazon for $65, along with 6 TMC2209 stepper drivers for $46.</li>
  <li>Upgrade to a touch probe. The induction sensor works pretty well, but I still don’t feel like it’s as accurate as a touch sensor. Figured I’d try one of the clone 3D touch sensors this time since it was only $28 vs the $65 for an official one. If it works well great, if it works but not well enough, I might swap it for the official one in the other printer.</li>
  <li>Dual extrusion! I love making multicolor parts, but switching filaments is a pain. I opted for a $43 <a href="https://www.amazon.ca/gp/product/B08LH9R82F">2 in 1 out hotend</a> that I hope will fit with minimal modifications. Of course with that I’ll need another extruder, and the cheapest one I could find was this $19 <a href="https://www.amazon.ca/gp/product/B09C7YSH13/">titan extruder clone</a>. At least it will match the other extruder that’s already on the printer. I already have a spare stepper motor to run it with.</li>
</ul>

<p>I’ll do writeups of some of those modifications later.</p>]]></content><author><name>Grant Emsley</name></author><category term="3D Printing" /><summary type="html"><![CDATA[I already have a Monoprice Maker Select 3D printer (a clone of the Wanhao I3) that I’ve been using for almost 5 years. It works well, and I’ve done a ton of upgrades and tuning to it. But my biggest complaints are that even with all the upgrades in the world, it’s still pretty slow if you want decent print quality, and the build area is too small for some of the things I want to build.]]></summary></entry><entry><title type="html">DIY Numberpad Mechanical Keyboard</title><link href="https://www.emsley.ca/hardware/numberpad" rel="alternate" type="text/html" title="DIY Numberpad Mechanical Keyboard" /><published>2021-11-17T00:00:00-05:00</published><updated>2021-11-17T00:00:00-05:00</updated><id>https://www.emsley.ca/hardware/numberpad</id><content type="html" xml:base="https://www.emsley.ca/hardware/numberpad"><![CDATA[<p>I recently bought a <a href="https://gaming.kinesis-ergo.com/edge/">Kinesis Gaming split keyboard</a>. It’s not a cheap keyboard, and probably more than I really need, but I was getting really sick of my old keyboard. The Microsoft Natural Ergonomic 4000 has been my only keyboard for at least the last decade. I really love the layout of it - the split design has saved me from wrist problems, and after a bit of practice it was easy to type on. I’ve been through about 5 of them. There are two downsides to it though. First, you can’t buy them anymore, at least not at any reasonable price. Second, the mushy membrane keys are fustrating. Mine had a few keys that had to be pressed really hard in order for them to register, and it was getting fustrating not having my keystrokes register.</p>

<p>Anyways, the new keyboard is great. Takes some getting used to, but it’s working well for me. I’m starting to get used to having the halves of the keyboard spread apart more so my arms are more comforatble. But what it really lacks is a numberpad. Most of the time I don’t need it, but when I do it’s really annoying to not have it. It also doesn’t have any easily accessible media keys - they are there, but you have to hit Fn, and I don’t have time for that!</p>

<p>So I built myself a mechanical numberpad with a few extra keys. I could have just bought one, but where’s the fun in that?</p>

<h2 id="finished-product">Finished Product</h2>

<figure class="image">
  <a href="/images/numpad/complete.jpg">
    <img src="/images/numpad/complete.jpg" alt="Mechanical Numberpad" style="max-width: 300px" />
    <figcaption>Mechanical Numberpad</figcaption>
  </a>
</figure>

<h2 id="features-i-wanted">Features I wanted</h2>

<ul>
  <li>3D printable</li>
  <li>Some way to adjust the height and tilt easily</li>
  <li>Multimedia keys and a volume knob</li>
  <li>Make sure it’s easy to replace the microcontroller without rewiring everything, for when I break the connector off</li>
</ul>

<h2 id="step-1-gather-the-parts">Step 1: Gather the parts</h2>

<p>Most of these came from aliexpress and amazon. Some I had lying around.</p>

<ul>
  <li>Cherry MX or compatible keyswitches. At least 23 of them.</li>
  <li>Rotary encoder</li>
  <li>Keycaps</li>
  <li>1N4148 diodes</li>
  <li>Pro Micro microcontroller</li>
  <li>Right angled pin headers</li>
</ul>

<p>The keycaps I got from a set of HyperX Pudding keycaps that I replaced some of the keys on the actual keyboard with. I had all the ones for the numberpad left over.</p>

<h2 id="step-2-design-the-keyboard-layout">Step 2: Design the keyboard layout</h2>

<p>http://www.keyboard-layout-editor.com/ is pretty awesome. Makes it super easy to design a layout, and other tools will import it’s data easily.</p>

<p>The keyboard layout I ended up with is:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[{x:1.5},"Encoder\nF13"],
[{y:-0.5},"F14",{x:2},"F15"],
["Play/\n\n\n\n\n\nPause","Mute","Prev","Next"],
[{y:1.5},"Num Lock","/","*","-"],
["7\nHome","8\n↑","9\nPgUp",{h:2},"+"],
["4\n←","5","6\n→"],
["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"],
[{w:2},"0\nIns",".\nDel"]
</code></pre></div></div>

<p>Wasn’t sure the exact use for each button at this point, but the F13, F14 and F15 buttons can be used as hotkeys in some programs, including AutoHotKey to automate just about anything I want. My earliest version didn’t include the F14 and F15 buttons, but there was room for them on the keypad and in the keyboard matrix without adding much extra wiring, so may as well add them.</p>

<h2 id="step-3-get-a-plate-designed">Step 3: Get a plate designed</h2>

<p>I intend to design the overall case in Fusion 360, but manually layout out each button would be a lot of extra work. https://kbplate.ai03.com/ takes your keyboard layout and creates a DXF file. That can be used for laser cutting or milling, or in my case imported as a sketch in fusion to use as a starting point.</p>

<h2 id="step-4-design-a-case">Step 4: Design a case</h2>

<p>I imported my DXF file and started designing the top plate. Replaced the switch cutout at the top with one appropriate for a rotary encoder. Opted not to use stabalizers simply because I couldn’t find anywhere reasonably priced to buy them. I extruded the plate 1.5mm which is a good depth to clip the switches in place. Then I made a second sketch with a 1.75mm offset around each switch and extruded what was left by another 4.5mm. This leaves clearance around the switches, but makes the top plate a lot more sturdy so the whole thing flexes less.</p>

<p>The rest I mostly muddled my way through designing. The top plate sits inside a body that has room for the wiring and microcontroller. Probably more room than I need, but I don’t need this to be super thin. It will get screwed in place with 4 M3 bolts into heat pressed inserts in the body. The body has a mounting area for the microcontroller, designed to let me slide the controller in from the top side with the pin headers already attached, then a cover will screw in there holding the microcontroller in place and covering everything except the USB port. The cover will give me the option of moving to a pro micro with a USB C connector later on, and also makes it easy to get the connector lined up perfectly since it only takes a 10 minute print to make a new cover instead of a 7 hour print for a new frame.</p>

<p>There are holes inside posts at each corner that run all the way through the frame for the screws for the top plate. Having the holes go all the way through lets me not have to worry as much about screw length, and will also let me put a second set of threaded inserts in the bottom. These will be used to screw in legs that let me adjust the height and tilt of the keyboard without having to reprint the entire frame.</p>

<p>The main thing I keep in mind when trying to design parts like this is how I am going to print it. If you know what orientation you are going to print each part, it’s easier to ensure you don’t have any unnecessary overhangs or other difficult to print features. In some places they are unavoidable, but I try to make them on less critical dimensions. For example the hole where the cover for the microcontroller goes will require supports. The holes that it screws into however won’t - even if it doesn’t print a perfect hole with the overhangs there, I’m heat pressing an insert into it anyways so I don’t have to worry about the holes being perfect.</p>

<p>The design took a few iterations to figure out exactly what I wanted and whether or not everything would work. The first print was just the top plate to make sure the spacing and fit was good and there was sufficient clearance
around the rotary encoder for the knobs I had. After testing that one I decided to add the additional 2 buttons to the side of the encoder.</p>

<p>The second test print was the frame, but with just a cutout of where the microcontroller would screw in so I could test fit it and make sure the supports that were needed there wouldn’t be hard to remove. This too took a few iterations to find a way to hold the board securely in place without interfering with any components or pin headers. It’s still not quite as secure as I’d like, but it should be good enough that it won’t get pushed out of place while plugging it in.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/numpad/prototypeplate.jpg">
    <img src="/images/numpad/prototypeplate.jpg" alt="First prototype plate" style="max-width: 300px" />
    <figcaption>First prototype plate</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/finalplatefront.jpg">
    <img src="/images/numpad/finalplatefront.jpg" alt="Finished plate - front" style="max-width: 300px" />
    <figcaption>Finished plate - front</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/finalplateback.jpg">
    <img src="/images/numpad/finalplateback.jpg" alt="Finished plate - back" style="max-width: 300px" />
    <figcaption>Finished plate - back</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/microholder.jpg">
    <img src="/images/numpad/microholder.jpg" alt="Microcontroller frame top view" style="max-width: 300px" />
    <figcaption>Microcontroller frame top view</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/microholder2.jpg">
    <img src="/images/numpad/microholder2.jpg" alt="Microcontroller back view" style="max-width: 300px" />
    <figcaption>Microcontroller back view</figcaption>
  </a>
</figure>

</div>

<h2 id="step-5-plan-the-wiring">Step 5: Plan the wiring</h2>

<p>This I find easiest to do on paper. Draw out the layout of the keyboard <em>upside down</em>, so you’re looking at the bottom of the top plate. That makes it far easier to follow when you come to actually soldering it up.</p>

<p>Then figure out the rows and columns, and which switches will connect where. I ended doing a few possible layouts before settling on what would be the easiest to physically wire up. Initially I thought I would use a 5x5 or 6x4 matrix, since both of those give enough spots for the buttons I have, but the layout would have been hard with rows jumping up and down all over the place because of the wider buttons. I ended up with a 7x4 matrix that’s pretty much a perfect grid, so easy to wire up. There are plenty of pins available on the microcontroller for that.</p>

<p>While I’m doing this, I’m also planning which pins I’ll use on the microcontroller to make it easiest to wire. The 3 pins of the encoder were going to go to the TX,RX and ground pins, simply because I needed a ground, and the other two put them all next to each other for an easy 3 pin connector. After test fitting I realized the top pin won’t be accessible, so I moved that down to use the ground, 2 and 3 pins. The columns will use the bottom 4 pins on the left side, and the rows will use the bottom 7 pins on the right side.</p>

<figure class="image">
  <a href="/images/numpad/wiringdiagram.jpg">
    <img src="/images/numpad/wiringdiagram.jpg" alt="Hand drawn wiring diagram" style="max-width: 300px" />
    <figcaption>Hand drawn wiring diagram</figcaption>
  </a>
</figure>

<h2 id="step-6-firmware">Step 6: Firmware</h2>

<p>I could jump right into the wiring now, but since I’ve never wired a keyboard with diodes before, I wanted to be able to triple check that I had everything wired correctly. So first I need to get the microcontroller working and firmware installed, then I can test a few buttons on a breadboard and make sure everything is working the way I expect it to.</p>

<p>The firmware I’m using is <a href="https://qmk.fm/">QMK</a>, simply because it seemed to have an active community and good documentation, and definitely supported the rotary encoder. There’s an online tool for configuring it, but since I like to know exactly how things work on the inside, I went the route of compiling and configuring it from the source code. Their documentation does a great job of walking you through getting the build environment setup.</p>

<p>Download QMK MSYS and install it. Follow along with the prompts.</p>

<p>Then create a custom keyboard with ‘‘qmk new-keyboard’’ and enter a name for your keyboard. I went with grantemsley/numpad. That creates a folder for all your keyboard’s configuration. Find the new keyboard folder and edit some files.</p>

<p>kbfirmware.com is a useful site for taking the output of the keyboard layout generated at the other site and generating the matrix to use and mapping pins and everything, but I opted to go without it so I can learn how the firmware works.</p>

<p>The most important parts are defining what pins are used for the matrix in config.h, and the LAYOUT macro in numpad.h - this layout file defines both how the keys are physically laid out, and their position in the matrix. Then edit the keymap file to assign keys to each button.  I setup the encoder as volume up and down, and clicking it to be F13. I use <a href="https://github.com/sirWest/AudioSwitch">AudioSwitch</a> to switch between my headset and speakers when I press F13, so clicking the volume knob changes devices. The other extra keys I assigned as media keys and F14 and F15, which can be used as hotkeys in other programs or AutoHotKey scripts.</p>

<p>Once the firmware was flashed, I tested it by using a wire to connect between each row and column one at a time. While doing this I found none of the keys in the bottom row worked. I had desoldered and resoldered pins on this microcontroller a few times, and the pad that pin connected to probably got lifted up at some point. Repairing that would mean removing that entire section of pin headers, and risk pulling up even more pads, so instead I soldered a jumper wire from that to another unused pin and changed the pin mapping in config.h.</p>

<p>I uploaded the customized firmware <a href="https://github.com/grantemsley/qmk_firmware">to a github repository</a> so I don’t lose it.</p>

<p>There’s still more work to do with the firmware, but I did enough to get it functional for now. One of the most important features is a way to put the controller into programming mode without having to disassemble the case again. Normally you have to short RST to ground, but that pin won’t be accessible without opening it up again. Luckily QMK has that built in, a feature called bootmagic lite. In config.h I defined the row and column of the key I want to use - in this case, the numlock key. Holding numlock while connecting the USB will put it into programming mode for a few seconds so you can flash new firmware without opening it.</p>

<h2 id="step-7-wiring">Step 7: Wiring</h2>

<p>Once the final faceplate was printed, it was time to start assembling and wiring. I installed all the switches with the LED opening on the bottom after reading this:  https://keyboardable.com/north-facing-switches-vs-south-facing-switches/. Since I won’t be using LEDs in it, it made no difference to me, and apparently some keycap profiles work better with them in that orientation.</p>

<p>I inserted all the keyswitches and encoder and made sure they all felt like they were working properly. If the opening for the keyswitch is too tight, particularly if you get the thickness of the plate wrong, it can cause the switches to bind up sometimes. Luckily I had figured that out in the earlier test runs where I had made the plate 2mm thick. The 1.5mm thick holes worked perfectly.</p>

<p>First was soldering the rows. These are made up entirely of diodes and their legs. First bend a tight loop into the leg of the diode away from the black stripe, then put that over the leg and tighten it. Solder that in place. Repeat for each diode in the row. Then starting at one end bend the remaining leg with the black stripe towards the next diode, wrap the leg around the leg of the next one, and solder there. Repeat down to the end of the row, then trim all the legs except for the last one on each row - that’s where you’ll solder the wires for the rows to. I then attached wires to each of the rows and crimped dupont headers to the other end so they can be plugged into the controller.</p>

<p>For the columns, I stripped about 5cm from the end of a wire, then measured how much insulation I’d need between pins. Use the wire strippers to cut the insulation there and push it down the wire leaving a bit of a gap of exposed wire. Then repeat for the next switch. Once I had exposed wire in all the right places, I soldered it down to each switch. It really helps here to tin the wire and the key’s pins before trying to solder them.  It took a few tries to get the wires stripped in the right spots, but you can be off by a fair bit without risking any shorts to the row wires. The columns also got crimped to Dupont headers to plug in to the microcontroller.</p>

<p>At the last moment I realized I might want to use multiple modes (or layers, as QMK calls them) with this keyboard, and for that I’d want some sort of indication of what mode it’s in. I added another 3 pin header to the RAW, GND and TX pins of the microcontroller and connected a strip of 4 WS2812 LEDs. Because the pins aren’t all together, and those pins are blocked by the case, I didn’t use pin headers in the microcontroller and just soldered the wires to it.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/numpad/wiring1.jpg">
    <img src="/images/numpad/wiring1.jpg" alt="Diodes wired in" style="max-width: 300px" />
    <figcaption>Diodes wired in</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/wiring2.jpg">
    <img src="/images/numpad/wiring2.jpg" alt="Diodes closeup" style="max-width: 300px" />
    <figcaption>Diodes closeup</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/wiring6.jpg">
    <img src="/images/numpad/wiring6.jpg" alt="Wires soldered to rows" style="max-width: 300px" />
    <figcaption>Wires soldered to rows</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/wiring5.jpg">
    <img src="/images/numpad/wiring5.jpg" alt="Wires and cable header added" style="max-width: 300px" />
    <figcaption>Wires and cable header added</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/wiring7.jpg">
    <img src="/images/numpad/wiring7.jpg" alt="Columns soldered" style="max-width: 300px" />
    <figcaption>Columns soldered</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/wiring9.jpg">
    <img src="/images/numpad/wiring9.jpg" alt="Columns closeup" style="max-width: 300px" />
    <figcaption>Columns closeup</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/.jpg">
    <img src="/images/numpad/.jpg" alt="" style="max-width: 300px" />
    <figcaption></figcaption>
  </a>
</figure>

</div>

<h2 id="step-8-final-assembly">Step 8: Final Assembly</h2>

<p>I installed all the threaded inserts and cleaned up the supports around the opening at the back. The microcontroller is held in very securely when the cover is installed, but can be easily removed to swap it out in the future. I’m not happy with how the cover fits, but I’m not unhappy enough to change and reprint it, so it stays.</p>

<p>After getting the LEDs to work it looked pretty good. But you know what would look better than 4 LEDs? 20 LEDs! So I opened it up again and added 3 strips of LEDs chained together. The first 6 LEDs run down the center starting at the top, the next 7 are on the left starting at the bottom, then 7 on the right starting at the top. Since that’ll draw a lot of power through the poor little microcontroller, I also set the RGBLIGHT_LIMIT_VAL to 180 instead of 255, to reduce the maximum brightness. Testing with a current meter this made it draw about 420ma with all white lights, and 160ma with all green.</p>

<p>Strangely when I tried it at max brightness, it would draw almost 700ma, and the voltage on the USB port (before the microcontroller) would start dropping to 4.6v. When it did this, it would stay at max brightness for a few seconds, then dim all the LEDs until it was only drawing about 300ma. I kind of expected the controller to just crash, but that doesn’t seem to be the case. Not sure if there is some power limiting code hiding somewhere, or that’s just how it deals with under voltage, but I thought it was odd.  No issues with the 180 max brightness, so that’s what I’ll stick to. I’m probably never going to set it to pure white full brightness anyways, so it’ll use less power than that.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/numpad/leds1.jpg">
    <img src="/images/numpad/leds1.jpg" alt="Add wires for LEDs" style="max-width: 300px" />
    <figcaption>Add wires for LEDs</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/leds2.jpg">
    <img src="/images/numpad/leds2.jpg" alt="LED strip added" style="max-width: 300px" />
    <figcaption>LED strip added</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/leds3.jpg">
    <img src="/images/numpad/leds3.jpg" alt="Single strip of LEDs works" style="max-width: 300px" />
    <figcaption>Single strip of LEDs works</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/numpad/leds4.jpg">
    <img src="/images/numpad/leds4.jpg" alt="4 LEDs only light up some of the keys" style="max-width: 300px" />
    <figcaption>4 LEDs only light up some of the keys</figcaption>
  </a>
</figure>

</div>

<h2 id="next-steps">Next Steps</h2>

<p>There’s still more to do with the firmware. Here are some ideas:</p>

<ul>
  <li>Figure out how layers work, and use one of the extra keys to switch between layers. Or possibly use the numlock key. Those layers can have other sets of key assignments.</li>
  <li>Use multiple keys at once to set different settings - possibly for switching modes, or for changing the lighting colors.</li>
</ul>

<p>For now it’s working well enough as intended. I can type numbers at lightning speed again.</p>]]></content><author><name>Grant Emsley</name></author><category term="Hardware" /><summary type="html"><![CDATA[I recently bought a Kinesis Gaming split keyboard. It’s not a cheap keyboard, and probably more than I really need, but I was getting really sick of my old keyboard. The Microsoft Natural Ergonomic 4000 has been my only keyboard for at least the last decade. I really love the layout of it - the split design has saved me from wrist problems, and after a bit of practice it was easy to type on. I’ve been through about 5 of them. There are two downsides to it though. First, you can’t buy them anymore, at least not at any reasonable price. Second, the mushy membrane keys are fustrating. Mine had a few keys that had to be pressed really hard in order for them to register, and it was getting fustrating not having my keystrokes register.]]></summary></entry><entry><title type="html">Laser engraved sign</title><link href="https://www.emsley.ca/laser/signforjasper" rel="alternate" type="text/html" title="Laser engraved sign" /><published>2021-11-15T00:00:00-05:00</published><updated>2021-11-15T00:00:00-05:00</updated><id>https://www.emsley.ca/laser/signforjasper</id><content type="html" xml:base="https://www.emsley.ca/laser/signforjasper"><![CDATA[<p>Someone commissioned a photo sign of a pet. Mostly documenting this so I remember what settings I used!</p>

<h2 id="materials">Materials</h2>

<ul>
  <li>Piece of plywood, approx 12” x 8” x 0.5”</li>
  <li>Piece of 0.5” thick solid wood for the frame</li>
  <li>Wood stain for frame</li>
  <li>Spray finish - I used a glossy acrylic sealer</li>
  <li>Polyurethane finish for the frame</li>
  <li>A few nails</li>
  <li>Picture hanging hook</li>
</ul>

<h2 id="prep-work">Prep Work</h2>

<p>First step was to get a good photo to use, remove the background, and convert it to greyscale. Then adjust the levels and exposure until there is a really good contrast between the light and dark parts. The picture I had was fairly low resolution which wasn’t ideal, but it worked.</p>

<p>Once you have the photo, bring it into Lightburn and size it fairly small to do some test runs. I tried a variety of settings, and recorded the results. All of these were done with the bottom of the toolholder about 13mm above the work surface, and the laser mounted one set of screwholes up, and the laser focused into as tight a beam as I could get it. All were done with the Jarvis dithering option</p>

<table>
  <thead>
    <tr>
      <th>Speed</th>
      <th>Power</th>
      <th>Line Interval</th>
      <th>Adjustments</th>
      <th>Results</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2000</td>
      <td>85</td>
      <td>0.1mm</td>
      <td>None</td>
      <td>Completely burnt, no detail at all</td>
    </tr>
    <tr>
      <td>3000</td>
      <td>85</td>
      <td>0.1mm</td>
      <td>None</td>
      <td>Better, but looked very pixelated and not well focused</td>
    </tr>
    <tr>
      <td>3000</td>
      <td>85</td>
      <td>0.2mm</td>
      <td>0.75 gamma</td>
      <td>A lot better. Still very pixelated looking</td>
    </tr>
    <tr>
      <td>4000</td>
      <td>100</td>
      <td>0.15mm</td>
      <td>0.75 gamma</td>
      <td>Worse overall, but better in some ways. Probably shouldn’t change 3 variables at once.</td>
    </tr>
    <tr>
      <td>3000</td>
      <td>100</td>
      <td>0.2mm</td>
      <td>0.75 gamma</td>
      <td>Very good, but the dithering is very noticable.</td>
    </tr>
    <tr>
      <td>4000</td>
      <td>100</td>
      <td>0.2mm</td>
      <td>0.75 gamma</td>
      <td>Slightly too light in the darker regions</td>
    </tr>
    <tr>
      <td>4000</td>
      <td>100</td>
      <td>0.175mm</td>
      <td>0.75 gamma</td>
      <td>Worse. Too many spots where the dots overlap</td>
    </tr>
    <tr>
      <td>4000</td>
      <td>100</td>
      <td>0.2mm</td>
      <td>None</td>
      <td>Best so far. At this point I increased the picture size to get a better idea what the full size version will look like.</td>
    </tr>
    <tr>
      <td>4000</td>
      <td>100</td>
      <td>0.2mm</td>
      <td>None</td>
      <td>Looks pretty good. Wood grain is really distracting but hopefully will be better in the full size version.</td>
    </tr>
  </tbody>
</table>

<h2 id="final-burning">Final Burning</h2>

<p>Burning the image and text took about 45 minutes. The name didn’t come out as dark as I would have liked, so I redid it a few times with slower speeds until it looked better. This is only possible if you haven’t moved the machine or the wood after the job finished, otherwise you’ll never get it lined up perfectly again.  If I were doing it again, I’d pick a different font. The font I used was AGSFONT, which is a line based font ideal for plotters and lasers. It looked really good in the smaller sizes, but once blown up to full size the lines didn’t merge together anymore which I don’t really like.</p>

<figure class="image">
  <a href="/images/dogsign/sign1.jpg">
    <img src="/images/dogsign/sign1.jpg" alt="Finished sign" style="max-width: 300px" />
    <figcaption>Finished sign</figcaption>
  </a>
</figure>

<h2 id="frame">Frame</h2>

<p>The frame was made of a 1” strip of 1/2” thick pine. I cut the top and bottom pieces the same size was the sign, and the sides  about an inch longer than the sides of the sign so they’d cover the top and bottom pieces. I intentionally left them a bit long just because I like the way that looks.</p>

<p>I sanded the pieces until they fit tightly around the sign, then they were stained with Minwax Red Oak stain and polyurethane. I used a prestain conditioner to help make the stain more even because pine doesn’t like to stain very evenly.</p>

<p>The sign itself I finished with glossy acrylic sealer, which changed the color of the wood in a way I really like. The nice thing about that spray is it dries really fast. The downside is it smells horrible.</p>

<p>To get the sign to be centered in the frame from front to back I sat it on a piece of 1/4” thick plywood while attaching the frame. The frame is just nailed in with 2 nails on each piece.</p>

<figure class="image">
  <a href="/images/dogsign/sign2.jpg">
    <img src="/images/dogsign/sign2.jpg" alt="Sign with frame" style="max-width: 300px" />
    <figcaption>Sign with frame</figcaption>
  </a>
</figure>

<p>Once that was done I attached the hook on the back with 2 small screws, predrilling to make sure I didn’t mess up the wood.</p>

<h2 id="notes-for-next-time">Notes for next time</h2>

<ul>
  <li>Wish I had done a bit better job sanding and finishing the frame. But that’s always the way, isn’t it?</li>
  <li>Smaller nails, or dark colored ones, would have been nice - they wouldn’t stand out as much.</li>
  <li>Choose a better font and test it full size.</li>
  <li>Do this in nicer weather so I can use the spray finishes outside.</li>
</ul>]]></content><author><name>Grant Emsley</name></author><category term="Laser" /><summary type="html"><![CDATA[Someone commissioned a photo sign of a pet. Mostly documenting this so I remember what settings I used!]]></summary></entry><entry><title type="html">Engraving Images with Lightburn</title><link href="https://www.emsley.ca/laser/lightburn-images" rel="alternate" type="text/html" title="Engraving Images with Lightburn" /><published>2019-07-07T00:00:00-04:00</published><updated>2019-07-07T00:00:00-04:00</updated><id>https://www.emsley.ca/laser/lightburn-images</id><content type="html" xml:base="https://www.emsley.ca/laser/lightburn-images"><![CDATA[<p><a href="https://lightburnsoftware.com/">Lightburn</a> is a program for controlling laser cutters and engravers.<br />
The license for GCode based machines is US$40, and it’s worth every penny.</p>

<p>It does have a few quirks though, which I’ve mostly sorted out.</p>

<h2 id="lightburn-setup">Lightburn Setup</h2>

<p>I’ll go over most of the settings that are important:</p>

<ul>
  <li>Settings:
** Units - mm/min</li>
  <li>Device Settings:
** Width - 558.0mm
** Height - 343.0mm
** Origin: Bottom left
** Enable Z axis on
** Enable laser fire button on
** S-value max - 1000
** Baud Rate - 115200</li>
</ul>

<h2 id="macros">Macros</h2>

<p>There are two <strong>very</strong> important macros for using lightburn on my machine. Lightburn doesn’t like negative coordinates - it works much better if everything starts at the bottom left and goes to positive coordinates from there.
So to accomodate that, we’ll use macros to set the coordinate offsets.  One macro turns that on, one turns it off for when we are going back to other programs that expect the machine origin to be in the top right.
This macro also enables laser mode, where GRBL will adjust the laser depending on speed, and turn it off when doing quick moves.</p>

<h3 id="set-lightburn-coord-system-macro">Set Lightburn Coord System Macro</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$32 = 1
G54
G10 L2 P1 X-568 Y-350
</code></pre></div></div>

<h3 id="reset-coordinate-system">Reset Coordinate System</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>G54
G10 L2 P1 X0 Y0 Z0
</code></pre></div></div>

<p>Note:  This macro does NOT turn off laser mode. I make sure that any milling gcode I run explicitly turns it off.</p>

<h3 id="zero-z-axis">Zero Z Axis</h3>

<p>I always set lightburn to engrave at Z=0. To make it work well, I use the move tab, fire the laser at 1% power, and jog up and down until it’s roughly focused.  Then I use the knob of the lens to focus it perfectly.
After it’s focused, I click the Zero Z axis macro.  If I forget this set, it will return to whatever height the machine started at and probably ruin my workpiece.  So don’t forget!</p>

<p>The software already has a Set Origin button for setting up X and Y properly.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>G92 Z0
</code></pre></div></div>

<h2 id="running-a-job">Running a Job</h2>

<p>I’m not going to cover setting up your artwork to engrave - lightburn has tutorial videos that cover it nicely.  But I will go over my process for running the job.</p>

<ul>
  <li>Put on laser glasses.</li>
  <li>Turn the machine on with the laser hooked up.</li>
  <li>Make sure the PWM mode switch is set to laser.</li>
  <li>Fix the workpiece to the bed.</li>
  <li>Run com2com as documented in another page here to connect to the serial port of the raspberry pi over ethernet.</li>
  <li>Double check that the job is setup properly - things are in the right layers, speeds are set properly, etc.</li>
  <li>Jog the laser over to the workpiece. Then raise or lower the Z axis to focus it. Click the Zero Z axis macro.</li>
  <li>On the laser tab, pick a job origin. I usually pick center but it depends on what’s easiest to align properly on the piece you are engraving.</li>
  <li>Jog the machine to the orign selected. Click Set Origin.</li>
  <li>Hold Ctrl while clicking Frame to make sure it will engrave where you want - holding control makes it turn on the laser at lower power to see the outline.</li>
  <li>Click start</li>
</ul>

<h2 id="engraving-settings">Engraving Settings</h2>

<p>Different woods will need different settings, but I’ll record here what settings I use.</p>

<table>
  <thead>
    <tr>
      <th>Type of Wood</th>
      <th>Speed (mm/min)</th>
      <th>Max Power</th>
      <th>Mode</th>
      <th>Passes</th>
      <th>Other Info</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Light woods like maple</td>
      <td>1200</td>
      <td>60%</td>
      <td>Cut</td>
      <td>1</td>
      <td>For engraving line art. Works best if you slightly UNfocus the laser to make slightly wider lines.</td>
    </tr>
    <tr>
      <td>Walnut</td>
      <td>1000</td>
      <td>95%</td>
      <td>Cut</td>
      <td>1</td>
      <td>Line art. Gives a nice groove you can feel with your fingernail.</td>
    </tr>
  </tbody>
</table>]]></content><author><name>Grant Emsley</name></author><category term="Laser" /><summary type="html"><![CDATA[Lightburn is a program for controlling laser cutters and engravers. The license for GCode based machines is US$40, and it’s worth every penny.]]></summary></entry><entry><title type="html">Using Fusion 360 with MPCNC</title><link href="https://www.emsley.ca/cnc/fusion360manufacturing" rel="alternate" type="text/html" title="Using Fusion 360 with MPCNC" /><published>2019-03-26T00:00:00-04:00</published><updated>2019-03-26T00:00:00-04:00</updated><id>https://www.emsley.ca/cnc/fusion360manufacturing</id><content type="html" xml:base="https://www.emsley.ca/cnc/fusion360manufacturing"><![CDATA[<p>Now that I have a way to connect directly to the machine from the PC, I have a lot more options for software.  Lightburn is doing everything I need with the laser, but for milling I need something else.</p>

<p>The best something else I’ve found so far is Fusion 360 + Universal GCODE Sender, though it does take awhile to learn everything.</p>

<h2 id="custom-postprocessor">Custom Postprocessor</h2>

<p>I created a custom postprocessor to generate my gcode.  It has a few advantages over the stock GRBL one:</p>

<ul>
  <li>It doesn’t try to do tool changes, since the machine doesn’t support them</li>
  <li>The stock postprocessor moves it’s X and Y into position, then moves Z up.  It assumes Z is already at a safe height.  But that’s not always the case on my machine, and if I forgot to raise it, it would drag the endmill through the work at full speed.  Mine raises it 15mm above the stock surface first.  If you have clamps or anything that are higher than that, edit the postprocessor on line 221 to change the height.</li>
  <li>At the end, stock moves the machine to home, potentially cutting through the workpiece.  Mine just raises the spindle and turns off.</li>
  <li>Stock left the spindle running, mine turns it off when done.</li>
  <li>My postprocessor starts by raising Z, turning the spindle on, then <strong>holding the machine</strong>.  This lets me verify the tool is actually turned on and plugged in, and lets me get into position to watch it before proceeding.  I can then start the job by pressing resume on the control panel I made for the machine.</li>
</ul>

<p>So far it’s been working very well for me.</p>

<p>Just download <a href="/files/cnc/mpcnc.cps">mpcnc.cps</a> and copy it to C:\Users\username\AppData\Roaming\Autodesk\Fusion 360 CAM\Posts</p>

<h2 id="milling-settings-with-fusion-360">Milling Settings with Fusion 360</h2>

<p>I’m not going to give a complete tutorial here - some things are self explainatory, for everything else there’s a million tutorials already.  I’m just going to cover some of the settings that work well on my specific machine.</p>

<h3 id="creating-round-holes">Creating round holes</h3>

<p>I had a tough time getting perfect 8mm diameter 4mm deep holes for inserting magnets into.  I want them ever so slightly more than 8mm so that there is a nice press fit with the magnets.</p>

<p>The settings I finally settled on, using an 1/8” 2 flute endmill were:</p>

<ul>
  <li>2D Circular</li>
  <li>Feed rate 100mm/min (this might be to slow, sometimes get a bit of burning)</li>
  <li>Lead rate 600/min</li>
  <li>Ramp/Plunge rage 1000/min</li>
  <li>Retract height 1mm from stock top (this saves time over it going a full centimeter above on every pass)</li>
  <li>Repeat passes (spring pass, helps make sure it removed any material deflection made it not remove on the first pass)</li>
  <li>Conventional milling</li>
  <li>Multiple depths - 2mm per pass</li>
  <li>Stock to leave 0</li>
  <li>Lead to centre ON (this ensures it removes the center of the hole too)</li>
</ul>

<p>Works well in red oak.</p>

<h3 id="creating-large-slots">Creating large slots</h3>

<p>For my dice vault I wanted slots that are about 12mm deep, about 125mm long and 25mm wide.</p>

<p>The best way I’ve found to do that and get clean good looking side walls that don’t require much sanding is to do two operations.  The first is 2D adaptive clearing, the second is 2D contour</p>

<p>For the adaptive clearing:</p>
<ul>
  <li>Cutting, leadout, ramp and plunge feedrates:  600-850 (850 is pushing it, there’s noticable bending and tilting when it’s cutting)</li>
  <li>lead in feedrate: about 100mm/min lower than the rest</li>
  <li>Optimal load: 1.27mm</li>
  <li>Both ways: Enabled</li>
  <li>Optimal load other way: 1.27mm</li>
  <li>Other way feedrate: 100mm/min lower than cutting</li>
  <li>Use slot clearing: Disabled</li>
  <li>Direction: Conventional</li>
  <li>Multiple depths: Enabled, 6mm</li>
  <li>Stock to leave: 0.6mm radial, 0 axial</li>
  <li>Entry position:  close to one corner of the slot</li>
</ul>

<p>For the contour:</p>
<ul>
  <li>Cutting feedrate 600mm/min, rest 500mm/min</li>
  <li>Sideways compensation: conventional</li>
  <li>Finish feedrate: 600mm/min</li>
  <li>Repeat finishing pass enabled</li>
</ul>]]></content><author><name>Grant Emsley</name></author><category term="CNC" /><summary type="html"><![CDATA[Now that I have a way to connect directly to the machine from the PC, I have a lot more options for software. Lightburn is doing everything I need with the laser, but for milling I need something else.]]></summary></entry><entry><title type="html">Connecting to RPI-CNC board over serial</title><link href="https://www.emsley.ca/cnc/rpicnc-serial" rel="alternate" type="text/html" title="Connecting to RPI-CNC board over serial" /><published>2018-12-20T00:00:00-05:00</published><updated>2018-12-20T00:00:00-05:00</updated><id>https://www.emsley.ca/cnc/rpicnc-serial</id><content type="html" xml:base="https://www.emsley.ca/cnc/rpicnc-serial"><![CDATA[<p>The Raspberry PI CNC board I use is great - but one limitation is that the software has to run on the PI.  For some programs, this works fine, and I can use a web interface in Laserweb or other software.  Or just send gcode to run.</p>

<p>But there are some programs that only run on Windows, and work better if they are directly connected to the machine’s COM/USB port rather than exporting gcode.  In particular, I’m trying out <a href="https://lightburnsoftware.com/">LightBurn</a>, which so far
works so much better than Laserweb.  For the $40 the author asks for it, it’s a steal!</p>

<p>So here’s how you can do a serial port over the network, to connect Lightburn “directly” to the machine without having to rip out the RPI CNC controller for something else.</p>

<h3 id="pi-side">PI Side</h3>

<p>We will use ser2net to make it so we can telnet to the PI, and be connected to the serial port the GRBL controller uses.</p>

<p>Install ser2net with <code class="language-plaintext highlighter-rouge">apt-get install ser2net</code></p>

<p>Then edit <code class="language-plaintext highlighter-rouge">/etc/ser2net.conf</code> and add this line to the bottom:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>7000:telnet:0:/dev/ttyAMA0:115200 8DATABITS NONE 1STOPBIT
</code></pre></div></div>

<p>Then <code class="language-plaintext highlighter-rouge">service ser2net restart</code></p>

<p>From now on, you’ll be able to telnet to port 7000 on the PI, and be connected to the COM port. This can stay running even along side Laserweb or other programs - as long as they only open the serial port on demand, and you only use one at a time, they won’t interfere with each other.</p>

<h3 id="windows-side">Windows Side</h3>

<p>Now we have to make a telnet connection look like a serial port.  Thankfully, someone already wrote software to do that!</p>

<p>Download and extract <a href="https://github.com/Raggles/com0com/releases">com2com</a>, open a command prompt as administrator, and run <code class="language-plaintext highlighter-rouge">setupc.exe</code> from the folder you extracted it to. In it’s command line, type:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>install 0 PortName=COM7 -
quit
</code></pre></div></div>

<p>This creates a virtual serial port COM7 on your computer.  That step only has to be done once.</p>

<p>From now on, when you want to connect that virtual serial port to the PI, you need to run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>com2tcp.exe --telnet --baud 115200 \\.\CNCB0 ip.address.of.pi 7000
</code></pre></div></div>

<p>Leave that window open while using the machine.  Now your program can connect to COM7 of your windows PC, and the commands will go over the network, through the PI, and to the GRBL controller. As far as the software is concerned, it’s connected directly to the controller.</p>]]></content><author><name>Grant Emsley</name></author><category term="CNC" /><summary type="html"><![CDATA[The Raspberry PI CNC board I use is great - but one limitation is that the software has to run on the PI. For some programs, this works fine, and I can use a web interface in Laserweb or other software. Or just send gcode to run.]]></summary></entry><entry><title type="html">D&amp;amp;D TV Table</title><link href="https://www.emsley.ca/woodworking/dndtvtable" rel="alternate" type="text/html" title="D&amp;amp;D TV Table" /><published>2018-11-09T00:00:00-05:00</published><updated>2018-11-09T00:00:00-05:00</updated><id>https://www.emsley.ca/woodworking/dndtvtable</id><content type="html" xml:base="https://www.emsley.ca/woodworking/dndtvtable"><![CDATA[<figure class="image">
  <a href="/images/dndtvtable/finish1.jpg">
    <img src="/images/dndtvtable/finish1.jpg" alt="My D&amp;D TV Table" style="max-width: 300px" />
    <figcaption>My D&amp;D TV Table</figcaption>
  </a>
</figure>

<p>I play Dungeons and Dragons, and we use a map on the table for our minis.  But printing maps gets expensive. So why not go digital?  Instead, we can use a TV built into a table and display the maps on there.</p>

<p>Originally I thought of using a projector.  I’ve seen a few people build rigs using projectors.  But the projectors I had access too need to be fairly far away from the surface they’re projecting on - higher than my ceiling if aimed down.  I don’t think my wife would approve me cutting holes in the ceiling and the floor above to mount a projector!  But I did have a nice 32” 1080p TV that wasn’t being used too much, so that’s what I went with.</p>

<h3 id="planning">Planning</h3>

<p>The first step was figuring out exactly what I want out of the table.  I had a few ideas:</p>

<ul>
  <li>I wanted it to be relatively cheap - 2x4s and plywood, not fine lumber.</li>
  <li>Fit a 32” TV - since that’s what I had on hand for the project</li>
  <li>Be quite sturdy. I don’t want the table rocking or tipping</li>
  <li>Have a bit of room around the TV for people to sit their stuff, but not too much - our laptops can go on side tables.</li>
</ul>

<p>The next step was mocking up the design in Fusion 360.  I suck at making animations in Fusion 360, but the actual plans worked out pretty good.  Starting with a 3D diagram lets me get all the measurements I need, and make certain everything is going to fit before I start buying any wood or cutting anything.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/0zeGgSZVw1I" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen=""></iframe>

<p>A couple things changed from that first mock up, but it worked out pretty good.</p>

<h3 id="materials-tools-and-cost">Materials, Tools and Cost</h3>

<p>The materials used were:</p>

<ul>
  <li>5x 2x4s</li>
  <li>4x 2x6s</li>
  <li>Less than half a sheet of 1/2” baltic birch plywood</li>
  <li>Wipe on poly</li>
  <li>3” wood screws</li>
  <li>1 1/2” wood screws</li>
  <li>3/8” wood screws</li>
  <li>M6 threaded rod</li>
  <li>M6 hex nuts</li>
  <li>Fender washers</li>
  <li>Metal angle things for screwing down the table top (I forget what these are called, they come in a pack of 100)</li>
  <li>Plexiglass sheet (eventually replaced for glass)</li>
  <li>Glass sheet</li>
  <li>A TV</li>
</ul>

<p>Tools used:</p>

<ul>
  <li>Circular saw (only because my table saw isn’t very easy to work with for large sheets of plywood)</li>
  <li>Table saw</li>
  <li>Mitre saw</li>
  <li>Screw drivers</li>
  <li>Drill</li>
  <li>Impact driver (optional)</li>
  <li>Hack saw</li>
  <li>Tape measure</li>
  <li>Glass cutter</li>
</ul>

<p>Most of the tools I already had or could borrow. The glass cutter I got on Amazon for under $20.</p>

<p>Excluding the TV and the new blade I needed for my saw, the materials cost a little under $200.</p>

<h3 id="tv-selection">TV Selection</h3>

<p>There is one very critical thing to look for when selecting a TV:  Viewing angle.</p>

<p>Size and resolution matter too, but viewing angle is the most important. Some cheaper TVs have a terrible viewing angle, and viewing them from too high or low, or too far to the sides will make the colors wrong and warp the image.  For this use case, with the TV lying flat and people on all sides of it, everyone is going to be in the absolute worst case viewing angle.</p>

<p>The TV I had is a Viewsonic VT3200 - a commercial display with a 170 degree horizontal, 160 degree vertical viewing angle.  And it looks fantastic, no matter where you sit at the table.</p>

<h3 id="build-pictures">Build Pictures</h3>

<h4 id="top-frame">Top Frame</h4>

<p>The frame uses 2x4s surrounding the TV, and 2x6 for the sides of the table. This makes sure there’s plenty of room for the TV mount that will be added later.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/dndtvtable/frame1.jpg">
    <img src="/images/dndtvtable/frame1.jpg" alt="Frame for the tabletop. Built upside down." style="max-width: 300px" />
    <figcaption>Frame for the tabletop. Built upside down.</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/frame2.jpg">
    <img src="/images/dndtvtable/frame2.jpg" alt="Double checking the TV fits." style="max-width: 300px" />
    <figcaption>Double checking the TV fits.</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/frame3.jpg">
    <img src="/images/dndtvtable/frame3.jpg" alt="The top side." style="max-width: 300px" />
    <figcaption>The top side.</figcaption>
  </a>
</figure>

</div>

<h4 id="legs">Legs</h4>

<p>The legs are simply a 2x4 and a 2x6 screwed together. These legs are rock solid. The first time I screwed them the wrong way around, with the 2x4  screwed to the wide part of the 2x6. That made them not fit properly and I had to do it all over again.  You can make the legs whatever height you want. The finished table top will be about 1 inch higher than the length of the legs.</p>

<p>I put the base upside down on the floor, put a piece of scrap plywood under the leg and clamp it into position, then used 3” screws to secure it in place. I didn’t bother with pilot holes since it’s soft wood and my impact driver has plenty of power.</p>

<p>The reason for putting the plywood under the legs is to make them a bit lower than the frame, so the table top won’t rest on them. The idea being that it’ll be easier to get a nice smooth top if it’s only touching the sides of frame, not the ends of the legs.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/dndtvtable/legs1.jpg">
    <img src="/images/dndtvtable/legs1.jpg" alt="Legs assembled" style="max-width: 300px" />
    <figcaption>Legs assembled</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/legs2.jpg">
    <img src="/images/dndtvtable/legs2.jpg" alt="Testing that they fit" style="max-width: 300px" />
    <figcaption>Testing that they fit</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/legs3.jpg">
    <img src="/images/dndtvtable/legs3.jpg" alt="Clamp the leg into position." style="max-width: 300px" />
    <figcaption>Clamp the leg into position.</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/legs4.jpg">
    <img src="/images/dndtvtable/legs4.jpg" alt="Screw them in" style="max-width: 300px" />
    <figcaption>Screw them in</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/legs5.jpg">
    <img src="/images/dndtvtable/legs5.jpg" alt="Table is starting to look like a table. Banana for scale." style="max-width: 300px" />
    <figcaption>Table is starting to look like a table. Banana for scale.</figcaption>
  </a>
</figure>

</div>

<h4 id="mounting-the-tv">Mounting the TV</h4>

<p>I went through a few ideas on how to mount the TV.  I knew I wanted to use the VESA mounting holes - that would ensure I could easily replace it if this one ever dies.  I also wanted to be able to raise and lower the TV easily so I could align it perfectly with the tabletop, even if I ended up with a different TV that was a different thickness.  To accomodate that, I used some threaded rod and nuts to allow fine control over the position of the TV.</p>

<p>First I printed out a template for the VESA mounting pattern, and drilled holes into a small piece of plywood that becomes the mount for the TV.  Then I cut some threaded rod that would go into the mounting holes in the TV.</p>

<p>That plywood gets screwed into a 2x4 that goes along the bottom of the base. This was the reason for using 2x6s on the outside - it let me screw this center 2x4 into the 2x4s that surround the TV, and also screw the ends into the sides of the table, so it’s nice and stable. I attached the TV to the plywood, lined everything up nicely, then clamped down the plywood and removed the TV.  Then screwed it in place.  It’s nice and sturdy.</p>

<p>The threaded rod allows for lots of adjustment - the whole thing goes:</p>

<ul>
  <li>TV</li>
  <li>Nut</li>
  <li>Fender washer</li>
  <li>Plywood base</li>
  <li>Fender washer</li>
  <li>Nut</li>
</ul>

<p>That lets me easily adjust how far each rod sticks above the base to get the TV right up to the table top, and to adjust each of the 4 posts to level it properly.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/dndtvtable/mount1.jpg">
    <img src="/images/dndtvtable/mount1.jpg" alt="Print out of VESA mounting pattern" style="max-width: 300px" />
    <figcaption>Print out of VESA mounting pattern</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/mount2.jpg">
    <img src="/images/dndtvtable/mount2.jpg" alt="VESA holes cut in plywood" style="max-width: 300px" />
    <figcaption>VESA holes cut in plywood</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/mount3.jpg">
    <img src="/images/dndtvtable/mount3.jpg" alt="Checking how long the rods need to be" style="max-width: 300px" />
    <figcaption>Checking how long the rods need to be</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/mount4.jpg">
    <img src="/images/dndtvtable/mount4.jpg" alt="Position the TV" style="max-width: 300px" />
    <figcaption>Position the TV</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/mount5.jpg">
    <img src="/images/dndtvtable/mount5.jpg" alt="Clamp the mount in place" style="max-width: 300px" />
    <figcaption>Clamp the mount in place</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/mount6.jpg">
    <img src="/images/dndtvtable/mount6.jpg" alt="Screw the mount down" style="max-width: 300px" />
    <figcaption>Screw the mount down</figcaption>
  </a>
</figure>

</div>

<h4 id="table-top">Table Top</h4>

<p>If I were doing this again, I’d probably try to make the top out of a single piece of material. But I simply didn’t have the tools to make that happen, and the results I got are still pretty nice.</p>

<p>The top was cut out of 4 strips of the plywood on my circular saw, since my little table saw can’t safely handle large sheets with one person operating it.  I measured and cut them to fit nicely around the TV, with just a little gap around each edge so that if someone spills a drink on the table, it’s more likely to roll down the edge than to continue into the TV itself.</p>

<p>I also used my CNC machine to engrave some dragons and a D20 symbol into the pieces.  The tape in one of the photos was just there to help me line them up in the machine exactly where I wanted the engraving.  Those turned out beautifully.</p>

<p>The hardest part of this was getting all 4 pieces level and square with no gaps between them.  I probably should have cut them a bit big with the circular saw and used the table saw for more accurate final cuts. I used dowels to help keep them lined up, but those didn’t work all that well.</p>

<p>I used a bunch of those angled metal pieces and tiny screws to secure each piece, while trying to make sure each lined up with the others.  Unfortunately, this meant using a hand screw driver since there isn’t enough room for my drill.  And since my floor is carpeted and I didn’t have a large flat sheet to lay it on, the table had to be upright for me to be able to line everything up properly.  Several hours were spent lying on the floor to drive screws above my head into the table.  I had originally planned for all the brackets to be on the inside of the table, but I later realized there wasn’t enough room to get a screw driver in, so they ended up on the outside.  There’s enough overhang that it didn’t really matter.</p>

<p>Then came a lot of sanding the edges of the table, followed by 4 or 5 coats of Minwax wipe on poly to give the top a bit of protection from being touched and drink spills.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/dndtvtable/top1.jpg">
    <img src="/images/dndtvtable/top1.jpg" alt="Cuting plywood with a circular saw. 2x4 as my 'straight' edge." style="max-width: 300px" />
    <figcaption>Cuting plywood with a circular saw. 2x4 as my 'straight' edge.</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/top2.jpg">
    <img src="/images/dndtvtable/top2.jpg" alt="Fit the first 2 pieces so I can measure the exact size for the last 2" style="max-width: 300px" />
    <figcaption>Fit the first 2 pieces so I can measure the exact size for the last 2</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/top3.jpg">
    <img src="/images/dndtvtable/top3.jpg" alt="Pieces in place" style="max-width: 300px" />
    <figcaption>Pieces in place</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/top4.jpg">
    <img src="/images/dndtvtable/top4.jpg" alt="Testing the dragon design on a scrap" style="max-width: 300px" />
    <figcaption>Testing the dragon design on a scrap</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/top5.jpg">
    <img src="/images/dndtvtable/top5.jpg" alt="Engraved pieces" style="max-width: 300px" />
    <figcaption>Engraved pieces</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/top6.jpg">
    <img src="/images/dndtvtable/top6.jpg" alt="Screwing in angle brackets" style="max-width: 300px" />
    <figcaption>Screwing in angle brackets</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/top7.jpg">
    <img src="/images/dndtvtable/top7.jpg" alt="So many angle brackets" style="max-width: 300px" />
    <figcaption>So many angle brackets</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/top8.jpg">
    <img src="/images/dndtvtable/top8.jpg" alt="Poly is finished" style="max-width: 300px" />
    <figcaption>Poly is finished</figcaption>
  </a>
</figure>

</div>

<h4 id="finishing-touches">Finishing Touches</h4>

<p>Initially I went with a piece of plexiglass just loose over the table top. This worked, but we found that when we put minis on it, it would curve in a bit and touch the screen. Which meant we had to lower the TV so the plexi wouldn’t press on it. Having the TV lower increased the parallax and made it hard to see what square the mini was actually in - it would look different depending on where you sat at the table.  In the end, I got a free broken pane of glass that had enough good section left to cut out a perfectly fitting top. The edges of the glass are wrapped in electrical tape since the glass cutter doesn’t always leave a perfectly smooth edge.  The glass just sits right on top of the TV’s frame, and doesn’t flex at all so nothing touches the screen. Then I raised the TV back up so the glass surface is level with the tabletop.</p>

<p>I also 3D printed a bracket to hold the remote in place so we never lose it, mounted a power bar on the table leg, and mounted a Raspberry PI under the table that runs the TV.</p>

<p>Since the TV has a serial port, I also <a href="https://github.com/grantemsley/viewsonictvrs232">wrote a program</a> that runs on the RPI to give the TV a web interface - where we can change the input, turn the TV on and off, and adjust color and volume from our phone or laptop.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/dndtvtable/finish1.jpg">
    <img src="/images/dndtvtable/finish1.jpg" alt="Finished table with plexiglass" style="max-width: 300px" />
    <figcaption>Finished table with plexiglass</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/finish2.jpg">
    <img src="/images/dndtvtable/finish2.jpg" alt="Remote control bracket" style="max-width: 300px" />
    <figcaption>Remote control bracket</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/finish3.jpg">
    <img src="/images/dndtvtable/finish3.jpg" alt="Remote just slides right in" style="max-width: 300px" />
    <figcaption>Remote just slides right in</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/finish4.jpg">
    <img src="/images/dndtvtable/finish4.jpg" alt="Power bar" style="max-width: 300px" />
    <figcaption>Power bar</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/dndtvtable/finish5.jpg">
    <img src="/images/dndtvtable/finish5.jpg" alt="Glass tabletop" style="max-width: 300px" />
    <figcaption>Glass tabletop</figcaption>
  </a>
</figure>

</div>

<h3 id="software">Software</h3>

<p>The RPI is just used to VNC to a virtual machine running <a href="https://www.rptools.net/toolbox/maptool/">Maptool</a>. This is a free program that lets us import the maps or design our own with tiles.</p>

<p>Originally the plan was to run Maptool directly on the RPI, but we found it to be a little too slow for our liking. Using it just for VNC to a more powerful machine works well, and also means I have a VM running 24/7 that our DM can remote into and create the maps at their leisure.  When we play, the DM runs another copy of Maptool on their laptop and connects to the server running in the virtual machine to control the map.</p>

<p>For the most part we play with physical minis, so we zoom in the map to make each square about 1 inch. For larger maps we can zoom out and use virtual minis when we need to.</p>

<h3 id="future-improvements">Future Improvements</h3>

<p>There are a few things I might do one day to improve the table:</p>

<ul>
  <li>Using bolts instead of screws to attach the legs. This would let us disassemble the table and make it “portable”, though I still wouldn’t want to move it very often.  This is something I’ll have to do if I ever move - it was built in the room we play in, because it won’t fit through the doorway fully assembled.</li>
  <li>A bit of trim around the edges of the glass, just to hide the taped edge</li>
  <li>A more powerful mini PC under the table. The RPI is great, but it would be nice to have something a little more powerful.</li>
</ul>]]></content><author><name>Grant Emsley</name></author><category term="Woodworking" /><summary type="html"><![CDATA[My D&amp;D TV Table]]></summary></entry><entry><title type="html">New laser from Endurance Lasers</title><link href="https://www.emsley.ca/laser/endurance-lasers-part1" rel="alternate" type="text/html" title="New laser from Endurance Lasers" /><published>2018-08-04T00:00:00-04:00</published><updated>2018-08-04T00:00:00-04:00</updated><id>https://www.emsley.ca/laser/endurance-lasers-part1</id><content type="html" xml:base="https://www.emsley.ca/laser/endurance-lasers-part1"><![CDATA[<p>I mentioned my new laser in my post about the IBM power supply mod. I’ve been trying to cut 3mm plywood with my cheap chinese lasers, and they just weren’t doing a good job of it.</p>

<p>Previously I’ve used <a href="https://www.fasttech.com/p/6790301">this 405nm 500mW</a> module, but it was very low powered, and more importantly didn’t have a TTL pin for PWM control.
Then I upgraded to <a href="https://www.fasttech.com/p/9369800">a 2500mW model</a>, which had a control board with PWM control. With PWM I can get great detail and shading doing raster graphics, but it’s still not enough power to cut through even thin plywood reliably.
It <em>will</em> cut 3mm plywood sometimes, but you’ll hit spots on the wood that it just doesn’t have the power to go through, and your piece will get damaged when you try to remove it.</p>

<p>So I took a look at higher quality lasers, and found <a href="http://endurancelasers.com/">Endurance Lasers</a>, a Russian site that sells laser modules. They even accept Bitcoin for payment, which is awesome!</p>

<p>I originally looked at the 5.6w version, but ended up buying their <a href="http://endurancelasers.com/diode-lasers/8-5w-plus-endurance-laser/">8.5w+ model</a> as well as a G2 lens and voltmeter for it. I paid close to CAD$800 with shipping and everything.
After outgrowing my last two laser purchases rather quickly, I wanted to make sure this would be the last one I have to buy.
In hindsight, I probably should have ordered the <a href="http://endurancelasers.com/diy-laser-kit/">DIY kit</a> and saved myself some money - I have all the skills needed to assemble it myself.</p>

<p>I love that the guy who runs Endurance Lasers gives you all the schematics, assembly diagrams and videos, and tons of other information. If anything breaks, it will be easy to repair myself.
Some of it is a bit scattered and difficult to find, so if you are going to buy from them I recommend you go to the bottom of the page that links to all the other pages, and read through <em>everything</em>.  There’s lots of useful information hidden in there.</p>

<p>Well here it is:</p>
<div class="gallery">
<figure class="image">
  <a href="/images/laser/1.jpg">
    <img src="/images/laser/1.jpg" alt="8.5+w Endurance laser" style="max-width: 300px" />
    <figcaption>8.5+w Endurance laser</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/laser/2.jpg">
    <img src="/images/laser/2.jpg" alt="Business end. Do not look into with remaining eye" style="max-width: 300px" />
    <figcaption>Business end. Do not look into with remaining eye</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/laser/3.jpg">
    <img src="/images/laser/3.jpg" alt="Internals" style="max-width: 300px" />
    <figcaption>Internals</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/laser/4.jpg">
    <img src="/images/laser/4.jpg" alt="Internals" style="max-width: 300px" />
    <figcaption>Internals</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/laser/5.jpg">
    <img src="/images/laser/5.jpg" alt="Internals" style="max-width: 300px" />
    <figcaption>Internals</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/laser/6.jpg">
    <img src="/images/laser/6.jpg" alt="Mounted on MPCNC" style="max-width: 300px" />
    <figcaption>Mounted on MPCNC</figcaption>
  </a>
</figure>

</div>

<h2 id="getting-the-laser-operational">Getting The Laser Operational</h2>

<p>There were a few modifications and upgrades I had to make to my CNC machine for the laser:</p>

<p>First order of business was printing the <a href="http://endurancelasers.com/download-center-lasers/"> casing</a> that redirects the side fan’s air towards the laser.</p>

<p>Then I had to <a href="https://www.thingiverse.com/thing:3026189">design a mount for the laser</a>.  I ended up making a full 3d model of the laser itself with fairly accurate dimensions, then designing two different mount options. I got lots of practice with Fusion 360.</p>

<p>Next was upgrading the power wiring for the laser. I used <a href="https://www.amazon.ca/gp/product/B0769FCLB4/">14awg silicone wire</a> for the portion that goes from the laser to the shut off switch, since that’s subjected to constant flexing.
The rest is run with 14awg solid household electric wire since I had a spool lying around.  The PWM pin doesn’t require heavy duty wire, so the 20awg stuff I already had there was fine.</p>

<p>Then I printed a bracket to hold the voltmeter onto the table.  After designing it, I realized that the voltmeter has a terrible viewing angle, so I mounted it crooked so I’d be able to see it.</p>

<p>Even with the thicker wires, I saw the voltage dropping to around 10v while the laser was running, so I <a href="/cnc/ibm-psu-mod">upgraded my power supply</a>.</p>

<h2 id="first-cut">First Cut</h2>

<p>Here’s my first cut, with barely any effort made to calibrate the laser.  This is in 1/8” baltic birch plywood.</p>

<figure class="image">
  <a href="/images/laser/cut1.jpg">
    <img src="/images/laser/cut1.jpg" alt="Cut plywood" style="max-width: 300px" />
    <figcaption>Cut plywood</figcaption>
  </a>
</figure>

<p>As you can see, it’s not pretty, but it did cut all the way through!</p>

<h2 id="improved-cutting-surface">Improved cutting surface</h2>

<p>One thing I quickly realized is that if the wood you are cutting is pushed against the table, smoke builds up under there and burns the wood around it. You also get more reflections of the laser and more charing on the bottom side.
Raising it above the surface fixes that. Professional machines use a <a href="https://www.google.ca/search?q=laser+cutter+honeycomb&amp;tbm=isch">metal honeycomb</a> material to do that. But sourcing it locally is impossible, and even from cheap sites like
Aliexpress it’s not all that cheap.</p>

<p>I did however have some scrap 3/4” melamine boards lying around, so I made my own kind.</p>

<p>I drew a grid on the board spaced about 2” apart, and drilled holes with a countersink bit.  I didn’t countersink them all the way though - I wanted the heads to all stick out a bit and not be driven all the way into the wood.
I used a #12 countersink bit, but didn’t drill far enough for the outer radius to get cut. Then I screwed in #8 1.5” screws. I wish I had a drill press to make sure the holes were all perfect - a few of them are tilted a bit, but it came out well enough.</p>

<p>It’s nowhere near as accurate as purchasing one, but it does the job.</p>

<div class="gallery">
<figure class="image">
  <a href="/images/laser/board1.jpg">
    <img src="/images/laser/board1.jpg" alt="Drill holes" style="max-width: 300px" />
    <figcaption>Drill holes</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/laser/board2.jpg">
    <img src="/images/laser/board2.jpg" alt="Insert screws" style="max-width: 300px" />
    <figcaption>Insert screws</figcaption>
  </a>
</figure>

<figure class="image">
  <a href="/images/laser/board3.jpg">
    <img src="/images/laser/board3.jpg" alt="Bed of nails to support workpiece" style="max-width: 300px" />
    <figcaption>Bed of nails to support workpiece</figcaption>
  </a>
</figure>

</div>

<h2 id="calibration">Calibration</h2>

<p>Calibrating the laser perfectly is important if you want good, clean cuts.</p>

<h3 id="focusheight">Focus/Height</h3>

<p>This is how I figured out how to calibrate the laser’s focus:</p>

<ul>
  <li>First I lowered the Z axis until the base of it just touched the workpiece. This always becomes my Z 0 position.</li>
  <li>Measured the distance from the workpiece to the laser lens - it’s 19mm. This won’t change, but was important for figuring out where the focus point should be. The focal length for the regular 3 element lens is around 60mm, so that means I should raise
the Z axis by 41mm</li>
  <li>Turn the lens so it’s about half way in.</li>
  <li>Raise Z to 41mm</li>
  <li>Turn lens a bit to try to get a nice tight dot.  Don’t worry about getting it perfect, just somewhere in the range that makes a small dot.</li>
  <li>Try engraving lines at different heights. I used <a href="/files/laser/calibrationlines.svg">this SVG with lines and markers for heights 31-51</a>.</li>
  <li>Look for where you get the thinnest lines. They should go from thick, to thin, to thick again.  That thin section is your usable cutting range.</li>
</ul>

<p>In my test, the 51mm line was still fairly thin, so I might have to try going even higher.  But in further testing, starting at 47mm seems to work best.</p>

<p>Now, as long as I don’t touch the lens, I can just lower the Z axis to touch the workpiece, then cut at Z 47mm.</p>

<h3 id="power-speed-and-passes">Power, Speed and Passes</h3>

<p>Too slow and you char the wood or even start a fire.  Too fast and you don’t break through.  The only way to figure this out is trial and error. And it will be different for each material you work with.</p>

<p>For cutting baltic birch plywood, the hardest part to cut is against the grain.  Lines going with the grain cut easily. So I made an SVG of a 5cm by 0.5cm rectangle, and made the long sides be across the grain.</p>

<p>Then I tested with different combinations of power levels from 50-100%, heights from 45-50, and speeds from 60-250 mm/min.  I made a spreadsheet to record my settings and the results. With option, I set it to a single pass and kept rerunning the job until
it either cut through, or was obvious it wasn’t going to work well.</p>

<p>What I’m looking for is:</p>

<ul>
  <li>How thin is the line on the top surface?  Thinner is better.</li>
  <li>Is the wood around the cut charred? It’s going to be black on the edges no matter what, but the wood that remains shouldn’t look like coals from a camp fire.</li>
  <li>Did it cut all the way through?  In how many passes?  Some settings result in the piece falling out on it’s own, others are removable with a little pressure, others damage the wood when removing it because too many fibres are still attached.</li>
</ul>

<p>So far the best settings I’ve found after much trial and error are:</p>

<ul>
  <li>80% power</li>
  <li>4 passes</li>
  <li>47mm height</li>
  <li>200mm/min</li>
</ul>

<h2 id="problems">Problems</h2>

<p>I do still have some issues with the equipment:</p>

<ul>
  <li>The voltmeter isn’t all that great. It resets itself constantly when the laser is being run at &lt; 100% duty cycle.  Powering it separately instead of inline with the laser might help with that. Also, the LEDs for the amperate rating are blue.
Which makes it nearly invisible when you have the safety glasses on - they block blue light almost entirely.</li>
  <li>The top fan on the laser died after at most a couple hours of operation. Replacing it was easy enough, and I opted to replace it with a more powerful fan while I was at it.  But 50mm fans aren’t super common, so I was lucky to find one quickly. 
<strong>Update</strong>: I emailed George from Endurance Lasers about the fan dying. He offered to send me a new one right away.  When I told him I had already replaced it, he refunded me the cost of the fan I bought. Now that’s good customer service! Very impressed with that.</li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p>This laser is a lot more powerful than the previous ones. I’m still working on fine tuning the settings, but it’s definitely up to the job.  Once I’ve made some stuff I’ll post more pictures and videos of the machine in action.</p>]]></content><author><name>Grant Emsley</name></author><category term="Laser" /><summary type="html"><![CDATA[I mentioned my new laser in my post about the IBM power supply mod. I’ve been trying to cut 3mm plywood with my cheap chinese lasers, and they just weren’t doing a good job of it.]]></summary></entry></feed>