<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Federico Hatoum — Blog</title>
  <link>https://hatoum.com/blog/</link>
  <atom:link href="https://hatoum.com/blog/feed.xml" rel="self" type="application/rss+xml"/>
  <description>Federico Hatoum is a software developer, maker and YouTuber in Los Angeles. Woodworking, 3D printing and repair write-ups, plus films and commercials.</description>
  <language>en-us</language>
  <lastBuildDate>Fri, 17 Dec 2021 11:22:08 -0800</lastBuildDate>
  <item>
    <title>Best Mini Spot Welder? Review of the Malectrics Mini Spot Welder</title>
    <link>https://hatoum.com/blog/2021/12/17/best-mini-spot-welder-review-of-the-malectrics-mini-spot-welder/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2021/12/17/best-mini-spot-welder-review-of-the-malectrics-mini-spot-welder/</guid>
    <pubDate>Fri, 17 Dec 2021 11:22:08 -0800</pubDate>
    <description>&lt;h2&gt;TL;DR&lt;/h2&gt;

&lt;p&gt;I reviewed the Malectrics Mini Spot Welder (v3) on my &lt;a href=&quot;https://www.youtube.com/channel/UCQGkNFXJCUBLkzMIShzf12g&quot;&gt;YouTube channel Fed Learns to Make&lt;/a&gt;. Compared to other mini spot welders, I found the Malectrics to be much better built, designed and safer. It&#x27;s not the cheapest (nor the most expensive), but is, in my opinion, the best you can get under $200.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href=&quot;https://malectrics.eu&quot;&gt;Malectrics.eu&lt;/a&gt;&lt;/p&gt;

&lt;figure class=&quot;video&quot;&gt;&lt;a class=&quot;yt&quot; href=&quot;https://www.youtube.com/watch?v=SelxyJrkfP4&quot; data-yt=&quot;SelxyJrkfP4&quot; data-title=&quot;Best Mini Spot Welder? Super Safe, Great Design - Review - Fed&amp;#x27;s Tool Corner&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/video/SelxyJrkfP4.webp&quot; alt=&quot;&quot; width=&quot;960&quot; height=&quot;540&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;yt-play&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Play video: Best Mini Spot Welder? Super Safe, Great Design - Review - Fed&amp;#x27;s Tool Corner&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;
</description>
  </item>
  <item>
    <title>Fed Learns To Make Video: Coffee Can Secret Hiding Place Stash!</title>
    <link>https://hatoum.com/blog/2021/6/27/fed-learns-to-make-video-coffee-can-secret-hiding-place-stash/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2021/6/27/fed-learns-to-make-video-coffee-can-secret-hiding-place-stash/</guid>
    <pubDate>Sun, 04 Jul 2021 22:05:58 -0700</pubDate>
    <description>&lt;p&gt;I build a secret stash to hide all my super-valuable stuff out of a Trader Joe&#x27;s coffee can, 3D printed parts, insulating foam and lots of magnets. No one will suspect that this coffee can holds all your most cherish possessions! Amaze your friends! Confound your enemies!&lt;/p&gt;

&lt;figure class=&quot;video&quot;&gt;&lt;a class=&quot;yt&quot; href=&quot;https://www.youtube.com/watch?v=C4B6cHK39vA&quot; data-yt=&quot;C4B6cHK39vA&quot; data-title=&quot;Coffee Can Secret Hiding Place Stash -- Stash all your awesome stuff in this secret hiding place!&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/video/C4B6cHK39vA.webp&quot; alt=&quot;&quot; width=&quot;960&quot; height=&quot;540&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;yt-play&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Play video: Coffee Can Secret Hiding Place Stash -- Stash all your awesome stuff in this secret hiding place!&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;Parts list (Amazon Affiliate Links):&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://amzn.to/3dhEByK&quot;&gt;6mmx2mm small magnets&lt;/a&gt;: &lt;a href=&quot;https://amzn.to/3dhEByK&quot;&gt;—&amp;gt; https://amzn.to/3dhEByK&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;https://amzn.to/3w6tWha&quot;&gt;3mmx2mm tiny magnets&lt;/a&gt;: &lt;a href=&quot;https://amzn.to/3w6tWha&quot;&gt;—&amp;gt; https://amzn.to/3w6tWha&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;https://amzn.to/3xVCLeX&quot;&gt;Tecbears PLA Filament (Black)&lt;/a&gt;: &lt;a href=&quot;https://amzn.to/3xVCLeX&quot;&gt;—&amp;gt; https://amzn.to/3xVCLeX&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;https://amzn.to/35YfLQC&quot;&gt;Geeetech PLA Filament (Clear)&lt;/a&gt;: &lt;a href=&quot;https://amzn.to/35YfLQC&quot;&gt;—&amp;gt; https://amzn.to/35YfLQC&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;https://amzn.to/3A6M2m8&quot;&gt;Loctite Tite Foam Window and Door Sealant&lt;/a&gt;: &lt;a href=&quot;https://amzn.to/3A6M2m8&quot;&gt;—&amp;gt; https://amzn.to/3A6M2m8&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;https://amzn.to/3h5HN1C&quot;&gt;E6000 Glue&lt;/a&gt;: &lt;a href=&quot;https://amzn.to/3h5HN1C&quot;&gt;—&amp;gt; https://amzn.to/3h5HN1C&lt;/a&gt;&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Fed Learns To Make Video: Compact Workbench with Pocket Hole Joinery</title>
    <link>https://hatoum.com/blog/2021/2/27/fed-learns-to-make-video-compact-workbench-with-pocket-hole-joinery/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2021/2/27/fed-learns-to-make-video-compact-workbench-with-pocket-hole-joinery/</guid>
    <pubDate>Sat, 27 Feb 2021 16:29:39 -0800</pubDate>
    <description>&lt;p&gt;I built a compact workbench based off of Steve Ramsey’s BMW design, but using pocket hole joinery and with more drawers.&lt;/p&gt;

&lt;figure class=&quot;video&quot;&gt;&lt;a class=&quot;yt&quot; href=&quot;https://www.youtube.com/watch?v=mWQc91Olo8s&quot; data-yt=&quot;mWQc91Olo8s&quot; data-title=&quot;Compact Workbench with Pocket Hole Joinery and Casters for Small Workshop&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/video/mWQc91Olo8s.webp&quot; alt=&quot;&quot; width=&quot;960&quot; height=&quot;540&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;yt-play&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Play video: Compact Workbench with Pocket Hole Joinery and Casters for Small Workshop&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;Some of the videos that helped me learn to make: &lt;/p&gt;

&lt;p&gt;Pocket Holes:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Steve Ramsey: &lt;a href=&quot;https://youtu.be/mvO6zaIUO18&quot;&gt;https://youtu.be/mvO6zaIUO18&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Colin Knecht: &lt;a href=&quot;https://youtu.be/bOrQ9lH8qSc&quot;&gt;https://youtu.be/bOrQ9lH8qSc&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Table Saw Basics:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Steve Ramsey: &lt;a href=&quot;https://youtu.be/tKtE0sTFi8g&quot;&gt;https://youtu.be/tKtE0sTFi8g&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Steve Ramsey: &lt;a href=&quot;https://youtu.be/JOhZxvgkWNM&quot;&gt;https://youtu.be/JOhZxvgkWNM&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Stumpy Nubs: &lt;a href=&quot;https://youtu.be/qSbS5zhH7cE&quot;&gt;https://youtu.be/qSbS5zhH7cE&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Miter Saw Basics:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Anika&#x27;s DIY Life: &lt;a href=&quot;https://youtu.be/7fjHvYy5lkg&quot;&gt;https://youtu.be/7fjHvYy5lkg&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Steve Ramsey&#x27;s Weekend Woodworker: &lt;a href=&quot;https://theweekendwoodworker.com/&quot;&gt;https://theweekendwoodworker.com/&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;My tools:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Banks Pin Nailer: &lt;a href=&quot;https://www.harborfreight.com/23-gauge-pin-nailer-64143.html&quot;&gt;https://www.harborfreight.com/23-gauge-pin-nailer-64143.html&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Dewalt DW745 10-inch table saw: &lt;a href=&quot;https://amzn.to/2YO5qUm&quot;&gt;https://amzn.to/2YO5qUm&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;DFM Small Square: &lt;a href=&quot;https://amzn.to/2YO5qUm&quot;&gt;https://amzn.to/2YO5qUm&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Dewalt Fixed Base Router (DWP611): &lt;a href=&quot;https://amzn.to/3ifwWBU&quot;&gt;https://amzn.to/3ifwWBU&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Elmer&#x27;s Wood Glue Max: &lt;a href=&quot;https://amzn.to/31CDHYv&quot;&gt;https://amzn.to/31CDHYv&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Porter Cable Cordless Brad Nailer: &lt;a href=&quot;https://amzn.to/3gmBCEb&quot;&gt;https://amzn.to/3gmBCEb&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Prusa MK3 3D Printer: &lt;a href=&quot;https://shop.prusa3d.com/en/3d-printers/180-original-prusa-i3-mk3s-kit.html&quot;&gt;https://shop.prusa3d.com/en/3d-printers/180-original-prusa-i3-mk3s-kit.html&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Rigid Air Compressor: &lt;a href=&quot;https://www.homedepot.com/p/RIDGID-6-Gal-Portable-Electric-Pancake-Air-Compressor-OF60150HB/303379052&quot;&gt;https://www.homedepot.com/p/RIDGID-6-Gal-Portable-Electric-Pancake-Air-Compressor-OF60150HB/303379052&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;WEN 4210T Drill Press: &lt;a href=&quot;https://amzn.to/3eSV0sm&quot;&gt;https://amzn.to/3eSV0sm&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;WEN 6502T Sander: &lt;a href=&quot;https://amzn.to/3dPTshl&quot;&gt;https://amzn.to/3dPTshl&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;My video equipment:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Barrina LED Light Fixtures: &lt;a href=&quot;https://amzn.to/3iwobUm&quot;&gt;https://amzn.to/3iwobUm&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Sony Alpha a6400 Mirrorless Camera: &lt;a href=&quot;https://amzn.to/2YPZ7Q6&quot;&gt;https://amzn.to/2YPZ7Q6&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Deity V-Mic D3 Shotgun Microphone: &lt;a href=&quot;https://amzn.to/2YTmVmu&quot;&gt;https://amzn.to/2YTmVmu&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Neewer LED Video Lights: &lt;a href=&quot;https://amzn.to/2ZrWbZf&quot;&gt;https://amzn.to/2ZrWbZf&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;OWC 4-Bay Thunderbolt Drive Enclosure: &lt;a href=&quot;https://amzn.to/3pGcsW0&quot;&gt;https://amzn.to/3pGcsW0&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;GoPro Hero7 Black action camera: &lt;a href=&quot;https://amzn.to/2WYzIlw&quot;&gt;https://amzn.to/2WYzIlw&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;


&lt;p&gt;Note: Amazon links are affiliate program links.&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Fed Learns to Make video: DIY Teleprompter</title>
    <link>https://hatoum.com/blog/2020/8/17/fed-learns-to-make-video-diy-teleprompter/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2020/8/17/fed-learns-to-make-video-diy-teleprompter/</guid>
    <pubDate>Sun, 16 Aug 2020 21:05:29 -0700</pubDate>
    <description>&lt;p&gt;I build a compact DIY Teleprompter that uses an iPhone or Android to display text. Has a built-in camera mount. I provide you with a parts list and a PDF of the plans I used, plus I show you how make regular glass more reflective. There are also links to the 3D printed parts I designed for the teleprompter.&lt;/p&gt;

&lt;figure class=&quot;video&quot;&gt;&lt;a class=&quot;yt&quot; href=&quot;https://www.youtube.com/watch?v=yjT1szUJFGY&quot; data-yt=&quot;yjT1szUJFGY&quot; data-title=&quot;DIY Teleprompter for DSLR -- Plans, Glass and Mirror film, uses iPhone/Android/Smartphone for text&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/video/yjT1szUJFGY.webp&quot; alt=&quot;&quot; width=&quot;960&quot; height=&quot;540&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;yt-play&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Play video: DIY Teleprompter for DSLR -- Plans, Glass and Mirror film, uses iPhone/Android/Smartphone for text&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;Rachel McAdams you were so great in Eurovision!&lt;br/&gt;&lt;a href=&quot;https://youtu.be/7q6Co-nd0lM&quot;&gt;https://youtu.be/7q6Co-nd0lM&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Parts Used for this build:&lt;/h3&gt;

&lt;p&gt;Double-sided Paper Tape: &lt;a href=&quot;https://amzn.to/3h3xXMn&quot;&gt;https://amzn.to/3h3xXMn&lt;/a&gt; (1&quot;) , &lt;a href=&quot;https://amzn.to/2Cw05Zy&quot;&gt;https://amzn.to/2Cw05Zy&lt;/a&gt; (1/2&quot;)&lt;/p&gt;

&lt;p&gt;1/4-20 Threaded Inserts (better than the ones I used): &lt;a href=&quot;https://amzn.to/30ZdTp0&quot;&gt;https://amzn.to/30ZdTp0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1/4-20 x 3/4&quot; Button Head Cap Screws: &lt;a href=&quot;https://amzn.to/3fWh4C4&quot;&gt;https://amzn.to/3fWh4C4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assorted Threaded Knurled Brass Inserts (for M2, M3, M4 and M5 screws): &lt;a href=&quot;https://amzn.to/2EbVe0k&quot;&gt;https://amzn.to/2EbVe0k&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assorted M2-M5 Nuts and Screws: &lt;a href=&quot;https://amzn.to/3kMQFdw&quot;&gt;https://amzn.to/3kMQFdw&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15mm Aluminum Rods: &lt;a href=&quot;https://amzn.to/311MUsX&quot;&gt;https://amzn.to/311MUsX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Camera mounting plate: &lt;a href=&quot;https://amzn.to/3iK97lc&quot;&gt;https://amzn.to/3iK97lc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Window Privacy Mirror Film Vinyl (different than the one I bought): &lt;a href=&quot;https://amzn.to/3h3ZiOH&quot;&gt;https://amzn.to/3h3ZiOH&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acrylic See-Through Mirror (in case you want to use acrylic): &lt;a href=&quot;https://amzn.to/3h6sZyl&quot;&gt;https://amzn.to/3h6sZyl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;8mm x 3mm Magnets: &lt;a href=&quot;https://amzn.to/3h1eBrq&quot;&gt;https://amzn.to/3h1eBrq&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sanding Drum Kit: &lt;a href=&quot;https://www.harborfreight.com/4-piece-quick-change-sanding-drum-set-35455.html&quot;&gt;https://www.harborfreight.com/4-piece-quick-change-sanding-drum-set-35455.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF Plans:&lt;/strong&gt;&lt;br/&gt;&lt;a href=&quot;https://hatoum.com/files/Teleprompter-Drawing-v20.pdf&quot;&gt;Teleprompter-Drawing-v20.pdf&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;3D Printed Parts:&lt;/h3&gt;

&lt;p&gt;Knob for M4 screw: &lt;a href=&quot;https://www.thingiverse.com/thing:3795536&quot;&gt;https://www.thingiverse.com/thing:3795536&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15mm Camera rail mounts: &lt;a href=&quot;https://www.thingiverse.com/thing:4572065&quot;&gt;https://www.thingiverse.com/thing:4572065&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Magnet Mounts: &lt;a href=&quot;https://www.thingiverse.com/thing:4572073&quot;&gt;https://www.thingiverse.com/thing:4572073&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Other Teleprompter videos:&lt;/h3&gt;

&lt;p&gt;$35: &lt;a href=&quot;https://youtu.be/n5_B8yksQmo&quot;&gt;https://youtu.be/n5_B8yksQmo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;$4: &lt;a href=&quot;https://youtu.be/f62KR51VE6c&quot;&gt;https://youtu.be/f62KR51VE6c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;$0: &lt;a href=&quot;https://youtu.be/xxIE-xBzbeA&quot;&gt;https://youtu.be/xxIE-xBzbeA&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3D Printed: &lt;a href=&quot;https://youtu.be/rcsASFFXf_k&quot;&gt;https://youtu.be/rcsASFFXf_k&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TKOR: &lt;a href=&quot;https://youtu.be/SZIA4kJPd6M&quot;&gt;https://youtu.be/SZIA4kJPd6M&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Some of the videos that helped me learn to make:&lt;/h3&gt;

&lt;p&gt;See Jane Drill: Air compressor basics: &lt;a href=&quot;https://www.youtube.com/watch?v=tpe4prO1B7U&quot;&gt;https://www.youtube.com/watch?v=tpe4prO1B7U&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inspire Woodcraft: Double-sided tape: &lt;a href=&quot;https://youtu.be/3Gw3Z3yt1v0&quot;&gt;https://youtu.be/3Gw3Z3yt1v0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3x3Custom: Double-sided tape: &lt;a href=&quot;https://youtu.be/QCjgdMAOnmU?t=238&quot;&gt;https://youtu.be/QCjgdMAOnmU?t=238&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tested-Adam Savage: Foam Core House: &lt;a href=&quot;https://youtu.be/ssxCQuv3KzE&quot;&gt;https://youtu.be/ssxCQuv3KzE&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nail Gun Tips and Tricks: &lt;a href=&quot;https://youtu.be/xgnbArqJfoE&quot;&gt;https://youtu.be/xgnbArqJfoE&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which Nail Gun Do I need?: &lt;a href=&quot;https://youtu.be/cYZ2hIqzH40&quot;&gt;https://youtu.be/cYZ2hIqzH40&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;-------------------------------------------------------------------------&lt;/p&gt;

&lt;h3&gt;My tools:&lt;/h3&gt;

&lt;p&gt;Dewalt DW745 10-inch table saw: &lt;a href=&quot;https://amzn.to/2YO5qUm&quot;&gt;https://amzn.to/2YO5qUm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DFM Small Square: &lt;a href=&quot;https://amzn.to/2YO5qUm&quot;&gt;https://amzn.to/2YO5qUm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dewalt Fixed Base Router (DWP611): &lt;a href=&quot;https://amzn.to/3ifwWBU&quot;&gt;https://amzn.to/3ifwWBU&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Elmer&#x27;s Wood Glue Max: &lt;a href=&quot;https://amzn.to/31CDHYv&quot;&gt;https://amzn.to/31CDHYv&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Porter Cable Cordless Brad Nailer: &lt;a href=&quot;https://amzn.to/3gmBCEb&quot;&gt;https://amzn.to/3gmBCEb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Banks Pin Nailer: &lt;a href=&quot;https://www.harborfreight.com/23-gauge-pin-nailer-64143.html&quot;&gt;https://www.harborfreight.com/23-gauge-pin-nailer-64143.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WEN 4210T Drill Press: &lt;a href=&quot;https://amzn.to/3eSV0sm&quot;&gt;https://amzn.to/3eSV0sm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WEN 6502T Sander: &lt;a href=&quot;https://amzn.to/3dPTshl&quot;&gt;https://amzn.to/3dPTshl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rigid Air Compressor: &lt;a href=&quot;https://www.homedepot.com/p/RIDGID-6-Gal-Portable-Electric-Pancake-Air-Compressor-OF60150HB/303379052&quot;&gt;https://www.homedepot.com/p/RIDGID-6-Gal-Portable-Electric-Pancake-Air-Compressor-OF60150HB/303379052&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;My video equipment:&lt;/h3&gt;

&lt;p&gt;Barrina LED Light Fixtures: &lt;a href=&quot;https://amzn.to/3iwobUm&quot;&gt;https://amzn.to/3iwobUm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sony Alpha a6400 Mirrorless Camera: &lt;a href=&quot;https://amzn.to/2YPZ7Q6&quot;&gt;https://amzn.to/2YPZ7Q6&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deity V-Mic D3 Shotgun Microphone: &lt;a href=&quot;https://amzn.to/2YTmVmu&quot;&gt;https://amzn.to/2YTmVmu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neewer LED Video Lights: &lt;a href=&quot;https://amzn.to/2ZrWbZf&quot;&gt;https://amzn.to/2ZrWbZf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Amazon links are affiliate program links.&lt;/p&gt;

&lt;p&gt;Sound effects obtained from &lt;a href=&quot;https://www.zapsplat.com&quot;&gt;https://www.zapsplat.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Music by Miishi: &lt;a href=&quot;https://soundcloud.com/miishiofficial&quot;&gt;https://soundcloud.com/miishiofficial&lt;/a&gt;&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Inaugural video of my new YouTube Channel: Fed Learns To Make</title>
    <link>https://hatoum.com/blog/2020/7/1/inaugural-video-of-my-new-youtube-channel-fed-learns-to-make/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2020/7/1/inaugural-video-of-my-new-youtube-channel-fed-learns-to-make/</guid>
    <pubDate>Wed, 01 Jul 2020 19:45:59 -0700</pubDate>
    <description>&lt;p&gt;This is the first video of my new YouTube channel called Fed Learns To Make.&lt;/p&gt;

&lt;p&gt;The idea behind the channel is to follow my journey as I learn to become a maker by watching hundreds and hundreds (and hundreds) of YouTube videos about all kinds topics. I’ve made some things here and there, but I never focused on methodically learning woodworking, mold making, cos play, metal work, electronics, machinery, etc.&lt;/p&gt;

&lt;p&gt;YouTube is an amazing source of information and learning, but sometimes it can be overwhelming due to the sheer number of videos on any particular topic. I’ll watch them all (or most of them) and distill down what I’ve learned in the videos I create, giving viewers links to the best videos on specific techniques or ideas.&lt;/p&gt;

&lt;figure class=&quot;video&quot;&gt;&lt;a class=&quot;yt&quot; href=&quot;https://www.youtube.com/watch?v=4A-kgpaA97c&quot; data-yt=&quot;4A-kgpaA97c&quot; data-title=&quot;Building a Shop Vac Boom Arm // Overhead Shop Vac Hose // Make space in your workshop // Woodworking&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/video/4A-kgpaA97c.webp&quot; alt=&quot;&quot; width=&quot;960&quot; height=&quot;540&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;yt-play&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Play video: Building a Shop Vac Boom Arm // Overhead Shop Vac Hose // Make space in your workshop // Woodworking&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;h2&gt;Related Video Links:&lt;/h2&gt;

&lt;p&gt;Stumpy Nubs video with Dura-Grit sanding blocks:&lt;br/&gt;&lt;a href=&quot;https://youtu.be/BhFIZQvywM&quot;&gt;https://youtu.be/BhFIZQvywM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make Anything kerf cut videos:&lt;br/&gt;&lt;a href=&quot;https://youtu.be/JS9yMUpoWME&quot;&gt;https://youtu.be/JS9yMUpoWME&lt;/a&gt;&lt;br/&gt;&lt;a href=&quot;https://youtu.be/ngC5S5vWQ4g&quot;&gt;https://youtu.be/ngC5S5vWQ4g&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;My Tools: &lt;/h2&gt;

&lt;p&gt;Dewalt DW745 10-inch Table Saw: &lt;a href=&quot;https://amzn.to/2YO5qUm&quot;&gt;https://amzn.to/2YO5qUm&lt;/a&gt;&lt;br/&gt;DFM Small Square: &lt;a href=&quot;https://amzn.to/2YO5qUm&quot;&gt;https://amzn.to/2YO5qUm&lt;/a&gt;&lt;br/&gt;Dewalt Fixed Base Router (DWP611): &lt;a href=&quot;https://amzn.to/3ifwWBU&quot;&gt;https://amzn.to/3ifwWBU&lt;/a&gt;&lt;br/&gt;Elmer&#x27;s Wood Glue Max: &lt;a href=&quot;https://amzn.to/31CDHYv&quot;&gt;https://amzn.to/31CDHYv&lt;/a&gt;&lt;br/&gt;Porter Cable Cordless Brad Nailer: &lt;a href=&quot;https://amzn.to/3gmBCEb&quot;&gt;https://amzn.to/3gmBCEb&lt;/a&gt;&lt;br/&gt;WEN 4210T Drill Press: &lt;a href=&quot;https://amzn.to/3eSV0sm&quot;&gt;https://amzn.to/3eSV0sm&lt;/a&gt;&lt;br/&gt;WEN 6502T Sander: &lt;a href=&quot;https://amzn.to/3dPTshl&quot;&gt;https://amzn.to/3dPTshl&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;My Video Equipment: &lt;/h2&gt;

&lt;p&gt;Barrina LED Light Fixtures: &lt;a href=&quot;https://amzn.to/3iwobUm&quot;&gt;https://amzn.to/3iwobUm&lt;/a&gt;&lt;br/&gt;Sony Alpha a6400 Mirrorless Camera: &lt;a href=&quot;https://amzn.to/2YPZ7Q6&quot;&gt;https://amzn.to/2YPZ7Q6&lt;/a&gt;&lt;br/&gt;Deity V-Mic D3 Shotgun Microphone: &lt;a href=&quot;https://amzn.to/2YTmVmu&quot;&gt;https://amzn.to/2YTmVmu&lt;/a&gt; &lt;br/&gt;Neewer LED Video Lights: &lt;a href=&quot;https://amzn.to/2ZrWbZf&quot;&gt;https://amzn.to/2ZrWbZf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Garage Hooks from the video: &lt;a href=&quot;https://amzn.to/2YScOxW&quot;&gt;https://amzn.to/2YScOxW&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Amazon links are affiliate program links.&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Install both a Raspberry PI Camera and a USB Camera on Octopi 0.17 and 0.18</title>
    <link>https://hatoum.com/blog/2020/5/27/install-both-a-raspberry-pi-camera-and-a-usb-camera-on-octopi-017/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2020/5/27/install-both-a-raspberry-pi-camera-and-a-usb-camera-on-octopi-017/</guid>
    <pubDate>Sat, 30 May 2020 08:48:20 -0700</pubDate>
    <description>&lt;h3&gt;Last updated February 27, 2021&lt;/h3&gt;

&lt;hr&gt;

&lt;p&gt;I use &lt;a href=&quot;https://octoprint.org/&quot;&gt;Octoprint&lt;/a&gt; to manage my Prusa MK3 3D printer. To keep an eye on my prints, I have two cameras hooked up to the Raspberry PI on which I have Octoprint installed. The main camera is a Raspberry PI camera that hooks up directly the PI via a ribbon cable, and the second camera is a Logitech C510 webcam that I plug into one of the PI’s USB ports.&lt;/p&gt;

&lt;p&gt;When I upgraded &lt;a href=&quot;https://github.com/guysoft/OctoPi&quot;&gt;Octopi&lt;/a&gt; — a Raspberry PI Linux distribution that comes with Octoprint pre-installed — the USB camera stopped working and I couldn’t figure out how to get it working again. Octopi 0.17 is significantly different from previous versions, so I couldn’t rely on the tutorials I had used before.&lt;/p&gt;

&lt;p&gt;I searched on YouTube, my favorite DIY resource, and found Chris Riley’s &lt;em&gt;Chris’ Basement&lt;/em&gt; channel. He has a &lt;a href=&quot;https://youtu.be/sCxvW1XX44U&quot;&gt;series of videos&lt;/a&gt; on how to set up an Octoprint multi-instance on one PI on Octopi 0.17.  His instructions are great and I wouldn’t have found a solution without his videos, but they are geared toward hooking up USB cameras — not both a Raspberry PI camera and a USB camera.&lt;/p&gt;

&lt;h2&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;In this post I don’t explain how to install Octopi 0.17/0.18, nor how to attach and get working a PI Cam. You’ll need to get that done first before moving on.&lt;/p&gt;

&lt;p&gt;You’ll also need to know a little about getting around a Linux command line and using the nano text editor.&lt;/p&gt;

&lt;p&gt;Once you have the PI  and PI Cam up and running, follow the instructions below to get a second (USB) camera working with your Raspberry PI.&lt;/p&gt;

&lt;h3&gt;Word of Caution:&lt;/h3&gt;

&lt;p&gt;You might be tempted to connect 2, 3 or 4 USB webcams to your Raspberry PI. Don’t do it. That path leads to madness. The cameras won’t mount as expected — I suspect because of limitations of Raspberry PIs in general, but I don’t know for sure. You’ll drive yourself crazy. Be content with running the RPI Camera Module and one USB camera.&lt;/p&gt;

&lt;h2&gt;1: Get information about your USB webcam&lt;/h2&gt;

&lt;p&gt;Log into your Raspberry PI via ssh. If you followed the standard Octopi setup, ssh’ing into your PI should be as simple as this:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; ssh pi@octopi.local&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Make sure your USB webcam is unplugged from Raspberry PI. Type the following command in the terminal:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; tail -f /var/log/messages&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Now plug the USB camera back in, and look at the new text that appeared in the logs you’re tailing. You should see bunch of lines that include the text “New USB device found”, or similar. Here’s an example of my log:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;May 25 17:43:00 octopi kernel: [    2.411980] usb 1-1.3: new high-speed USB device number 5 using dwc_otg
May 25 17:43:00 octopi kernel: [    2.753813] usb 1-1.3: New USB device found, idVendor=046d, idProduct=081b, bcdDevice= 0.12
May 25 17:43:00 octopi kernel: [    2.759809] usb 1-1.3: New USB device strings: Mfr=0, Product=0, SerialNumber=2May 25 17:43:00 octopi kernel: [    2.763045] usb 1-1.3: SerialNumber: 61196260&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;You&#x27;ll need the values for &lt;strong&gt;idVendor&lt;/strong&gt;, &lt;strong&gt;idProduct&lt;/strong&gt;, and &lt;strong&gt;SerialNumber&lt;/strong&gt; in the next step.&lt;/p&gt;

&lt;h2&gt;2: Create (or edit if existing) USB rules file&lt;/h2&gt;

&lt;p&gt;Use the nano text editor to edit (or create) a usb rules file:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; sudo nano /etc/udev/rules.d/99-usb.rules&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Add the following line to the file:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;SUBSYSTEM==&quot;video4linux&quot;, ATTRS{idVendor}==&quot;046d&quot;, ATTRS{idProduct}==&quot;081b&quot;, ATTRS{serial}==&quot;61196260&quot;, SYMLINK+=&quot;PrusaWebCam&quot;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;These are the values I found in my log for my camera (a Logitech C510 HD webcam) — you’ll need to use your values for idVendor, idProduct and serial. For SYMLINK, use whatever name you want to give your camera. You’ll use the name in upcoming steps.&lt;/p&gt;

&lt;h2&gt;3: Confirm USB camera is properly set up:&lt;/h2&gt;

&lt;p&gt;Before moving on to step 4, it’s a good idea to confirm that the camera you configured in the previous udev USB rules step is working properly. If it isn’t, then none of the steps that follow will work.&lt;/p&gt;

&lt;p&gt;First, let’s reboot the Raspberry PI to make it read the settings in &lt;code&gt;99-usb.rules&lt;/code&gt; and connect your camera.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; sudo reboot&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Once your PI is back up, ssh into it again and type the following command to list all the devices under the &lt;code&gt;/dev&lt;/code&gt; directory:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; ls -la /dev&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;If &lt;code&gt;99-usb.rules&lt;/code&gt; was read correctly at startup, you should find the symlink you created under &lt;code&gt;/dev&lt;/code&gt;. Here’s what I see on my PI (I removed lots of entries to keep this short):&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;drwxr-xr-x  2 root root          60 Feb 11 19:20 net
crw-rw-rw-  1 root root      1,   3 Feb 11 19:20 null
crw-------  1 root root    108,   0 Feb 11 19:20 ppp
lrwxrwxrwx  1 root root           6 Feb 11 19:20 PrusaWebCam -&amp;gt; video0
crw-rw-rw-  1 root tty       5,   2 Feb 11 19:26 ptmx
drwxr-xr-x  2 root root           0 Feb 14  2019 pts
brw-rw----  1 root disk      1,   0 Feb 11 19:20 ram0&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;The &lt;code&gt;-&amp;gt;&lt;/code&gt; character next to PrusaWebCam indicates that linux set up a symbolic link to the video0 device called PrusaWebCam.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;If you see a symbolic link for your camera:&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Congratulations! You are the golden child! Move on to step 4.&lt;/p&gt;

&lt;h3&gt;If you DON’T see a symbolic link for your camera:&lt;/h3&gt;

&lt;p&gt;Darn it! Something is wrong in &lt;code&gt;99-usb.rules&lt;/code&gt;.  Here are some things you can try:&lt;/p&gt;

&lt;h3&gt;Troubleshooting 1:&lt;/h3&gt;

&lt;p&gt;Before you start messing around with text editors, try the following: REBOOT AGAIN. This shouldn’t be a serious step, but it’s worked some than once for me.&lt;/p&gt;

&lt;h3&gt;Troubleshooting 2:&lt;/h3&gt;

&lt;p&gt;One of the main culprits of issues with udev rules is that some cameras don’t have valid serial numbers.&lt;/p&gt;

&lt;p&gt;For example, I bought a &lt;a href=&quot;https://amzn.to/2NhkBCg&quot;&gt;cheap USB endoscope on Amazon&lt;/a&gt; to test and connected it to my spare Raspberry PI with Octopi 0.18 installed. I tailed the messages log while I plugged the endoscope in and here’s a partial list of the output:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;Feb 11 20:04:22 octopi2 kernel: [ 2619.572078] usb 1-1.1.3: new high-speed USB device number 7 using dwc_otg
Feb 11 20:04:23 octopi2 kernel: [ 2619.783159] usb 1-1.1.3: New USB device found, idVendor=1908, idProduct=2311, bcdDevice= 1.00
Feb 11 20:04:23 octopi2 kernel: [ 2619.783177] usb 1-1.1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;code&gt;SerialNumber=0&lt;/code&gt; was suspicious to me, but I tried using it anyway in a second entry in my 99-usb.rules file, with &lt;code&gt;SYMLINK+=&quot;EndoCam&quot;&lt;/code&gt;. After a reboot, I didn’t find an EndoCam symbolic link under the &lt;code&gt;/dev&lt;/code&gt; directory. I rebooted several more times, still no luck.&lt;/p&gt;

&lt;p&gt;The fix was easy. I added the EndoCam entry without a serial number attribute. Here’s what my &lt;code&gt;99-usb.rules&lt;/code&gt; file looks like now with both cameras configured: &lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;SUBSYSTEM==&quot;video4linux&quot;, ATTRS{idVendor}==&quot;046d&quot;, ATTRS{idProduct}==&quot;081b&quot;, ATTRS{serial}==&quot;3A108F50&quot;, SYMLINK+=&quot;PrusaWebCam&quot;
SUBSYSTEM==&quot;video4linux&quot;, ATTRS{idVendor}==&quot;1908&quot;, ATTRS{idProduct}==&quot;2311&quot;, SYMLINK+=&quot;EndoCam&quot;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;After rebooting, I now saw two video symbolic links under &lt;code&gt;/dev&lt;/code&gt;.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;lrwxrwxrwx  1 root root           6 Feb 11 20:04 EndoCam -&amp;gt; video5
lrwxrwxrwx  1 root root           6 Feb 11 19:20 PrusaWebCam -&amp;gt; video0&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;Troubleshooting 3:&lt;/h3&gt;

&lt;p&gt;Recheck your &lt;code&gt;99-usb.rules&lt;/code&gt; file. Make sure the syntax is correct, that the serial number and vendor ID are correct, and that you don’t have any strange characters like “smart quotes” or anything else that isn’t a standard ASCII character. &lt;/p&gt;

&lt;h2&gt;4: Prepare octopi.txt file for new webcam:&lt;/h2&gt;

&lt;p&gt;Under &lt;code&gt;/boot&lt;/code&gt; there is an &lt;code&gt;octopi.txt&lt;/code&gt; file which is a configuration file for the &lt;code&gt;webcamd&lt;/code&gt; service (more on that service later). If you have your Raspberry PI camera running, then &lt;code&gt;octopi.txt&lt;/code&gt; is set up to configure your PI cam. We’ll copy that file and use it to configure our webcam.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; cd /boot
&amp;gt; sudo cp octopi.txt octopi2.txt
&amp;gt; sudo nano octopi2.txt&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;Edit &lt;strong&gt;octopi2.txt&lt;/strong&gt;:&lt;/h3&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Change the text &lt;code&gt;camera=&quot;raspi&quot;&lt;/code&gt; (or it might be &lt;code&gt;camera=&quot;auto&quot;&lt;/code&gt;) to &lt;code&gt;camera=&quot;usb&quot;.&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;The line might be commented out, indicated by a “#” (pound, or hash symbol) at the beginning of the line. Make sure to remove the # at the beginning of the line, otherwise changing the line to read &lt;code&gt;camera=&quot;usb&quot;&lt;/code&gt; will have no effect.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;NOTE: Some people have reported not seeing a “camera” entry at all in their octopi.txt file. If that’s the case, you’ll need to add one yourself.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Remove the &lt;code&gt;#&lt;/code&gt; from in front of the line that starts with &lt;code&gt;camera_usb_options&lt;/code&gt; to uncomment it. Currently, it should look something like &lt;code&gt;camera_usb_options=&quot;-r 640x480 -f 10&quot;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Change that line to point to your USB camera. You’ll do that by adding a &lt;code&gt;-d&lt;/code&gt; flag with the name you gave your USB camera. Here’s what my camera usb options looks like:&lt;br/&gt; &lt;code&gt;camera_usb&lt;em&gt;_&lt;/em&gt;options=&quot;-d /dev/PrusaWebCam -r 1280x720 -f 10&quot;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;NOTE: Be conservative with your resolution and framerate settings. A Logitech C920 can support 1920x1080 at 30 frames per second. However, your Raspberry PI can’t keep up with the camera, especially if it’s running a PI Cam module and Octoprint. So, I recommend setting USB cameras as 1280x720 and 10 fps.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;If your camera supports higher resolution you can experiment with changing the &lt;code&gt;-r&lt;/code&gt; setting (resolution) from &lt;code&gt;640x480&lt;/code&gt; to a different resolution, like I did in my example above. The &lt;code&gt;-f&lt;/code&gt; flag is for framerate.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Further down in &lt;code&gt;octopi2.txt&lt;/code&gt; you’ll need to comment out the line that starts with &lt;code&gt;camera_raspi_options&lt;/code&gt; by adding a &lt;code&gt;#&lt;/code&gt; in front of it.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Finally, remove the &lt;code&gt;#&lt;/code&gt; from in front of the line that starts with &lt;code&gt;camera_http_options&lt;/code&gt; to uncomment it (should be at the very end of the file) and change it to read &lt;code&gt;camera_http_options=&quot;-p 8081&quot;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;That sets the port for your webcam to 8081.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;You’re done with this file and can save and close it.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;Now let’s edit &lt;strong&gt;octopi.txt&lt;/strong&gt; (the config file for your Raspicam):&lt;/h3&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; sudo nano octopi.txt&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;To avoid the original &lt;code&gt;octopi.txt&lt;/code&gt; from starting up the wrong camera, let’s edit it as well and make sure &lt;code&gt;camera&lt;/code&gt; is set to &lt;code&gt;raspi&lt;/code&gt; and not &lt;code&gt;auto&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Find the &lt;code&gt;camera&lt;/code&gt; line and make sure it reads &lt;code&gt;camera=&quot;raspi&quot;&lt;/code&gt;instead of &lt;code&gt;auto&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;NOTE: As mentioned above, your octopi.txt file might not have a “camera” entry. If that’s the case for you, add one and set it to &lt;code&gt;camera=&quot;raspi&quot;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Set the port of the PI camera to 8080 by uncommenting the last line of the file, which should be &lt;code&gt;camera_http_options&lt;/code&gt; by deleting the &lt;code&gt;#&lt;/code&gt; in front of the line.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Make the line read &lt;code&gt;camera_http_options=&quot;-p 8080&quot;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Save and close the file&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;5: Prepare webcamd service files:&lt;/h2&gt;

&lt;p&gt;First we’ll duplicate the existing webcamd file.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; cd /root/bin
&amp;gt; sudo cp webcamd webcamd2&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;Now let’s edit &lt;strong&gt;webcamd&lt;/strong&gt;.&lt;/h3&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; sudo nano webcamd&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;&lt;li&gt;&lt;p&gt;Toward the top of the file, make sure the line that starts with &lt;code&gt;cfg_files+=&lt;/code&gt; points to &lt;code&gt;octopi.txt&lt;/code&gt;. It should read: &lt;code&gt;cfg_files+=/boot/octopi.txt&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Further down in the file, look for two lines that read:&lt;br/&gt;&lt;code&gt;# add video device into options&lt;/code&gt;&lt;br/&gt;&lt;code&gt;options=&quot;$options -d /dev/$device&quot;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Add a &lt;code&gt;#&lt;/code&gt; in front of the &lt;code&gt;options&lt;/code&gt; line to comment it out.&lt;br/&gt;&lt;code&gt;#options=&quot;$options -d /dev/$device&quot;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;That line only works when you have a single camera connected, otherwise it causes problems.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;We’ll make almost the same edits to &lt;strong&gt;webcamd2&lt;/strong&gt;.&lt;/h3&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; sudo nano webcamd2&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;&lt;li&gt;&lt;p&gt;Toward the top of the file, make sure the line that starts with &lt;code&gt;cfg_files+=&lt;/code&gt; points to &lt;code&gt;octopi2.txt&lt;/code&gt; (our second octopi configuration file). It should read: &lt;code&gt;cfg_files+=/boot/octopi2.txt&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Comment out the same &lt;code&gt;options&lt;/code&gt; line as you did in &lt;strong&gt;webcamd&lt;/strong&gt;.&lt;br/&gt;&lt;code&gt;#options=&quot;$options -d /dev/$device&quot;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;6: Set up service for webcamd2:&lt;/h2&gt;

&lt;p&gt;Now that we have our webcamd2 file ready, we need to create a service start file. We’ll copy an existing service file and edit it.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; cd /etc/systemd/system/
&amp;gt; sudo cp webcamd.service webcamd2.service
&amp;gt; sudo nano webcamd2.service&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;&lt;li&gt;&lt;p&gt;Change the &lt;code&gt;ExecStart&lt;/code&gt; line to read &lt;code&gt;ExecStart=/root/bin/webcamd2&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Save and close the file.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;Now let’s inform Linux about the webcamd2 service so it will get started at boot time:&lt;/h3&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; sudo systemctl enable webcamd2&lt;/code&gt;&lt;/pre&gt;


&lt;h2&gt;7: Set up camera proxy:&lt;/h2&gt;

&lt;p&gt;The final step for running a second webcam on Octopi, is to set up a proxy. The proxy links the internal webcamd2 camera service to an http port, allowing you (and Octoprint) to view the camera’s mpeg stream from a browser.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; cd /etc/haproxy
&amp;gt; sudo nano haproxy.cfg&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;&lt;li&gt;&lt;p&gt;Under the &lt;code&gt;frontend public&lt;/code&gt; heading add the following line:&lt;br/&gt;&lt;code&gt;use_backend webcam2 if { path_beg /webcam2/ }&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;There will already be an entry for &lt;code&gt;webcam&lt;/code&gt;. Copy the entire &lt;code&gt;backend webcam&lt;/code&gt; section and paste it below the first entry. We’ll make a couple of changes to have it point to the second webcam. It should look like this:&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;backend webcam2
        reqrep ^([^\ :]*)\ /webcam2/(.*)     \1\ /\2
        server webcam1  127.0.0.1:8081
        errorfile 503 /etc/haproxy/errors/503-no-webcam.http&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Notice a few things: &lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;regrep line changed to read &lt;code&gt;webcam2&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;server&lt;/code&gt; line port changed to 8081, the port we assigned the second camera in an earlier step.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;HOWEVER, the server name should remain &lt;code&gt;webcam1&lt;/code&gt;. That’s not a typo above. Tricksy Linux.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Here’s what the two &lt;code&gt;backend&lt;/code&gt; entries look like in my &lt;code&gt;haproxy.cfg&lt;/code&gt; file.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;backend webcam
        reqrep ^([^\ :]*)\ /webcam/(.*)     \1\ /\2
        server webcam1  127.0.0.1:8080
        errorfile 503 /etc/haproxy/errors/503-no-webcam.http

backend webcam2
        reqrep ^([^\ :]*)\ /webcam2/(.*)     \1\ /\2
        server webcam1  127.0.0.1:8081
        errorfile 503 /etc/haproxy/errors/503-no-webcam.http&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Now you can reboot and you should see output from your second camera by pointing a browser to port 8081 on your Octopi box. Example: I have Bonjour setup and called my Raspberry PI box “octopi”, so the URL for the second camera within my home network is: &lt;a href=&quot;http://octopi.local:8081/?action=stream&quot;&gt;http://octopi.local:8081/?action=stream&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don’t see your USB camera at port 8081, move on to step 8 for troubleshooting tips.&lt;/p&gt;

&lt;h2&gt;8: Troubleshooting Services&lt;/h2&gt;

&lt;p&gt;The most common issue after not seeing your camera listed under /dev is problems with the service that launches mjpg streamer for the USB camera.&lt;/p&gt;

&lt;p&gt;If you don’t see your USB webcam show up at port 8081, do you see it under /dev, then the service that starts up mjpg streamer is having a problem. To confirm this, run the following systemctl command: &lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&amp;gt; systemctl status webcamd2.service&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;If the service started up correctly, you’ll see something like this:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;● webcamd2.service - the OctoPi webcam daemon with the user specified config
   Loaded: loaded (/etc/systemd/system/webcamd2.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2021-02-27 15:16:51 PST; 9min ago
  Process: 340 ExecStart=/root/bin/webcamd2 (code=exited, status=0/SUCCESS)
 Main PID: 486 (mjpg_streamer)
    Tasks: 4 (limit: 1939)
   CGroup: /system.slice/webcamd2.service
           └─486 ./mjpg_streamer -o output_http.so -w ./www-octopi -p 8081 -i input_uvc.so -d /dev/LogiCam -r 640x480 -f 5

Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: Format............: JPEG
Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: TV-Norm...........: DEFAULT
Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: www-folder-path......: ./www-octopi/
Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: HTTP TCP port........: 8081
Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: HTTP Listen Address..: (null)
Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: username:password....: disabled
Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: commands.............: enabled
Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: starting input plugin input_uvc.so
Feb 27 15:16:50 octopi2 mjpg_streamer[486]: MJPG-streamer [486]: starting output plugin: output_http.so (ID: 00)
Feb 27 15:16:51 octopi2 systemd[1]: Started the OctoPi webcam daemon with the user specified config.&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;However, if the service failed to start up correctly, you’ll see something like this:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;● webcamd2.service - the OctoPi webcam daemon with the user specified config
   Loaded: loaded (/etc/systemd/system/webcamd2.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Sat 2021-02-27 15:28:51 PST; 1min 35s ago
  Process: 350 ExecStart=/root/bin/webcamd2 (code=exited, status=0/SUCCESS)

Feb 27 15:28:50 octopi2 mjpg_streamer[484]: MJPG-streamer [484]: starting application
Feb 27 15:28:50 octopi2 mjpg_streamer[484]: MJPG-streamer [484]: MJPG Streamer Version: git rev: 5554f42c352ecfa7edaec6fc51e507afce605a34
Feb 27 15:28:50 octopi2 mjpg_streamer[484]: MJPG-streamer [484]: Using V4L2 device.: /dev/video3
Feb 27 15:28:50 octopi2 mjpg_streamer[484]: MJPG-streamer [484]: Desired Resolution: 640 x 480
Feb 27 15:28:50 octopi2 mjpg_streamer[484]: MJPG-streamer [484]: Frames Per Second.: 5
Feb 27 15:28:50 octopi2 mjpg_streamer[484]: MJPG-streamer [484]: Format............: JPEG
Feb 27 15:28:50 octopi2 mjpg_streamer[484]: MJPG-streamer [484]: TV-Norm...........: DEFAULT
Feb 27 15:28:50 octopi2 mjpg_streamer[484]: MJPG-streamer [484]: init_VideoIn failed&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Notice the last line. It reads &lt;code&gt;init_VideoIn failed&lt;/code&gt;. AND THIS IS WITH THE SAME CAMERA WITH THE SAME SETTINGS.&lt;/p&gt;

&lt;h3&gt;Troubleshooting Tip 1:&lt;/h3&gt;

&lt;p&gt;Reduce the resolution and frame rate of both your PI Camera and your USB webcam. &lt;/p&gt;

&lt;p&gt;Your Raspberry PI is amazing, but it still must obey the laws of physics, and you just might be asking it to do too much. Remember, your PI is running Linux, Octoprint and two video streaming services.&lt;/p&gt;

&lt;p&gt;Here are the settings for my PI Cam and Logitech C510 in octopi.txt and octopi2.txt, respectively:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// octopi.txt -- raspi cam settings
camera_raspi_options=&quot;-x 1280 -y 720 -fps 10&quot;

// octopi2.txt -- USB cam settings
camera_usb_options=&quot;-d /dev/PrusaWebCam -r 1280x720 -f 10&quot;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Both cameras support resolutions of 1920x1080 and frame rates of 30fps, but setting the cameras to their max values caused the cameras not to start up. Sometimes I’d get one, or the other, but never both at the same time.&lt;/p&gt;

&lt;p&gt;NOTE: Don’t set your frame rate to less than 5. While testing, I set my USB camera to &lt;code&gt;-f 1&lt;/code&gt; and discovered in the logs that the value was being pushed up (or “coerced” in video4linux speak) to 5. Seems like Linux doesn’t like frame rates that low.&lt;/p&gt;

&lt;h3&gt;Troubleshooting Tip 2:&lt;/h3&gt;

&lt;p&gt;Switch the camera to another USB port.&lt;/p&gt;

&lt;p&gt;This shouldn’t matter, but apparently it can make a difference. Follow this procedure:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;p&gt;Boot your PI, confirm that the service didn’t load properly.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Move the USB camera to another port while the PI is still on.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Reboot your PI.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Check the service status.&lt;/p&gt;

&lt;/li&gt;&lt;/ol&gt;

&lt;h3&gt;Troubleshooting Tip 3:&lt;/h3&gt;

&lt;p&gt;Change the service’s restart delay.&lt;/p&gt;

&lt;p&gt;By editing webcamd2.service you can change the delay before the service controller tries to restart a failing service.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;sudo nano /etc/systemd/system/webcamd2.service&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Change the RestartSec setting to 3, instead of 1, which is the default.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;RestartSec=3&lt;/code&gt;&lt;/pre&gt;

&lt;hr&gt;

&lt;h3&gt;UPDATE February 27, 2021:&lt;/h3&gt;

&lt;p&gt;Added new services troubleshooting section, and updated the camera configuration section with comments about limiting resolution and frame rates.&lt;/p&gt;

&lt;h3&gt;UPDATE February 11, 2021:&lt;/h3&gt;

&lt;p&gt;Added a new troubleshooting section with information about confirming the camera set up and configuring cameras without serial numbers.&lt;/p&gt;

&lt;h3&gt;UPDATE February 7, 2021:&lt;/h3&gt;

&lt;h3&gt;TL;DR:&lt;/h3&gt;

&lt;p&gt;Because of issues with HTML and Unicode, the code fragments in the instructions below had curly quotes (“) instead of straight quotes (&quot;). Anyone that copied text off this page was unknowingly pasting in curly quotes that caused the Linux configuration files to not work. I’ve gone through and updated all the code sections and confirmed that everything works in Octopi 0.18. &lt;/p&gt;

&lt;h3&gt;The full story (for those who are curious):&lt;/h3&gt;

&lt;p&gt;A couple of weeks ago this post started getting a flurry of comments and questions, seemingly related to the instructions below not working when users updated to Octopi 0.18. The most common complaint was that only one camera (typically the PI cam) would work, while the USB camera didn’t connect.&lt;/p&gt;

&lt;p&gt;To investigate why Octopi 0.18 didn’t work as expected, I took a spare Raspberry PI and installed a fresh copy of Octopi 0.18. Octoprint 1.5.2 worked correctly, as did a spare Raspberry PI camera module I have.&lt;/p&gt;

&lt;p&gt;I followed my own instructions to connect a spare USB camera — I apparently have a lot of spare parts — and it didn’t work. The webcamd2 service I had created tried over and over to connect to the USB camera but failed. For a couple of hours I went down various rabbit holes, reading through comments, trying various approaches and learning more about the vagaries of Linux configuration. At one point, I even compared configuration files from Octopi 0.17 and 0.18, looking for a bug.&lt;/p&gt;

&lt;p&gt;After ruling out issues with all the other configuration files I had created or edited, I was left with just one: the 99-usb.rules file. That’s how you tell the USB system about your USB camera and set up a symlink/alias to the camera. The alias/symlink is supposed to show up under &lt;code&gt;/dev&lt;/code&gt; with whatever name you gave in your rules file. I had called my USB camera TestCam, but there was no entry under &lt;code&gt;/dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I checked my working Octopi 0.17 build and sure enough, I saw a symlinked entry under the /dev directory. When I compared the two 99-usb.rules files from my Octopi 0.17 and 0.18 installations, I saw what was going on. The Octopi 0.18 rules files had curly quotes (“) instead of standard straight quotes (&quot;). Curly quotes — also known as “smart” quotes — are fancy quotes used in word processors and webpages, but they don’t belong in text-only Linux configuration files. Putting curly quotes in configuration files is like putting diesel in a gasoline engine. It don’t work.&lt;/p&gt;

&lt;p&gt;The only text I had copied and pasted from this blog entry had been for the usb rules file. And, when I checked, I saw that the usb rules text in the post had curly quotes in it. Once I edited &lt;code&gt;99-usb.rules&lt;/code&gt;, replaced the stupid smart quotes with regular ASCII straight quotes and rebooted, the USB camera showed up under &lt;code&gt;/dev&lt;/code&gt;, webcam2 service was able to find it and start up, and the camera worked correctly. I then went through all the code sections in this blog post and ensured that none contained curly quotes.&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Recent 3D Designs Posted to Thingiverse</title>
    <link>https://hatoum.com/blog/2019/2/25/recent-3d-designs-posted-to-thingiverse/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2019/2/25/recent-3d-designs-posted-to-thingiverse/</guid>
    <pubDate>Mon, 25 Feb 2019 16:59:59 -0800</pubDate>
    <description>&lt;p&gt;In May of 2018, my wife, dog and I moved to Los Angeles from New York City. In the process, I purchased new furniture for my home office. Almost all the furniture in my home comes from IKEA because I’m a big fan of the hackability of their products.&lt;/p&gt;

&lt;p&gt;Around the same time as I received my furniture I had also gotten a new 3D printer — a Prusa MK3 — and put it immediately to use.&lt;/p&gt;

&lt;p&gt;What follows is a collection of my recent 3D designs which, except for one, have to do with altering, improving or repairing an IKEA product. They are all available on Thingiverse.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.thingiverse.com/thing:3003134&quot;&gt;&lt;strong&gt;IKEA Veberod Shelf and Drawer Clips:&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I own a pair of IKEA Veberöd (Veberod) shelves, which I really like. The frames are made out of steel square tubing and the shelves and drawers are made of finished plywood.&lt;/p&gt;

&lt;p&gt;My only complaint about the shelves is that they don&#x27;t have stops for the drawers. They ride on steel runners which are open on both ends. Unless I carefully positioned each drawer, they didn&#x27;t sit flush with the frame which really caused my OCD to flare up.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.thingiverse.com/thing:3003134&quot;&gt;The clips in this Thing&lt;/a&gt; attach to the steel frame behind every drawer and provide a satisfying stop by way of little protrusions or wings, keeping all the drawers aligned and allowing me to sleep at night.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/01-img-7284.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/01-img-7284.webp&quot; alt=&quot;&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://www.thingiverse.com/thing:3076931&quot;&gt;&lt;strong&gt;IKEA PS Metal Cabinet replacement foot insert:&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I moved, one of the pieces of furniture I brought with me was an IKEA PS metal cabinet.&lt;/p&gt;

&lt;p&gt;During the move, some of the plastic foot inserts at the tip of the legs had gotten lost or damaged,&lt;a href=&quot;https://www.thingiverse.com/thing:3076931&quot;&gt; so I designed a new one &lt;/a&gt;and printed 4 out in blue PETG.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/02-1d74035d3ec77e7fd52f6d6b15c0e084-preview.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/02-1d74035d3ec77e7fd52f6d6b15c0e084-preview.webp&quot; alt=&quot;&quot; width=&quot;628&quot; height=&quot;472&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://www.thingiverse.com/thing:3419785&quot;&gt;&lt;strong&gt;IKEA Lixhult Air Hole Grommets:&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I bought a Lixhult metal cabinet from IKEA and wanted to place backup hard drives inside the cabinet. In order to ensure proper cooling of the drives, I needed to make some air holes in the front of the cabinet. &lt;a href=&quot;https://www.thingiverse.com/thing:3419785&quot;&gt;These air hole grommets&lt;/a&gt; fit over the holes I made in the cabinet sheet metal, allow airflow, but hide the sharp edges around the holes.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/03-img-7371.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/03-img-7371.webp&quot; alt=&quot;&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://www.thingiverse.com/thing:3437659&quot;&gt;&lt;strong&gt;IOGEAR USB Switch Wall Mount:&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a &lt;a href=&quot;https://www.thingiverse.com/thing:3437659&quot;&gt;simple wall mount for an IOGear USB Switch&lt;/a&gt; (Model GUS434). It has screw holes for flush-mounting the USB switch to a flat surface like a wall. I used double-sided tape to attach it to the wall behind my desk.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/04-img-8619.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/04-img-8619.webp&quot; alt=&quot;&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://www.thingiverse.com/thing:3453426&quot;&gt;&lt;strong&gt;IKEA Sinnerling Lamp shade replacement:&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a r&lt;a href=&quot;https://www.thingiverse.com/thing:3453426&quot;&gt;eplacement shade in two parts for IKEA&#x27;s Sinnerling lamp&lt;/a&gt;. The lamps have a cork base with a large, fairly heavy, frosted glass shade that sits over the cork base.&lt;/p&gt;

&lt;p&gt;I bought 2 Sinnerling lamps from Ikea and had them delivered to my house. Unfortunately, I had a lot of problems receiving the lamps unbroken. I tried ordering the lamps several times, but was only successful in receiving one unbroken lamp. IKEA was very good about getting me refunds and re-ordering the lamps. On the final delivery attempt, I received one good lamp and one broken lamp. Since the base and electrical wiring of the lamp was fine, I carefully brushed off the broken glass, kept it and designed this Thing as a replacement shade. The last picture is of an undamaged, original IKEA Sinnerling lamp showing its glass shade.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/05-img-8688.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2019/recent-3d-designs-posted-to-thingiverse/05-img-8688.webp&quot; alt=&quot;&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;
</description>
  </item>
  <item>
    <title>Thing added to the verse of Thingiverse</title>
    <link>https://hatoum.com/blog/2018/2/18/thing-added-to-the-verse-of-thingiverse/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2018/2/18/thing-added-to-the-verse-of-thingiverse/</guid>
    <pubDate>Sun, 18 Feb 2018 15:30:26 -0800</pubDate>
    <description>&lt;p&gt;Today I added a design to &lt;a href=&quot;https://www.thingiverse.com/thing:2798677&quot;&gt;Thingiverse&lt;/a&gt; for a camera mount system for 3D printers, based on another design. I did all the redesigning and additions in &lt;a href=&quot;https://tinkercad.com&quot;&gt;Tinkercad&lt;/a&gt;, which I appreciate more every time I use it.&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href=&quot;https://www.thingiverse.com/thing:2798677&quot;&gt;https://www.thingiverse.com/thing:2798677&lt;/a&gt;&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Don&#x27;t use SketchUp for 3D-printed designs</title>
    <link>https://hatoum.com/blog/2018/2/6/dont-use-sketchup-for-3d-printed-designs/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2018/2/6/dont-use-sketchup-for-3d-printed-designs/</guid>
    <pubDate>Tue, 06 Feb 2018 18:49:26 -0800</pubDate>
    <description>&lt;h2&gt;TL;DR:&lt;/h2&gt;

&lt;p&gt;SketchUp is great in many ways, especially for creating architectural and construction models. However, while the objects that it creates look solid, many are not. That&#x27;s not a problem if all you&#x27;re doing is showing a client a design or creating an animation -- but it&#x27;s a huge problem if your intention is to print your model in 3D.&lt;/p&gt;

&lt;p&gt;Unfortunately, for all its design prowess, &lt;a href=&quot;https://www.sketchup.com/&quot;&gt;SketchUp&lt;/a&gt; produces faulty, unprintable STL files (the most common file type used by 3D printers). Some slicers (programs used to generate special 3D-printable gcode files) will not complain about SketchUp files, though many will, including Simplify3D.&lt;/p&gt;

&lt;p&gt;Don&#x27;t use SketchUp for designing objects you expect to 3D print. Better choices are the amazing Tinkercad (an online and free tool) or the hardcore Fusion 360 (free to many).&lt;/p&gt;

&lt;h2&gt;SketchUp is great (for some things):&lt;/h2&gt;

&lt;p&gt;I love &lt;a href=&quot;https://www.sketchup.com/&quot;&gt;SketchUp&lt;/a&gt;. I used it for many years to help me visualize DIY designs. It&#x27;s easy to use and when it first came out (and Google eventually bought it), it was way ahead of its time. The way that it let you extrude surfaces and position objects in 3D space was really revolutionary.&lt;/p&gt;

&lt;p&gt;And it&#x27;s still great today, but only if you intend to display your designs on screens or on paper. Unfortunately, for all its design prowess, SketchUp produces faulty, unprintable STL files (the most common file type used by 3D printers).&lt;/p&gt;

&lt;p&gt;The two images below illustrate the problem I&#x27;m talking about. Both images are screenshots from Simplify3D, an excellent and popular slicer. A slicer is a program that takes STL files and converts them into gcode files for a specific 3D printer. Gcode files contain instructions that tell a 3D printer how to print an object (coordinates, speeds, amount of material, etc).&lt;/p&gt;

&lt;p&gt;Slicers also allow you to visualize the layers of a 3D print. The first image below is a screenshot from the layer visualization panel in &lt;a href=&quot;https://simplify3d.com&quot;&gt;Simplify3D&lt;/a&gt;, a fantastic, if pricey, slicing program. The visualization is of a 3D model which was edited in SketchUp to shorten one of its parts and then output as an STL file. You&#x27;ll notice right away that something looks very wrong. There are holes in some surfaces, surfaces that jut out at strange angles and areas which should be voids are filled in. What you&#x27;re seeing is an unprintable 3D model. SketchUp created 3D geometry that looks great on screen, but which can&#x27;t be replicated as a physical object.&lt;/p&gt;

&lt;p&gt;The second image is of the same original source model edited in &lt;a href=&quot;https://tinkercad.com&quot;&gt;Tinkercad&lt;/a&gt; (a really great and free online CAD tool), output as an STL file and then visualized in Simplify3D. Even if you&#x27;re not an expert in CAD or 3D printing, it&#x27;s easy to spot the differences between the good model and the bad model.&lt;/p&gt;

&lt;div class=&quot;gallery&quot;&gt;&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/01-screen-shot-2018-02-05-at-14-16-48.webp&quot; data-caption=&quot;Bad model, bad! — STL model output from SketchUp. Notice all malformed surfaces. (Simplify3D screenshot)&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/01-screen-shot-2018-02-05-at-14-16-48.webp&quot; alt=&quot;Bad model, bad!&quot; width=&quot;1600&quot; height=&quot;1176&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Bad model, bad! — STL model output from SketchUp. Notice all malformed surfaces. (Simplify3D screenshot)&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/02-screen-shot-2018-02-05-at-14-16-48.webp&quot; data-caption=&quot;Bad model, bad! — STL model output from SketchUp. Notice all malformed surfaces. (Simplify3D screenshot)&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/02-screen-shot-2018-02-05-at-14-16-48.webp&quot; alt=&quot;Bad model, bad!&quot; width=&quot;1600&quot; height=&quot;1176&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Bad model, bad! — STL model output from SketchUp. Notice all malformed surfaces. (Simplify3D screenshot)&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/03-screen-shot-2018-02-05-at-14-17-16.webp&quot; data-caption=&quot;You&amp;#x27;re a mess — Close of the same Simplify3D visualization.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/03-screen-shot-2018-02-05-at-14-17-16.webp&quot; alt=&quot;You&amp;#x27;re a mess&quot; width=&quot;1600&quot; height=&quot;1176&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;You&amp;#x27;re a mess — Close of the same Simplify3D visualization.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/04-screen-shot-2018-02-05-at-14-17-16.webp&quot; data-caption=&quot;You&amp;#x27;re a mess — Close of the same Simplify3D visualization.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/04-screen-shot-2018-02-05-at-14-17-16.webp&quot; alt=&quot;You&amp;#x27;re a mess&quot; width=&quot;1600&quot; height=&quot;1176&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;You&amp;#x27;re a mess — Close of the same Simplify3D visualization.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/05-screen-shot-2018-02-06-at-19-51-08.webp&quot; data-caption=&quot;Who&amp;#x27;s a good model? — This model was created by editing the same source model, but in Tinkercad rather than SketchUp. (Simplify3D screenshot)&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/05-screen-shot-2018-02-06-at-19-51-08.webp&quot; alt=&quot;Who&amp;#x27;s a good model?&quot; width=&quot;1600&quot; height=&quot;1176&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Who&amp;#x27;s a good model? — This model was created by editing the same source model, but in Tinkercad rather than SketchUp. (Simplify3D screenshot)&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/06-screen-shot-2018-02-06-at-19-51-08.webp&quot; data-caption=&quot;Who&amp;#x27;s a good model? — This model was created by editing the same source model, but in Tinkercad rather than SketchUp. (Simplify3D screenshot)&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2018/dont-use-sketchup-for-3d-printed-designs/06-screen-shot-2018-02-06-at-19-51-08.webp&quot; alt=&quot;Who&amp;#x27;s a good model?&quot; width=&quot;1600&quot; height=&quot;1176&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Who&amp;#x27;s a good model? — This model was created by editing the same source model, but in Tinkercad rather than SketchUp. (Simplify3D screenshot)&lt;/figcaption&gt;&lt;/figure&gt;

&lt;/div&gt;

&lt;p&gt;What&#x27;s worse is that SketchUp doesn&#x27;t give the user any clue that something is wrong, nor does it provide any tools to repair faulty geometry. In fact, most people who use SketchUp to design 3D objects are unaware that there are problems with the models they are exporting. They will swear to you that it worked fine in their slicer. That&#x27;s because some slicers, such as &lt;a href=&quot;https://ultimaker.com/en/products/ultimaker-cura-software&quot;&gt;Cura&lt;/a&gt;, hide geometry problems in an attempt, I think, to be more user friendly. The problem is that the practice doesn&#x27;t guarantee a good print and further compounds users&#x27; confusion.&lt;/p&gt;

&lt;p&gt;That&#x27;s what happened to me. I used SketchUp to design &lt;a href=&quot;https://www.thingiverse.com/thing:2740259&quot;&gt;footrests for my Herman Miller Mirra chair&lt;/a&gt;. When it came time to print my models on my &lt;a href=&quot;http://amzn.to/2BfCUzR&quot;&gt;Monoprice Select Mini v2 3D printer&lt;/a&gt;, I experienced all kinds of problems. Since I was new to 3D printers, I assumed that either the printer was faulty or I was using it incorrectly. Later, when I switched from Cura to Simplify3D for slicing my models, I noticed that the geometry of the footrests was broken. I&#x27;m amazed they printed at all.&lt;/p&gt;

&lt;p&gt;Rather than spend time redesigning the footrests in Fusion 360 (a high-end and free to many CAD program), I ran my broken STL files through the free &lt;a href=&quot;https://web.archive.org/web/20190109090710/https://service.netfabb.com/login.php&quot;&gt;Netfabb Online Service&lt;/a&gt; which repairs 3D meshes. My models finally printed correctly, but if I want to continue refining my designs I have no choice but to painstakingly port the work over to another CAD program.&lt;/p&gt;

&lt;p&gt;From that moment on I started learning Fusion 360 and use Tinkercad. &lt;/p&gt;
</description>
  </item>
  <item>
    <title>[UPDATED][DEPRECATED] Simplify3D: Confusing First Layer settings</title>
    <link>https://hatoum.com/blog/2018/1/2/simplify3d-confusing-first-layer-settings/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2018/1/2/simplify3d-confusing-first-layer-settings/</guid>
    <pubDate>Tue, 02 Jan 2018 14:23:01 -0800</pubDate>
    <description>&lt;h2&gt;UPDATE:&lt;/h2&gt;

&lt;p&gt;Has has been pointed out, while this blog post was accurate many years ago, it no longer applies.&lt;/p&gt;

&lt;h2&gt;First Layer Height and Width:&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://simplify3d.com&quot;&gt;Simplify3D 4.0&lt;/a&gt; is a powerful 3D mesh slicer program for 3D printing with many options and settings, some of which are non-obvious. Such is the case with the First Layer Settings, under a process&#x27; Layer tab. Until I happened upon a post in Simplify3D&#x27;s forums I didn&#x27;t understand the effects of changing the First Layer Height and First Layer Width settings, causing me a lot of frustration and failed first layers.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2018/simplify3d-confusing-first-layer-settings/01-screen-shot-2018-01-02-at-17-07-28.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2018/simplify3d-confusing-first-layer-settings/01-screen-shot-2018-01-02-at-17-07-28.webp&quot; alt=&quot;&quot; width=&quot;947&quot; height=&quot;419&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;h2&gt;First Layer Height:&lt;/h2&gt;

&lt;p&gt;Both nozzle height and extrusion amount can be affected by this setting, but perhaps not in the way you think.&lt;/p&gt;

&lt;p&gt;If set &lt;em&gt;below&lt;/em&gt; 100%:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Amount of extruded plastic&lt;/strong&gt; is &lt;strong&gt;UNCHANGED&lt;/strong&gt;.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Layer height&lt;/strong&gt; (distance from nozzle to printing bed) is &lt;strong&gt;REDUCED&lt;/strong&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;Values below 100% &lt;strong&gt;ONLY&lt;/strong&gt; lower the nozzle closer to the printing surface. Essentially squishes the standard amount of plastic into a lower layer height.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;This is meant to help with adhesion.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;if set &lt;em&gt;above&lt;/em&gt; 100%:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Amount of extruded plastic &lt;/strong&gt;is&lt;strong&gt; INCREASED.&lt;/strong&gt;&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Layer height&lt;/strong&gt; is &lt;strong&gt;INCREASED&lt;/strong&gt;.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;BOTH&lt;/strong&gt; extrudes more plastic &lt;strong&gt;AND&lt;/strong&gt; pulls the nozzle slightly away from bed so as not to squish the layer.&lt;/p&gt;

&lt;/li&gt;&lt;li&gt;&lt;p&gt;This is used primarily when printing fine layer heights and/or on slightly uneven printing beds. The extra height and plastic volume makes thin layers thicker and also helps smooth out bumps and inconsistencies in bed surfaces.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;First Layer Width:&lt;/h2&gt;

&lt;p&gt;Width changes ALWAYS AFFECT extrusion amounts, but leave Layer Height UNCHANGED.&lt;/p&gt;

&lt;p&gt;If set below 100%:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;The &lt;strong&gt;amount of extruded plastic&lt;/strong&gt; is &lt;strong&gt;REDUCED&lt;/strong&gt;.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;If set above 100%:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;The &lt;strong&gt;amount of extruded plastic&lt;/strong&gt; is &lt;strong&gt;INCREASED&lt;/strong&gt;.&lt;/p&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;For reference, here&#x27;s the full thread in Simplify3D&#x27;s forums: &lt;a href=&quot;https://forum.simplify3d.com/viewtopic.php?f=9&amp;amp;t=2292&amp;amp;start=20#p18419&quot;&gt;https://forum.simplify3d.com/viewtopic.php?f=9&amp;amp;t=2292&amp;amp;start=20#p18419&lt;/a&gt;&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Using Regular Expressions to change case</title>
    <link>https://hatoum.com/blog/2017/12/6/using-regular-expressions-to-change-case/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2017/12/6/using-regular-expressions-to-change-case/</guid>
    <pubDate>Wed, 06 Dec 2017 06:12:53 -0800</pubDate>
    <description>&lt;p&gt;You can change the case of text with Regular Expressions in some applications and programming languages by placing control strings in the replacement expression indicating the type of conversion you want.&lt;/p&gt;
&lt;p&gt;NOTE: The following examples were tested in &lt;a href=&quot;https://www.barebones.com/products/bbedit/&quot;&gt;BBEdit&lt;/a&gt; which has a great grep search/replace functionality and which uses &lt;code&gt;\&lt;/code&gt; to indicate capture groups rather than &lt;code&gt;$&lt;/code&gt; as is common in other RegEx implementations.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;\U&lt;/code&gt;: Start converting all letters to uppercase. Ex:&lt;ul&gt;&lt;li&gt;Source text: &lt;code&gt;Hello World&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Selection RegEx: &lt;code&gt;(Hello) World&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Replacement: &lt;code&gt;\U\1 World&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Final value: HELLO WORLD&lt;/li&gt;&lt;li&gt;Comments: Notice &lt;code&gt;\U&lt;/code&gt; starts uppercase conversion and affects all text following it, regardless of the capture group.&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;li&gt;&lt;code&gt;\L&lt;/code&gt;: Start converting all letters to lowercase. Ex:&lt;ul&gt;&lt;li&gt;Source text: &lt;code&gt;Hello World&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Selection RegEx: &lt;code&gt;Hello World&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Replacement: &lt;code&gt;\LHello World&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Final value: &lt;code&gt;hello world&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Comments: With or Without capture groups, the case control string &lt;code&gt;\L&lt;/code&gt; affects all text that follows it. &lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;li&gt;&lt;code&gt;\E&lt;/code&gt;: End most recent conversion setting. Only necessary if you&#x27;re not using additional control strings to change text case, but wish to stop the initial conversion at some point before the end of the replacement string.&lt;ul&gt;&lt;li&gt;Example 1:&lt;ul&gt;&lt;li&gt;Source text: &lt;code&gt;hEllo FuNnY WorlD&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Selection RegEx: &lt;code&gt;([a-zA-Z]*) ([a-zA-Z]*) ([a-zA-Z]*)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Replacement: &lt;code&gt;\U\1 \2 \3&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Final value: &lt;code&gt;HELLO FUNNY WORLD&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Comments: The initial &lt;code&gt;\U&lt;/code&gt; control string converts all characters that follow uppercase.&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;li&gt;Example 2:&lt;ul&gt;&lt;li&gt;Source text: &lt;code&gt;hEllo FuNnY WorlD&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Selection RegEx: &lt;code&gt;([a-zA-Z]*) ([a-zA-Z]*) ([a-zA-Z]*)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Replacement: &lt;code&gt;\U\1 \L\2 \U\3&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Final value: &lt;code&gt;HELLO funny WORLD&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Comments: We set a conversion control character before each capture group, resetting the conversion that takes place.&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;li&gt;Example 3:&lt;ul&gt;&lt;li&gt;Source text: &lt;code&gt;hEllo FuNnY WorlD&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Selection RegEx: &lt;code&gt;([a-zA-Z]*) ([a-zA-Z]*) ([a-zA-Z]*)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Replacement: &lt;code&gt;\U\1\E \2 \3&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Final value: &lt;code&gt;HELLO FuNnY WorlD&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Comments: A &lt;code&gt;\E&lt;/code&gt; control string is used after the initial &lt;code&gt;\U\1&lt;/code&gt; (which converts the first capture group to all caps). &lt;code&gt;\E&lt;/code&gt; ends the uppercase conversion, leaving capture groups 2 and 3 unaffected by the initial &lt;code&gt;\U&lt;/code&gt;. &lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;More complete info at: &lt;a href=&quot;https://www.regular-expressions.info/replacecase.html&quot;&gt;https://www.regular-expressions.info/replacecase.html&lt;/a&gt;&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Repair Video: MacBook Pro 15, Late 2013 Battery Replacement</title>
    <link>https://hatoum.com/blog/2017/8/20/repair-video-macbook-pro-15-late-2013-battery-replacement/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2017/8/20/repair-video-macbook-pro-15-late-2013-battery-replacement/</guid>
    <pubDate>Sun, 20 Aug 2017 14:33:46 -0700</pubDate>
    <description>&lt;p&gt;For the last 10 years, or so, along with my friend &lt;a href=&quot;https://marfla.com/familias/fiesta-kyla/attachment/image-95/&quot;&gt;Flavio&lt;/a&gt; I&#x27;ve been recording a popular Spanish-language podcast called &lt;a href=&quot;https://puromac.com&quot;&gt;Puromac&lt;/a&gt;, about all things Apple. We also have a &lt;a href=&quot;https://youtube.com/puromac&quot;&gt;YouTube channel&lt;/a&gt; which, up until recently, only had videos in Spanish. Well, I recently replaced the battery of my MacBook Pro using an iFixIt kit and made two videos about the experience: one in English and the other in Spanish. Below is the English version for your viewing pleasure:&lt;/p&gt;

&lt;figure class=&quot;video&quot;&gt;&lt;a class=&quot;yt&quot; href=&quot;https://www.youtube.com/watch?v=rfHHIERH2J0&quot; data-yt=&quot;rfHHIERH2J0&quot; data-title=&quot;Repair: MacBook Pro 15, Late 2013 Battery Replacement [ENGLISH]&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/video/rfHHIERH2J0.webp&quot; alt=&quot;&quot; width=&quot;960&quot; height=&quot;540&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;yt-play&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Play video: Repair: MacBook Pro 15, Late 2013 Battery Replacement [ENGLISH]&lt;/span&gt;&lt;/a&gt;&lt;/figure&gt;
</description>
  </item>
  <item>
    <title>Repair: Bad Electrolytic Capacitor Strikes Again, This Time In A Refrigerator Control Unit</title>
    <link>https://hatoum.com/blog/2017/8/7/refrigerator-repair-bad-electrolytic-capacitor-strikes-again/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2017/8/7/refrigerator-repair-bad-electrolytic-capacitor-strikes-again/</guid>
    <pubDate>Sun, 13 Aug 2017 15:04:17 -0700</pubDate>
    <description>&lt;h2&gt;TLDR;&lt;/h2&gt;

&lt;p&gt;My Kitchen Aid model KBLC36FMS02 built-in refrigerator had been making odd sounds for a few weeks and then one day stopped cooling. I pulled the fridge out of its niche and eventually pulled out the control board on top of condenser coil. When I Googled some of the numbers on the PCB (ex: &quot;W10219463 control board fix&quot;), I came across the blog of &lt;a href=&quot;https://www.stevejenkins.com/blog/2014/03/how-to-fix-a-whirlpool-kitchenaid-w10219463-2307028-control-board-for-6/&quot;&gt;Steve Jenkins&lt;/a&gt;, who had an excellent post on the control board issue with all the information I needed to repair it. The problem with my control board came down to a faulty 220uf electrolytic capacitor. And as I learned from my friend &lt;a href=&quot;https://josh.com&quot;&gt;Josh&lt;/a&gt; when I repaired a &lt;a href=&quot;https://hatoum.com/blog/2015/11/17/repair-20-year-old-coffee-maker/&quot;&gt;30-year old coffee maker&lt;/a&gt;, electrolytic capacitors always go bad.&lt;/p&gt;

&lt;h2&gt;Details&lt;/h2&gt;

&lt;p&gt;When my refrigerator, a Kitchen Aid model KBLC36FMS02 started making odd sounds, I ignored it. A few weeks later, when it stopped cooling, I couldn&#x27;t ignore it.&lt;/p&gt;

&lt;p&gt;My first thought was that the compressor had a leaked coolant and no longer worked. I pulled the refrigerator out of its niche and took apart the enclosure on top of the fridge which housed the compressor and condenser coil.&lt;/p&gt;

&lt;p&gt;Before taking apart the top housing, I had unplugged the refrigerator. Since I didn&#x27;t see anything obviously wrong with the compressor, I plugged the fridge back in to see if that might reset the temperature sensors. The compressor started up and I saw frost appear on the output tube, so I guessed that the compressor was working correctly.&lt;/p&gt;

&lt;p&gt;Next I took a look at the condenser coils. I thought that maybe the refrigerator had turned itself off because, if the coils were sufficiently dirty, the fridge couldn&#x27;t release heat. The coils &lt;em&gt;were&lt;/em&gt; filthy, having never been cleaned in the 10 years since the fridge had been in operation.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2017/refrigerator-repair-bad-electrolytic-capacitor/01-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2017/refrigerator-repair-bad-electrolytic-capacitor/01-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;Dirty condenser coils&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;I cleaned out the coils and started up the fridge again, but it was clear after a few minutes that it still wasn&#x27;t cooling. That&#x27;s when I noticed that the condenser coil fan wasn&#x27;t spinning. So, my next guess as to what was wrong with the fridge was that the control board, which I could see above the condenser coils, had a problem with it. I removed the board and took a look at it.&lt;/p&gt;

&lt;p&gt;From my experience fixing a &lt;a href=&quot;https://hatoum.com/blog/2015/11/17/repair-20-year-old-coffee-maker/&quot;&gt;30-year old coffee maker&lt;/a&gt; I learned that electrolytic capacitors often go bad. However, the capacitors on the board didn&#x27;t look damaged or have any discharge like the ones I replaced in my old coffee maker.&lt;/p&gt;

&lt;p&gt;I Googled the numbers on the PCB of the control board, hoping to find if I could find a replacement board and how much it would cost. Ebay had several services that would either sell you a new board ($850!!) or repair existing boards ($70-$200).&lt;/p&gt;

&lt;p&gt;Then I came across &lt;a href=&quot;https://www.stevejenkins.com/blog/2014/03/how-to-fix-a-whirlpool-kitchenaid-w10219463-2307028-control-board-for-6/&quot;&gt;Steve Jenkins&lt;/a&gt;&#x27; blog which had a post about the very control unit I was researching. Steve&#x27;s post is excellent, with lots of useful information, including the fact that the failure condition I was experiencing is a well-known issue with the control board (model W10219463), and that two parts in particular fail on the board: a relay and an electrolytic capacitor.&lt;/p&gt;

&lt;p&gt;From Steve&#x27;s blog I learned that the single 200uf capacitor on the board is the one to go bad and when I looked at it again, I noticed that even though there was no discharge from the capacitor, its top was bulging, just like Steve described.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2017/refrigerator-repair-bad-electrolytic-capacitor/02-img-5806.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2017/refrigerator-repair-bad-electrolytic-capacitor/02-img-5806.webp&quot; alt=&quot;&quot; width=&quot;1600&quot; height=&quot;1119&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;Bulging capacitor top&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;I removed the bad capacitor and tested it, confirming that it did not hold anywhere near the charge it was supposed to. &lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2017/refrigerator-repair-bad-electrolytic-capacitor/03-img-5807.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2017/refrigerator-repair-bad-electrolytic-capacitor/03-img-5807.webp&quot; alt=&quot;&quot; width=&quot;1600&quot; height=&quot;1455&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;Low capacity on bad capacitor&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;So, I replaced the bad 220uf capacitor with a fresh one, reinstalled the control board and started up the refrigerator. The compressor went on as did the fan! After a few minutes I confirmed that the fridge was cooling again. &lt;/p&gt;
</description>
  </item>
  <item>
    <title>Jasmine unit testing: Don&#x27;t forget to callThrough()</title>
    <link>https://hatoum.com/blog/2016/11/12/jasmine-unit-testing-dont-forget-to-callthrough/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2016/11/12/jasmine-unit-testing-dont-forget-to-callthrough/</guid>
    <pubDate>Sat, 12 Nov 2016 08:55:36 -0800</pubDate>
    <description>&lt;figure&gt;&lt;a href=&quot;https://jasmine.github.io/&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/jasmine-unit-testing-dont-forget-to-callthrough/01-image-asset.webp&quot; alt=&quot;Jasmine&quot; width=&quot;127&quot; height=&quot;30&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;One of the great things about Jasmine, the Javascript unit testing library, is the &lt;code&gt;spy&lt;/code&gt;. A &lt;code&gt;spy&lt;/code&gt; lets you peek into the workings of the methods of Javascript objects.
Just don&#x27;t forget to use &lt;code&gt;callThrough()&lt;/code&gt; when you don&#x27;t want to alter how the spied-upon function behaves. That&#x27;s because a &lt;code&gt;spy&lt;/code&gt; automatically replaces the spied function with a stub. If you want the spied-upon function to be called normally, add &lt;code&gt;.and.callThrough()&lt;/code&gt; to your &lt;code&gt;spy&lt;/code&gt; statement.&lt;/p&gt;
&lt;h2&gt;Jasmine spies are great&lt;/h2&gt;
&lt;p&gt;One of the great things about Jasmine, the Javascript unit testing library, is the spy. From &lt;a href=&quot;https://jasmine.github.io/archives/2.5/introduction&quot;&gt;Jasmine&#x27;s documentation&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A spy can stub any function and tracks calls to it and all arguments. A spy only exists in the &lt;code&gt;describe&lt;/code&gt; or &lt;code&gt;it&lt;/code&gt; block in which it is defined, and will be removed after each spec.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They are extremely useful for testing and should be part of every unit test writer&#x27;s tool set. However, if you forget some basic truths about spies, you will get unexpected results and wonder why your beautiful tests don&#x27;t work. Some examples:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;spyOn(myGreatJSLib, &#x27;doSomething&#x27;);
myGreatJSLib.doSomething();
// passes
expect(myGreatJSLib.doSomething).toHaveBeenCalled();

spyOn(myGreatJSLib, &#x27;doAnotherThing&#x27;);
myGreatJSLib.doAnotherThing(&#x27;value1&#x27;, 10);
// also passes
expect(myGreatJSLib.doAnotherThing).toHaveBeenCalledWith(&#x27;value1&#x27;, 10);&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;code&gt;spyOn()&lt;/code&gt; replaces functions&lt;/h2&gt;
&lt;p&gt;Jasmine&#x27;s documentation adds:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;By chaining the spy with &lt;code&gt;and.callThrough&lt;/code&gt;, the spy will still track all calls to it but in addition it will delegate to the actual implementation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is an important piece of information to keep in mind, because, depending on what you&#x27;re testing, your tests will appear to be working correctly, but your &lt;code&gt;expect&lt;/code&gt; statements might fail unexpectedly.&lt;/p&gt;
&lt;p&gt;Imagine we&#x27;re testing our awesome &lt;code&gt;RickAndMortyLib&lt;/code&gt; which has a &lt;code&gt;getQuote(characterName)&lt;/code&gt; function. Supplied with the values &lt;code&gt;Rick&lt;/code&gt;, &lt;code&gt;Morty&lt;/code&gt;, or &lt;code&gt;Summer&lt;/code&gt;, the function will return a quote for that character. For the sake of this example, there is only one quote per character:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Rick: &quot;Oh yeah, you gotta get schwifty.&quot;&lt;/li&gt;&lt;li&gt;Morty: &quot;Don&#x27;t even trip about your pants, dawg. We got an extra pair right here.&quot;&lt;/li&gt;&lt;li&gt;Summer: &quot;God, Grandpa, you&#x27;re such a dick.&quot;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Some examples:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;spyOn(RickAndMortyLib, &#x27;getQuote&#x27;);
RickAndMortyLib.getQuote(&#x27;Rick&#x27;);
// passes
expect(RickAndMortyLib.getQuote).toHaveBeenCalledWith(&#x27;Rick&#x27;);

// but....
var rickQuote = RickAndMortyLib.getQuote(&#x27;Rick&#x27;);
// FAILS
expect(rickQuote).toBe(&#x27;Oh yeah, you gotta get schwifty.&#x27;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why did that last &lt;code&gt;expect&lt;/code&gt; fail? Because the &lt;code&gt;spyOn()&lt;/code&gt; call up top &lt;em&gt;replaces&lt;/em&gt; &lt;code&gt;getQuote()&lt;/code&gt; with a stub which can only confirm that it was called and/or called with specific arguments. We could fake a response with one of these two techniques:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;spyOn(RickAndMortyLib, &#x27;getQuote&#x27;).and.returnValue(
                   &#x27;Morty, can you get to the left nipple?&#x27;);
var rickQuote = RickAndMortyLib.getQuote(&#x27;Rick&#x27;);
// passes
expect(rickQuote).toBe(&#x27;Morty, can you get to the left nipple?&#x27;);

// or....
spyOn(RickAndMortyLib, &#x27;getQuote&#x27;).and.callFake(function() {
    return &#x27;GRAAAAAASSSSSSS....tastes bad.&#x27;
});
// passes
expect(rickQuote).toBe(&#x27;GRAAAAAASSSSSSS....tastes bad.&#x27;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Those two tests pass, and the &lt;code&gt;and.returnValue()&lt;/code&gt; and &lt;code&gt;and.callFake()&lt;/code&gt; calls can be very useful in situations where it&#x27;s impossible or difficult to supply whatever your library needs to complete the function call on its own. However, know that you&#x27;re not really testing the function itself when you use a plain &lt;code&gt;spyOn()&lt;/code&gt; call or when you chain &lt;code&gt;and.returnValue()&lt;/code&gt; or &lt;code&gt;and.callFake()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To really test the function call itself, you need to add &lt;code&gt;and.callThrough()&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;spyOn(RickAndMortyLib, &#x27;getQuote&#x27;).and.callThrough();
RickAndMortyLib.getQuote(&#x27;Rick&#x27;);
// passes
expect(RickAndMortyLib.getQuote).toHaveBeenCalledWith(&#x27;Rick);
var rickQuote = RickAndMortyLib.getQuote(&#x27;Rick&#x27;);
// now this expect passes
expect(rickQuote).toBe(&#x27;Oh yeah, you gotta get schwifty.&#x27;);&lt;/code&gt;&lt;/pre&gt;
</description>
  </item>
  <item>
    <title>Programming Basics: Names matter</title>
    <link>https://hatoum.com/blog/2016/9/4/programming-basics-names-matter/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2016/9/4/programming-basics-names-matter/</guid>
    <pubDate>Sun, 04 Sep 2016 09:02:39 -0700</pubDate>
    <description>&lt;h2&gt;TLDR;&lt;/h2&gt;
&lt;p&gt;The names developers use for identifiers in their code is essential for readability, maintainability and is one of the indicators of a competent software developer.&lt;/p&gt;
&lt;p&gt;Combined with a naming convention system, well-chosen identifier names have the potential to make or break a project, especially on collaborative endeavors with multiple developers. &lt;/p&gt;
&lt;h2&gt;What makes a good name?&lt;/h2&gt;
&lt;p&gt;A good identifier name enhances comprehension of the code it describes, making it readable, easy to follow and ultimately more maintainable.&lt;/p&gt;
&lt;p&gt;While placing comments in code is very important, you could argue that using descriptive names for identifiers in our code greatly reduces or possibly eliminates the need for comments.&lt;/p&gt;
&lt;p&gt;You can further magnify the effect of the identifier names you use by applying naming conventions.&lt;/p&gt;
&lt;h3&gt;What are naming conventions?&lt;/h3&gt;
&lt;p&gt;For the uninitiated, naming conventions are rule sets applied to the names of identifiers in software (ex: variables, constants, types, functions). There are many systems of naming conventions such as &lt;a href=&quot;https://en.wikipedia.org/wiki/Hungarian_notation&quot;&gt;Hungarian Notation&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/CamelCase&quot;&gt;Camel Case&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&#x27;s an example of Camel Case -- where the individual words in identifier names are visually separated by capitalizing the first letter of that word. &lt;code&gt;getName()&lt;/code&gt; instead of &lt;code&gt;getname()&lt;/code&gt;. The camel cased version of the method is easier to read.&lt;/p&gt;
&lt;p&gt;I personally separate the concepts of naming from naming conventions since, although similar, they aren&#x27;t the same thing. Most naming conventions dictate the use of underscores, letter case and letter code combinations for use within identifier names, but they don&#x27;t address the actual content or meaning of the identifier itself. &lt;/p&gt;
&lt;p&gt;Most naming convention systems rely on the programmer applying them to logical, meaningful names. And that&#x27;s the area in which, surprisingly, a lot of software developers do a poor job.&lt;/p&gt;
&lt;p&gt;A good identifier name for a service that handled Person objects could be &lt;code&gt;personservice&lt;/code&gt;. Applying Camel Case to it transforms it to &#x27;PersonService&#x27;. Again, the application of a naming convention makes it easier to read and understand.&lt;/p&gt;
&lt;p&gt;However, if instead of calling the class &lt;code&gt;PersonService&lt;/code&gt; we had called it &lt;code&gt;ps&lt;/code&gt;, applying camel case to it (&lt;code&gt;PS&lt;/code&gt;) does little to aid readability, and the meaning -- arguably the most important part of the name -- is still vague.&lt;/p&gt;
&lt;h2&gt;Examples:&lt;/h2&gt;
&lt;p&gt;One of the things that source code obfuscaters do is rename variables and function calls to remove their meaning. Why? Because it&#x27;s much harder to understand code that has no context. Consider the following snippets of Javascript:&lt;/p&gt;
&lt;h4&gt;Original code:&lt;/h4&gt;
&lt;p&gt;This is fairly useless code, does nothing too important, but even without comments (which I always encourage), you can easily follow along to figure out what the code is intended to do.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;var mass, acceleration;
var force = 0;
var isAccelerating = false;

mass = 10;
acceleration = 9.8;

function calculateForce(massKg, accelMeterSecondSq) {
    return massKg * accelMeterSecondSq;
}

isAccelerating = (acceleration &amp;gt; 0) ? true : false;

if (isAccelerating) {
    force = calculateForce(mass, acceleration);
}

console.log(&#x27;Value is: &#x27; + force);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even if you&#x27;re unfamiliar with the formula for force ( force = mass * acceleration), you could follow along and get the meaning of code.&lt;/p&gt;
&lt;h4&gt;Obfuscated:&lt;/h4&gt;
&lt;p&gt;Here&#x27;s what an obfuscater might turn the original code into. I&#x27;ve kept the formatting the same, so we can just focus on the differences in the identifier names.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;var b,c;
var d = 0;
var t = false;

b = 10;
c = 9.8;

function a(e,f) {
    return e*f;
}

t = (c &amp;gt; 0) ? true : false;

if (t) {
    d = a(b,c);
}

console.log(&#x27;Value is: &#x27; + d);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While functionally the program does the same thing, unless you happen to recognize numbers like 9.8 as the acceleration due to gravity and that force = mass * acceleration, you would have a very hard time placing the code in any sort of context.&lt;/p&gt;
&lt;h4&gt;Stupidly named identifiers:&lt;/h4&gt;
&lt;p&gt;I&#x27;ve seen far too much of this kind of thing. To the programmer who wrote this code, it makes perfect sense, but to anyone else it would be hard to follow.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;var heavy, fast;
var hard = 0;
var acceleration =  false;

heavy = 10;
fast = 9.8;

function calc(val1, val2) {
    return val1 * val2;
}

acceleration = (fast &amp;gt; 0) ? true : false;

if (acceleration) {
    hard = calc(heavy, fast);
}

console.log(&#x27;Value is: &#x27; + hard);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I consider this version of the code worse than the obfuscated code. At first glance, the identifiers appear to provide contextual information, but as you read the code, you discover that they are named in such a way as to inhibit understanding.&lt;/p&gt;
&lt;h3&gt;Anecdotal proof&lt;/h3&gt;
&lt;p&gt;An excellent programmer and mentor of mine told me a story that illustrated very clearly the effect that identifier names have in software development. He was in a job where he was treated poorly and had decided to leave. In his last week of employment he altered his source code as a final act of rebellion. He didn&#x27;t add a back door or a virus which could have gotten him into legal trouble. Instead, he changed all the identifier names. &lt;code&gt;isReady()&lt;/code&gt; became &lt;code&gt;isNotDoneNot()&lt;/code&gt;, &lt;code&gt;correct&lt;/code&gt; became &lt;code&gt;unbadly&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt; became &lt;code&gt;value123&lt;/code&gt;. Unfortunately, the programmer who inherited the code was a good friend of my mentor and called him up bitching about how my mentor had ruined his life because the code was impossible to follow. They&#x27;re still friends.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Please use logical, descriptive names for your identifiers. Your fellow programmers will enjoy working on your code, even if they aren&#x27;t aware why. This also applies to Lone Wolf programmers as well who &quot;work alone, damnit!&quot; Descriptively named identifiers will greatly reduce the amount of time you spend saying to yourself &quot;WTF was I trying to do here?!&quot; when maintaining your old code.&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Repair: 30 year-old coffee maker</title>
    <link>https://hatoum.com/blog/2015/11/17/repair-20-year-old-coffee-maker/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2015/11/17/repair-20-year-old-coffee-maker/</guid>
    <pubDate>Sat, 02 Jan 2016 18:11:29 -0800</pubDate>
    <description>&lt;h2&gt;Intro&lt;/h2&gt;

&lt;p&gt;About 15 years ago, I inherited a vintage Black and Decker thermal carafe drip coffee maker, model TCM-411 from the 80&#x27;s. It was given to me in payment for helping ready an apartment for sale.&lt;/p&gt;

&lt;p&gt;I really like the TCM-411. It&#x27;s very simple to operate (no timers or clocks to mess with), it makes good hot coffee, and the glass-lined, mirrored thermal carafe keeps the coffee hot for hours. The only control is a slide switch on the front that turns on the brewing process and which automatically turns it off once all the water has been drained from the reservoir tank. (&lt;a href=&quot;https://hatoum.com/files/black_decker_tcm411.pdf&quot;&gt;PDF manual&lt;/a&gt;, &lt;a href=&quot;https://kitchen.manualsonline.com/manuals/mfg/black_decker/tcm411_tcm413.html&quot;&gt;Manuals Site&lt;/a&gt;)&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/01-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/01-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;MY BLACK &amp; DECKER TCM-411 IN ALL ITS TIME-STAINED GLORY&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;And then one day...without  warning..it stopped working! Almost entirely, but not quite. I could get it to brew coffee if I fiddled with it for 2-3 minutes.&lt;/p&gt;

&lt;p&gt;This post is the story of how, through trial and error, I eventually restored this fantastic coffee maker to its former glory and fully expect to brew another 30 years of great coffee with it. &lt;/p&gt;

&lt;h2&gt;TL;DR&lt;/h2&gt;

&lt;p&gt;After much investigation and final confirmation by my friend Josh of what I suspected was the cause of my coffee maker&#x27;s problems, I learned a valuable lesson:&lt;/p&gt;

&lt;blockquote&gt;Electrolytic capacitors &lt;em&gt;eventually&lt;/em&gt; go bad&lt;/blockquote&gt;

&lt;p&gt;If the device that you are attempting to repair has &lt;a href=&quot;https://en.wikipedia.org/wiki/Electrolytic_capacitor&quot;&gt;electrolytic capacitors&lt;/a&gt;, and the device is more than, say, 10 years old, the capacitors are highly likely to be the cause of your problems.&lt;/p&gt;

&lt;h2&gt;The Full Deal&lt;/h2&gt;

&lt;p&gt;I&#x27;m no electronics expert -- more of an electronics dabbler. It&#x27;s something that has always interested me and I&#x27;ve read many books on the subject, know enough to make mistakes, had conversations with actual experts and have started and sometimes completed many simple electronics projects.&lt;/p&gt;

&lt;p&gt;My goal in this post is to describe the thought processes I went through when investigating what was wrong with my coffee maker and trying to repair it. &lt;/p&gt;

&lt;h3&gt;How coffeemakers work&lt;/h3&gt;

&lt;p&gt;All coffee makers basically have the same parts with some variations:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Heating Element: A sealed resistor that heats the water.&lt;/li&gt;&lt;li&gt;Thermostat: Device that shuts off the heating element once it reaches a threshold temperature.&lt;/li&gt;&lt;li&gt;Temperature Fuse: To prevent coffee makers from causing fires if they malfunction, they all contain fuses that flow when a threshold temperature is reached.&lt;/li&gt;&lt;li&gt;Water Reservoir: Holds the water.&lt;/li&gt;&lt;li&gt;Ground Coffee Holder: This is the place where you put the ground coffee beans.&lt;/li&gt;&lt;li&gt;Coffee Pot: Container to hold finished coffee.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The heated water flows over or through the ground coffee beans and into the coffee pot.&lt;/p&gt;

&lt;h3&gt;What went wrong with my coffee maker&lt;/h3&gt;

&lt;p&gt;When it&#x27;s functioning normally, the TCM-411 coffeemaker is simple to use. After filling the water reservoir and adding ground coffee to the basket filter you start the brewing process by sliding the switch on the front on the coffeemaker to the right. A red LED next to the switch lights up and stays on. About two seconds later you hear &quot;blurp&quot; as the first bit of water is heated and rises up from the heating element and trickles over the ground coffee.&lt;/p&gt;

&lt;p&gt;One day, when I slid the switch over to start brewing my coffee and it didn&#x27;t &quot;catch&quot;. The red LED went on for a moment and then shut off. After some experimentation, I realized that I could get the coffee maker to complete a brew cycle if I kept sliding the switch over, and as soon as it turned off, I would slide it over again. If I did that for around 3 minutes it would finally catch and remain on through the rest of the brew cycle.&lt;/p&gt;

&lt;p&gt;I had two theories as to why the coffee maker wasn&#x27;t working:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;em&gt;Maybe the water reservoir outflow is plugged up?&lt;/em&gt; This was my first theory. I thought water wasn&#x27;t getting into the heater, causing the heater to shut off by whatever mechanism that made it shut off during normal operation. I realized that this theory was incorrect once I figured out that fiddling with the sliding switch would eventually lead to a complete brew cycle.&lt;/li&gt;&lt;li&gt;&lt;em&gt;Maybe the thermostat is broken?&lt;/em&gt; This was my second theory, and I was convinced I was right (oh, but I wasn&#x27;t). It just seemed right that a broken thermostat would cause the coffee machine shut off prematurely.&lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;Disassembly and Investigation&lt;/h3&gt;

&lt;p&gt;I took apart the TCM-411 to see if a visual inspection of its inner workings would lead to a diagnosis of why my favorite coffee maker wasn&#x27;t working.&lt;/p&gt;

&lt;div class=&quot;gallery&quot;&gt;&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/02-img-2583.webp&quot; data-caption=&quot;Underside — Screw holes underneath the coffee maker.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/02-img-2583.webp&quot; alt=&quot;Underside&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Underside — Screw holes underneath the coffee maker.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/03-img-2583.webp&quot; data-caption=&quot;Underside — Screw holes underneath the coffee maker.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/03-img-2583.webp&quot; alt=&quot;Underside&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Underside — Screw holes underneath the coffee maker.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/04-img-2584.webp&quot; data-caption=&quot;Back — Screw hole on the back of the TCM-411&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/04-img-2584.webp&quot; alt=&quot;Back&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Back — Screw hole on the back of the TCM-411&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/05-img-2584.webp&quot; data-caption=&quot;Back — Screw hole on the back of the TCM-411&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/05-img-2584.webp&quot; alt=&quot;Back&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Back — Screw hole on the back of the TCM-411&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/06-img-2585.webp&quot; data-caption=&quot;Reservoir shelf — View down onto the shelf where the water reservoir sits. You can see the water intake from the reservoir and a screw hole.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/06-img-2585.webp&quot; alt=&quot;Reservoir shelf&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Reservoir shelf — View down onto the shelf where the water reservoir sits. You can see the water intake from the reservoir and a screw hole.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/07-img-2585.webp&quot; data-caption=&quot;Reservoir shelf — View down onto the shelf where the water reservoir sits. You can see the water intake from the reservoir and a screw hole.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/07-img-2585.webp&quot; alt=&quot;Reservoir shelf&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Reservoir shelf — View down onto the shelf where the water reservoir sits. You can see the water intake from the reservoir and a screw hole.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/08-img-2586.webp&quot; data-caption=&quot;Underneath, cover off — View into the coffee maker once the bottom plastic cover is removed. You can see the heating element and water flow assembly and the printed circuit board attached to the sliding switch and red LED.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/08-img-2586.webp&quot; alt=&quot;Underneath, cover off&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Underneath, cover off — View into the coffee maker once the bottom plastic cover is removed. You can see the heating element and water flow assembly and the printed circuit board attached to the sliding switch and red LED.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/09-img-2586.webp&quot; data-caption=&quot;Underneath, cover off — View into the coffee maker once the bottom plastic cover is removed. You can see the heating element and water flow assembly and the printed circuit board attached to the sliding switch and red LED.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/09-img-2586.webp&quot; alt=&quot;Underneath, cover off&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Underneath, cover off — View into the coffee maker once the bottom plastic cover is removed. You can see the heating element and water flow assembly and the printed circuit board attached to the sliding switch and red LED.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/10-img-2588.webp&quot; data-caption=&quot;Heating assembly — Another view of the heating and water flow assembly.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/10-img-2588.webp&quot; alt=&quot;Heating assembly&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Heating assembly — Another view of the heating and water flow assembly.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/11-img-2588.webp&quot; data-caption=&quot;Heating assembly — Another view of the heating and water flow assembly.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/11-img-2588.webp&quot; alt=&quot;Heating assembly&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Heating assembly — Another view of the heating and water flow assembly.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/12-img-2590.webp&quot; data-caption=&quot;Heating assembly, sideview — A side view of the heating and water flow assembly, with the water tubes facing up. You can see a white tube pressed up against the inside of the heating/water assembly which contains the two temperature fuses. You can also just make out the plastic tube holding the thermistor pressed against the outside of the heating/water assembly.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/12-img-2590.webp&quot; alt=&quot;Heating assembly, sideview&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Heating assembly, sideview — A side view of the heating and water flow assembly, with the water tubes facing up. You can see a white tube pressed up against the inside of the heating/water assembly which contains the two temperature fuses. You can also just make out the plastic tube holding the thermistor pressed against the outside of the heating/water assembly.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/13-img-2590.webp&quot; data-caption=&quot;Heating assembly, sideview — A side view of the heating and water flow assembly, with the water tubes facing up. You can see a white tube pressed up against the inside of the heating/water assembly which contains the two temperature fuses. You can also just make out the plastic tube holding the thermistor pressed against the outside of the heating/water assembly.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/13-img-2590.webp&quot; alt=&quot;Heating assembly, sideview&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Heating assembly, sideview — A side view of the heating and water flow assembly, with the water tubes facing up. You can see a white tube pressed up against the inside of the heating/water assembly which contains the two temperature fuses. You can also just make out the plastic tube holding the thermistor pressed against the outside of the heating/water assembly.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/14-img-2591.webp&quot; data-caption=&quot;Heating/water assembly, side view — A view from the other other side of the heating/water assembly, showing a brownish-orange tube around the thermistor which is a low cost thermostat.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/14-img-2591.webp&quot; alt=&quot;Heating/water assembly, side view&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Heating/water assembly, side view — A view from the other other side of the heating/water assembly, showing a brownish-orange tube around the thermistor which is a low cost thermostat.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/15-img-2591.webp&quot; data-caption=&quot;Heating/water assembly, side view — A view from the other other side of the heating/water assembly, showing a brownish-orange tube around the thermistor which is a low cost thermostat.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/15-img-2591.webp&quot; alt=&quot;Heating/water assembly, side view&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Heating/water assembly, side view — A view from the other other side of the heating/water assembly, showing a brownish-orange tube around the thermistor which is a low cost thermostat.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/16-img-2596.webp&quot; data-caption=&quot;Thermistor inside tube&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/16-img-2596.webp&quot; alt=&quot;Thermistor inside tube&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Thermistor inside tube&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/17-img-2596.webp&quot; data-caption=&quot;Thermistor inside tube&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/17-img-2596.webp&quot; alt=&quot;Thermistor inside tube&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Thermistor inside tube&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/18-img-2597.webp&quot; data-caption=&quot;Testing the thermistor — At room temperature, the thermistor reads at 50 ohms.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/18-img-2597.webp&quot; alt=&quot;Testing the thermistor&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Testing the thermistor — At room temperature, the thermistor reads at 50 ohms.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/19-img-2597.webp&quot; data-caption=&quot;Testing the thermistor — At room temperature, the thermistor reads at 50 ohms.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/19-img-2597.webp&quot; alt=&quot;Testing the thermistor&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Testing the thermistor — At room temperature, the thermistor reads at 50 ohms.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/20-img-2598.webp&quot; data-caption=&quot;Thermistor, close-up&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/20-img-2598.webp&quot; alt=&quot;Thermistor, close-up&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Thermistor, close-up&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/21-img-2598.webp&quot; data-caption=&quot;Thermistor, close-up&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/21-img-2598.webp&quot; alt=&quot;Thermistor, close-up&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Thermistor, close-up&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/22-img-2600.webp&quot; data-caption=&quot;Temperature fuses — At first I thought these were diodes, but then learned they are temperature fuses. The only thing you can test about them is if they allow electrical flow (continuity).&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/22-img-2600.webp&quot; alt=&quot;Temperature fuses&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Temperature fuses — At first I thought these were diodes, but then learned they are temperature fuses. The only thing you can test about them is if they allow electrical flow (continuity).&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/23-img-2600.webp&quot; data-caption=&quot;Temperature fuses — At first I thought these were diodes, but then learned they are temperature fuses. The only thing you can test about them is if they allow electrical flow (continuity).&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/23-img-2600.webp&quot; alt=&quot;Temperature fuses&quot; width=&quot;1500&quot; height=&quot;2000&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Temperature fuses — At first I thought these were diodes, but then learned they are temperature fuses. The only thing you can test about them is if they allow electrical flow (continuity).&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/24-img-2601.webp&quot; data-caption=&quot;Switch PCB — The printed circuit board (PCB) to which the slide switch attaches.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/24-img-2601.webp&quot; alt=&quot;Switch PCB&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Switch PCB — The printed circuit board (PCB) to which the slide switch attaches.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/25-img-2601.webp&quot; data-caption=&quot;Switch PCB — The printed circuit board (PCB) to which the slide switch attaches.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/25-img-2601.webp&quot; alt=&quot;Switch PCB&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Switch PCB — The printed circuit board (PCB) to which the slide switch attaches.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/26-img-2603.webp&quot; data-caption=&quot;Original capacitor — Here&amp;#x27;s one of the capacitors I replaced on the coffee maker&amp;#x27;s PCB. Notice the discharge residue on the side of the barrel. This was the clue that made me realize the capacitors had gone bad.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/26-img-2603.webp&quot; alt=&quot;Original capacitor&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Original capacitor — Here&amp;#x27;s one of the capacitors I replaced on the coffee maker&amp;#x27;s PCB. Notice the discharge residue on the side of the barrel. This was the clue that made me realize the capacitors had gone bad.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/27-img-2603.webp&quot; data-caption=&quot;Original capacitor — Here&amp;#x27;s one of the capacitors I replaced on the coffee maker&amp;#x27;s PCB. Notice the discharge residue on the side of the barrel. This was the clue that made me realize the capacitors had gone bad.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/27-img-2603.webp&quot; alt=&quot;Original capacitor&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Original capacitor — Here&amp;#x27;s one of the capacitors I replaced on the coffee maker&amp;#x27;s PCB. Notice the discharge residue on the side of the barrel. This was the clue that made me realize the capacitors had gone bad.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/28-img-2608.webp&quot; data-caption=&quot;Discharge, &amp;quot;C0&amp;quot; capacitor&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/28-img-2608.webp&quot; alt=&quot;Discharge, &amp;quot;C0&amp;quot; capacitor&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Discharge, &amp;quot;C0&amp;quot; capacitor&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/29-img-2608.webp&quot; data-caption=&quot;Discharge, &amp;quot;C0&amp;quot; capacitor&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/29-img-2608.webp&quot; alt=&quot;Discharge, &amp;quot;C0&amp;quot; capacitor&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Discharge, &amp;quot;C0&amp;quot; capacitor&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/30-img-2609.webp&quot; data-caption=&quot;Discharge, &amp;quot;C1&amp;quot; capacitor&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/30-img-2609.webp&quot; alt=&quot;Discharge, &amp;quot;C1&amp;quot; capacitor&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Discharge, &amp;quot;C1&amp;quot; capacitor&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/31-img-2609.webp&quot; data-caption=&quot;Discharge, &amp;quot;C1&amp;quot; capacitor&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/31-img-2609.webp&quot; alt=&quot;Discharge, &amp;quot;C1&amp;quot; capacitor&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;Discharge, &amp;quot;C1&amp;quot; capacitor&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/32-img-2610.webp&quot; data-caption=&quot;PCB close-up — In this picture you can see the sliding switch, the replacement C1 capacitor: two larger capacity capacitors in series. You can also see the relay (big blue box) that switches power to the heating element.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/32-img-2610.webp&quot; alt=&quot;PCB close-up&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;PCB close-up — In this picture you can see the sliding switch, the replacement C1 capacitor: two larger capacity capacitors in series. You can also see the relay (big blue box) that switches power to the heating element.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/33-img-2610.webp&quot; data-caption=&quot;PCB close-up — In this picture you can see the sliding switch, the replacement C1 capacitor: two larger capacity capacitors in series. You can also see the relay (big blue box) that switches power to the heating element.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/33-img-2610.webp&quot; alt=&quot;PCB close-up&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;PCB close-up — In this picture you can see the sliding switch, the replacement C1 capacitor: two larger capacity capacitors in series. You can also see the relay (big blue box) that switches power to the heating element.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/34-img-2611.webp&quot; data-caption=&quot;PCB alternate view — Here you see view of the other side of the PCB, with the replacement capacitors (two smaller capacity capacitors in parallel), the relay (blue box), sliding switch and red LED that pokes out the coffee maker&amp;#x27;s front panel.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/34-img-2611.webp&quot; alt=&quot;PCB alternate view&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;PCB alternate view — Here you see view of the other side of the PCB, with the replacement capacitors (two smaller capacity capacitors in parallel), the relay (blue box), sliding switch and red LED that pokes out the coffee maker&amp;#x27;s front panel.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/35-img-2611.webp&quot; data-caption=&quot;PCB alternate view — Here you see view of the other side of the PCB, with the replacement capacitors (two smaller capacity capacitors in parallel), the relay (blue box), sliding switch and red LED that pokes out the coffee maker&amp;#x27;s front panel.&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2016/repair-20-year-old-coffee-maker/35-img-2611.webp&quot; alt=&quot;PCB alternate view&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/a&gt;&lt;figcaption&gt;PCB alternate view — Here you see view of the other side of the PCB, with the replacement capacitors (two smaller capacity capacitors in parallel), the relay (blue box), sliding switch and red LED that pokes out the coffee maker&amp;#x27;s front panel.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;/div&gt;

&lt;p&gt;I learned a lot from the disassembly. However, while I&#x27;m presenting the information in a nice bulleted list, like it was obvious to me, it took me some time to figure out what all the parts were and what role they played.&lt;/p&gt;

&lt;p&gt;For example, while I had read about thermistors, I had never actually seen one in use. The one in the coffee maker looked like a glass diode to me. Also, when I first came upon the two temperature fuses (you&#x27;ll see them in the picture gallery) I also thought they were &lt;a href=&quot;https://en.wikipedia.org/wiki/Diode&quot;&gt;diodes&lt;/a&gt; and was puzzled as to why there two in series. To figure out what the parts were, I took educated guesses (that looks like a diode, that looks like a resistor, etc) and Googled part numbers and images with which to compare. &lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Rather than a thermostat, the TCM-411 uses a &lt;a href=&quot;https://en.wikipedia.org/wiki/Thermistor&quot;&gt;thermistor&lt;/a&gt; to cut power to the heating element. A thermistor is a resistor that reacts to temperature. A PTC (positive temperature coefficient) thermistor increases in resistance as it gets warmer. An NTC (negative temperature coefficient) thermistor -- which is the kind my coffee maker has -- goes down in resistance as its temperature increases. I tested the thermistor and confirmed it was working correctly.&lt;/li&gt;&lt;li&gt;Coffee makers have &lt;a href=&quot;https://en.wikipedia.org/wiki/Thermal_cutoff&quot;&gt;thermal fuses or cutoff&lt;/a&gt; to prevent fires. If the temperature goes beyond a certain point (in this case 240 degrees Fahrenheit) the fuse will blow and instantly cut current to the heating element. The reason there are two fuses, when one would suffice, is that the fuses can go bad and it&#x27;s much cheaper to add a second fuse than defend lawsuits. The only test you can make on a thermal fuse, as far as I know, is to make sure that it doesn&#x27;t have a short -- that it allows electricity to flow through it.&lt;/li&gt;&lt;li&gt;The printed circuit board that provide the single control for the coffee maker has a momentary sliding switch, a relay, some resistors and a couple of electrolytic capacitors. The capacitors were labeled C0 (20uf) and C1 (44uf). Everything checked out ok with the switch and relay, but the capacitors looked suspicious. There was residue around them. When I mentioned this to my oft-consulted friend &lt;a href=&quot;https://josh.com&quot;&gt;Josh&lt;/a&gt;, he immediately said: &quot;That&#x27;s it. Electrolytic capacitors are cheap and always go bad.&quot; He explained that electrolytic capacitors are really cheaply made -- they basically contain paper and an electrolyte which over time will leak out of the capacitor.&lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;Repair&lt;/h3&gt;

&lt;p&gt;Once I understood that the electrolytic capacitors were bad, the repair was really easy. I didn&#x27;t have the exact capacity capacitors I needed (a 50uf and a 20uf) but Josh showed me that we could use capacitors in series and parallel to get whatever values we needed. We used two 100uf capacitors in series to replace the 50uf capacitors, and two 10uf capacitors in parallel to replace the 20uf capacitor.&lt;/p&gt;

&lt;p&gt;Once we replaced the capacitors, my TCM-411 started brewing again. It was a happy day.&lt;/p&gt;
</description>
  </item>
  <item>
    <title>To Drobo or not to Drobo</title>
    <link>https://hatoum.com/blog/2015/4/26/i-like-my-drobo-heres-why/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2015/4/26/i-like-my-drobo-heres-why/</guid>
    <pubDate>Sun, 03 May 2015 15:52:20 -0700</pubDate>
    <description>&lt;h2&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Standard RAID systems require from some to a lot of management which I don&#x27;t want to do. Drobos have very low maintenance needs.&lt;/li&gt;&lt;li&gt;Drobos accept drives of varying capacity and manufacturers making setup and storage updates easy.&lt;/li&gt;&lt;li&gt;There is a simple migration path between Drobo products, which means I can upgrade hardware around my data.&lt;/li&gt;&lt;li&gt;I treat my Drobo as I would any storage device, either single or multi-disk: I know that it&#x27;s fallible and should never be the sole repository of important data. I use it only as a backup device and am not surprised or outraged if drives fail.&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Is Longer; Read if You Want&lt;/h2&gt;

&lt;h2&gt;Background:&lt;/h2&gt;

&lt;p&gt;A few years ago I wanted to buy an enclosure for backups. My various computers were accumulating an ever-increasing amount of of data in the form of pictures, movies, music, applications, emails and documents. It was no longer efficient to manually connect a backup drive to all the devices in my house, nor could I fit all my backups on the same drive.&lt;/p&gt;

&lt;p&gt;I decided I needed a drive enclosure that had RAID capabilities. My needs were fairly simple, in order of importance:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Low maintenance&lt;/li&gt;&lt;li&gt;Expandable architecture&lt;/li&gt;&lt;li&gt;Easy setup&lt;/li&gt;&lt;li&gt;Data security&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;In my work and on personal projects I gained experience with RAID 0, 1 and 5 systems.&lt;/p&gt;

&lt;p&gt;Without getting into specifics (&lt;a href=&quot;https://en.wikipedia.org/wiki/Standard_RAID_levels&quot;&gt;you can learn more about RAID levels&lt;/a&gt; from your friend and mine Wikipedia) I was looking for a RAID 5-like system.&lt;/p&gt;

&lt;p&gt;One thing I kept seeing during my research is that there were two camps: Drobo and everybody else. Particularly, there were many Drobo naysayers, with various arguments as to why Drobos were terrible. It seemed like the voices against Drobo were shrill and didn&#x27;t have good arguments, so I decided to look into it. &lt;/p&gt;

&lt;h2&gt;Misinformation:&lt;/h2&gt;

&lt;p&gt;Drobo detractors have a standard set of arguments to support their assertion that Drobo&#x27;s &quot;BeyondRAID&quot; is inferior to Synology/ QNAP/ Rosewill/ [VENDOR_NAME] solutions. They claim:&lt;/p&gt;

&lt;blockquote&gt;1. &quot;Drobo&#x27;s system is proprietary and therefore your data is locked-in.&quot;&lt;/blockquote&gt;

&lt;p&gt;This is a meaningless statement. &lt;em&gt;All&lt;/em&gt; RAID systems are proprietary because none implement RAID specs in exactly the same way. If you buy a VendorX system and want to move a set of drives over to VendorY, you can&#x27;t, even if both enclosures are set up to use RAID 5, for example. The truth is that once you buy into a particular vendor, Drobo included, you can&#x27;t move a physical set of drives out of that ecosystem.&lt;/p&gt;

&lt;p&gt;Plus, within ecosystems, not all manufacturers make is easy to move drives to new hardware. Drobo has a well-defined migration path within their products and it&#x27;s super easy to fairly easy to move data and/or drives from one system to another. For example, I had a 2nd Gen Drobo 4-Bay (USB 2.0 + Firewire 800) and bought a 3rd Gen Drobo 4-Bay (USB 3.0) for the increased throughput and data rebuilding speeds. I popped the drives out of my 2nd Gen and placed them into my 3rd Gen device and it worked perfectly.&lt;/p&gt;

&lt;blockquote&gt;2. &quot;Drobos are unreliable and experience more unrecoverable data loss than traditional RAID systems.&quot;&lt;/blockquote&gt;

&lt;p&gt;No matter what flavor of RAID, if you have enough drive failures, it will be impossible to recover the data. The quality of the drives you place in your RAID system have much more to do with the reliability of your device than the manufacturer of the enclosure.&lt;/p&gt;

&lt;p&gt;The part of this statement that had a hint of truth is that with the first and second generation Drobos the rebuild time was so lengthy that it would be possible to have a second drive failure, a power outage or some other event that would ruin your data. That happened to me once (a second drive failure during rebuild) and my data was unrecoverable. However, I didn&#x27;t care. I expect all storage devices fail, so I don&#x27;t keep important data in just one place.&lt;/p&gt;

&lt;p&gt;New models of Drobo are much faster (at least 4 to 5 times faster) and have comparable rebuild times to other RAID systems. Also, all current Drobo models have built-in batteries to safely shut down during a power outage.&lt;/p&gt;

&lt;blockquote&gt;3. &quot;Drobos are slow&quot;&lt;/blockquote&gt;

&lt;p&gt;This was true about the first Drobos -- both throughput and rebuild/data management speeds were slow. Current Drobos are much faster and comparable to other RAID systems.&lt;/p&gt;

&lt;p&gt;However, this was largely a non-argument for me. I wanted a RAID system so that I could expand it to hold more than any single drive I could buy and if I got data protection along with, that was a bonus. Throughput speed was not a concern. If I wanted speed from a drive system, I wouldn&#x27;t use any variant of RAID 5, instead opting for a striped (RAID 1) arrangement.&lt;/p&gt;

&lt;h2&gt;My decision:&lt;/h2&gt;

&lt;p&gt;After looking at arguments and data on both sides of the &quot;To Drobo or Not To Drobo&quot; debate, I opted to buy a Drobo 4-bay. To summarize everything above, here&#x27;s why:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Drobos have very low maintenance:&lt;/strong&gt;&lt;br/&gt;I don&#x27;t have to worry about matching drives (neither size and nor manufacturer) and Drobos have a LEDs that tell me the status of all my drives at a glance. It tells me if a drive fails or if I&#x27;m running out of space.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Increasing the amount of storage is very easy:&lt;/strong&gt;&lt;br/&gt;Pop one drive out, pop a larger drive in.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Data migration is simple:&lt;/strong&gt;&lt;br/&gt;This was not something I looked at originally, but greatly appreciated when I wanted to migrate to a newer Drobo. You can physically move drives between an older and newer 4-bay Drobo, as I did, for example. Migrating between different models is slightly more work, but still very simple.&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Drive Recommendations:&lt;/h2&gt;

&lt;p&gt;Apart from my Drobo, I also have a no-name brand of USB 3 4-bay drive enclosure. I use it in place of 4 different enclosures, each with its own power supply (it runs in JBOD mode--Just a Bunch of Disks). I&#x27;ve experienced drive failures in my Drobo and even more in the USB 3 enclosure. I tried different manufacturers and types, but kept on having failures (about one every 3-4 months).&lt;/p&gt;

&lt;p&gt;Finally, I switched to the &lt;a href=&quot;https://www.amazon.com/gp/product/B008JJLZ7G/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B008JJLZ7G&amp;amp;linkCode=as2&amp;amp;tag=hatoum-20&amp;amp;linkId=3HFH5WY2YRLRTGI4&quot;&gt;Western Digital RED series of RAID drives&lt;/a&gt; and haven&#x27;t had to replace drives yet. Really. I thought the whole &quot;made especially for RAID systems&quot; was marketing bullshit, but in my own experience it was true. &lt;/p&gt;

&lt;h2&gt;BTW: When &lt;em&gt;Not&lt;/em&gt; To Get a Drobo, Synology, QNAP, etc&lt;/h2&gt;

&lt;p&gt;You&#x27;ll be disappointed in your purchase, no matter what the manufacturer or technology they use unless you keep the following points in mind:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;All storage fails eventually, even RAIDs:&lt;br/&gt;If you&#x27;re thinking that a RAID-5 enclosure is going to keep your data safe, you&#x27;re wrong. RAID is not magic and In fact, in some ways, RAID systems are more prone to failure than single drives.&lt;/li&gt;&lt;li&gt;RAID is not a backup:&lt;br/&gt;There is a difference between backing up your data and the data-redundancy you get with RAIDs (more, less or none depending on the RAID level). &lt;br/&gt;Data needs to be in &lt;em&gt;at least&lt;/em&gt; 2 separate places (preferably 3, with one being offsite) to be safe. Referring to the first point, don&#x27;t buy a RAID if your thought is to put all your pictures, movies, documents on one &quot;data secure&quot; device. You&#x27;ll be so sad when you have 2 drive failures and lose everything. &lt;/li&gt;&lt;/ul&gt;
</description>
  </item>
  <item>
    <title>Sophomoric but fun</title>
    <link>https://hatoum.com/blog/2015/3/24/sophomoric-but-fun/</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2015/3/24/sophomoric-but-fun/</guid>
    <pubDate>Tue, 24 Mar 2015 10:26:47 -0700</pubDate>
    <description>&lt;p&gt;Just a short post to let the world (anyone who cares, really) that I created a new satirical site called &quot;&lt;a href=&quot;http://ilovecaulk.com&quot;&gt;ILoveCaulk.com&lt;/a&gt;&quot;.&lt;/p&gt;

&lt;p&gt;Why did I spend time creating something as dumb as ILoveCaulk.com? Well, my friend &lt;a href=&quot;https://josh.com&quot;&gt;Josh&lt;/a&gt; and I were talking about domains that we owned, and I told him that one of my treasured domains was &lt;a href=&quot;http://ilovecaulk.com&quot;&gt;ILoveCaulk.com&lt;/a&gt;. He asked if I had done anything with it, and I said &quot;Um...no...but...it&#x27;s awesome, right?&quot; He said it wasn&#x27;t awesome if I hadn&#x27;t put it to use, and he was right. My plans for the site include writing a blog for it and introducing a section called the &quot;Girls of ILoveCaulk.com&quot;.&lt;/p&gt;

&lt;p&gt;So enjoy or deride -- your choice -- &lt;a href=&quot;http://ilovecaulk.com&quot;&gt;ILoveCaulk.com&lt;/a&gt;&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Repair: Nordictrack Audiostrider 990 Elliptical Wheels</title>
    <link>https://hatoum.com/blog/2014/03/repair-nordictrack-audiostrider-990.html</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2014/03/repair-nordictrack-audiostrider-990.html</guid>
    <pubDate>Sun, 09 Mar 2014 10:11:00 -0700</pubDate>
    <description>&lt;h2&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;In 2009 I bought a Nordictrack elliptical exercise machine, &lt;a href=&quot;https://web.archive.org/web/20140724013945/https://service.nordictrack.com/CustomerService/pdfDownload.do?fileName=NTEL7906.0-246891.pdf&amp;amp;directory=%2fpdf%2f&quot;&gt;model Audiostrider 990&lt;/a&gt; (PDF link). As home exercise machines go, it&#x27;s fine. It&#x27;s uses variable magnetic resistance and it folds up fairly compactly. It also has two front wheels that it can be tilted on them and moved around.&lt;/p&gt;

&lt;p&gt;The wheel design of the model I bought is flawed, however. Each wheel is made of somewhat soft plastic and rides on a steel axle, without bearings, and which has an hexagonal nut at the end. Over time, the nut and axle literally pulverize the wheels, as you&#x27;ll see in the pictures below.&lt;/p&gt;

&lt;p&gt;Rather than spend $25 on replacement wheels from Nordictrack, I bought replacements from McMaster.com.&lt;/p&gt;

&lt;p&gt;Incidentally, I noticed that Nordictrack has updated the design of the AudioStrider 990 and now use a much smarter wheel and rolling system, perhaps because of complaints from users of the model I own.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Repair&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The repair was simple, with the hardest part finding a wheel that would be just the right size and not too expensive.&lt;/p&gt;

&lt;p&gt;After a bit of searching, I found the perfect set of wheels on &lt;a href=&quot;https://mcmaster.com/&quot;&gt;McMaster-Carr&lt;/a&gt; (a simply awesome website).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wheels:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://web.archive.org/web/20141114120510/http://www.mcmaster.com/nav/enter.asp?partnum=2781T54&quot;&gt;Part Number: 2781T54&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Description: Econo-Lite Polypropylene Wheel, Black, 4&quot; X 1-1/4&quot;, 1/2&quot; Axle, 275# Capacity&lt;/p&gt;

&lt;p&gt;Price: $2.35 each&lt;/p&gt;

&lt;p&gt;In order to keep the wheels I bought from rubbing on the outer cylinder, surrounding the axle, I placed 4 washers at the &quot;front&quot; of the axle, and another between the new wheel and the outer nut. The extra washer kept the wheels from moving laterally along the axle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lubricant:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The lubricant I used is called &lt;a href=&quot;https://www.amazon.com/gp/product/B000KXLR5E/ref=as_li_ss_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000KXLR5E&amp;amp;linkCode=as2&amp;amp;tag=puromaccom-20&quot;&gt;Sil-Glyde Lube Compoun&lt;/a&gt;d and works great. It&#x27;s primarily for car and boat maintenance, but I&#x27;ve found many other uses such as lubricating wooden door hinges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pictures of the repair&lt;/strong&gt;&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/01-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/01-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;Original Wheel&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Original wheel, before removal.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/02-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/02-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;Left wheel&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Left wheel, showing how the axle destroyed the wheel from within.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/03-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/03-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;RIght wheel removed&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Right wheel removed, showing plastic dust from the axle grinding away inside the wheel.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/04-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/04-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;RIght wheel damage&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Right wheel, showing damage inside.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/05-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/05-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1200&quot; height=&quot;1600&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;Replacement wheel&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://web.archive.org/web/20141114120510/http://www.mcmaster.com/nav/enter.asp?partnum=2781T54&quot;&gt;Replacement wheel&lt;/a&gt; purchased from &lt;a href=&quot;https://www.mcmaster.com/&quot;&gt;McMaster-Carr&lt;/a&gt;&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/06-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/06-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;Axle with washers and lubricant&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Washers keep the new wheel from rubbing against the outer metal cylinder of the axle, and automotive grease keeps the axle lubricated to prevent binding and wear.&lt;/p&gt;

&lt;figure&gt;&lt;a class=&quot;lightbox&quot; href=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/07-image-asset.webp&quot;&gt;&lt;img src=&quot;https://hatoum.com/assets/img/blog/2014/repair-nordictrack-audiostrider-990/07-image-asset.webp&quot; alt=&quot;&quot; width=&quot;1600&quot; height=&quot;1200&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;View full-size image&lt;/span&gt;&lt;/a&gt;&lt;figcaption&gt;Completed repair&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Completed repair, with outer washer to keep the wheel from moving laterally and the hexagonal nut holding everything in place.&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Hiding XML in script tags</title>
    <link>https://hatoum.com/blog/2013/07/hiding-xml-in-script-tags.html</link>
    <guid isPermaLink="true">https://hatoum.com/blog/2013/07/hiding-xml-in-script-tags.html</guid>
    <pubDate>Tue, 16 Jul 2013 06:28:00 -0700</pubDate>
    <description>&lt;h2&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;A few years ago I created a simple Paypal form generation system for my wife, who runs her own business; a &lt;a href=&quot;https://web.archive.org/web/20140112124839/http://pravassawellnesstravel.com/&quot;&gt;wellness travel company called Pravassa&lt;/a&gt;. The original version of the form generator used Flex as the display layer and XML files as the data/model. She edited XML files which dictated to the Flex form system I built what to display (prices, descriptions, etc).&lt;/p&gt;

&lt;p&gt;When my wife updated her website to SquareSpace 6 (from versions 4 and 5), I decided to port all my form generation code to Javascript/JQuery/HTML 5/CSS 4.&lt;/p&gt;

&lt;p&gt;Whereas before I used a Flex URLLoader object to load the configuration XML files, I switched to using JQuery&#x27;s AJAX functions. And that&#x27;s when I ran into a problem.&lt;/p&gt;

&lt;p&gt;SquareSpace 6 websites use virtual docroots, where all the files loaded by website owners are converted to references and redirects to the actual file. This allows SS6 to, for example, automatically generate and reference different versions of images for display on different screen sizes (mobile site vs. desktop).&lt;/p&gt;

&lt;p&gt;The only problem with the system is that it interferes with AJAX calls, when those calls are to files on your own site. The reason for this is that AJAX calls can only be made to the same domain, unless the sites involved support Cross Origin Resource Sharing (&lt;a href=&quot;http://www.w3.org/TR/cors/&quot;&gt;CORS&lt;/a&gt;). CORS is a kind of security model that allows different domains to make calls to each other.&lt;/p&gt;

&lt;p&gt;SS6 rewrites all the URLs for files so that, to an AJAX call, they no longer appear to be on the same site. For example, if your SS6 site is &quot;www.awesomesite.com&quot;, and you place an XML file under &quot;awesomesite.com/myfiles/config.xml&quot;, when the file is requested, SS6 redirects the URL to &quot;static.squarespace.com/878783783hsfsysfkhksfh/khwirykhfkhs/dfdf78d7f8.xml&quot; or something equally ugly. Because the URL gets changed, &quot;local&quot; AJAX requests for files on one&#x27;s own site fail silently or with a non-related error.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://web.archive.org/web/20131115030417/http://answers.squarespace.com/questions/3557/is-cors-support-planned-for-squarespace-6&quot;&gt;Since SquareSpace isn&#x27;t going to support CORS anytime soon&lt;/a&gt;, I was forced to use a different technique to access the XML configuration files my wife uses for her website. By the way, I realize my need to load local files via AJAX is a somewhat specific use case, though I hope that SquareSpace either eventually supports CORS, or no longer uses redirects when users request files from their own file store. &lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;My solution was to embed the XML configuration files right on the page, hidden in a &amp;lt;script&amp;gt; tag. This is a hack, but it works, and it allowed my wife to continue adding forms to her website without having to learn a whole new way of doing things.&lt;/p&gt;

&lt;p&gt;The basic idea is using a script tag without a type attribute, but with an id attribute. The id gives you a simple lookup via JQuery to access the XML document between the script tags.&lt;/p&gt;

&lt;p&gt;Example Script tag:&lt;/p&gt;

&lt;pre&gt;&amp;lt;script id=&quot;form_config&quot;&amp;gt;
 &amp;lt;form_config&amp;gt;
&amp;lt;name&amp;gt;My Great Form&amp;lt;/name&amp;gt;
 &amp;lt;/form_config&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/pre&gt;

&lt;p&gt;JQuery to access the value of &amp;lt;name&amp;gt;:&lt;/p&gt;

&lt;pre&gt;//Pulls the content of the script tag out as text.
var xmlDoc = jQuery(&#x27;#form_config&#x27;).text();

//Searches within the text (treating it as an XML doc)
var nameValue = jQuery(xmlDoc).find(&#x27;name&#x27;).text(); 
&lt;/pre&gt;
</description>
  </item>
</channel>
</rss>
