<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>26oclock</title>
    <subtitle>Powering my hedonic treadmill with software and electronics</subtitle>
    <link rel="self" type="application/atom+xml" href="/atom.xml"/>
    <link rel="alternate" type="text/html" href="/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2024-12-20T00:00:00+00:00</updated>
    <id>/atom.xml</id>
    <entry xml:lang="en">
        <title>Sniffing the Fuji G mount with a MCEX-45G macro tube</title>
        <published>2022-09-19T00:00:00+00:00</published>
        <updated>2024-12-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Scott
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/mcex-45g-teardown/"/>
        <id>/posts/mcex-45g-teardown/</id>
        
        <content type="html" xml:base="/posts/mcex-45g-teardown/">&lt;h1 id=&quot;context&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#context&quot; aria-label=&quot;Anchor link for: context&quot;&gt;Context&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;The Fujifilm GFX line of cameras is the most accessible digital &#x27;medium format&#x27; system to date, and the Fujinon lenses are optically fantastic and incredibly capable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;fuji-gf.jpg&quot; alt=&quot;Fujifilm GFX50R with 110mm lens held in hand&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;While there are a handful of dumb mechanical lens adaptors for the G-mount, and a couple of &#x27;smart&#x27; adaptors from companies like Fringer, there is very little information about the mount or protocol.&lt;&#x2F;p&gt;
&lt;p&gt;I had a &#x27;&lt;em&gt;the right kind of wrong&lt;&#x2F;em&gt;&#x27; idea to figure out GF lens control with the end-goal of (possibly) building a &#x27;medium format&#x27; film camera around them.&lt;&#x2F;p&gt;
&lt;p&gt;As all of the currently released GF lenses use fly-by-wire focus, electronic aperture, and some need to be powered up to position floating optical elements - if I want to build a camera around them then I&#x27;ll need to reverse engineer the mechanical, electrical, and software to even consider camera design.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;disassembling-a-mcex-45g&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#disassembling-a-mcex-45g&quot; aria-label=&quot;Anchor link for: disassembling-a-mcex-45g&quot;&gt;Disassembling a MCEX-45G&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;I picked up the 45mm extension tube on a ~25% discount with the intention of using it to bootstrap debugging, and probably provide donor lens&#x2F;body mount flanges.&lt;&#x2F;p&gt;
&lt;p&gt;Can confirm it works as advertised with the GF 110mm F2.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;stick-moss-macro.jpg&quot; alt=&quot;Close up detail photo of broken stick with green moss and spiderwebs, black background&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Lets dive in.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lens-mount-basics&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#lens-mount-basics&quot; aria-label=&quot;Anchor link for: lens-mount-basics&quot;&gt;Lens mount basics&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The electrical connections between the body and lens are made with 12 spring loaded contacts on the body which mechanically align with 11 contact rectangles on the lens.&lt;&#x2F;p&gt;
&lt;p&gt;My reference drawing for the lens contacts:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;lens-contacts-drawing.png&quot; alt=&quot;Dimensioned mechanical drawing of lens pin shapes and positions&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lens-side&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#lens-side&quot; aria-label=&quot;Anchor link for: lens-side&quot;&gt;Lens Side&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The lens-side contacts are 1.6 x 1.3 mm rectangular pads, with the long edge aligned tangentially to the circular mount.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When looking at the back of the lens mount, the right-most pin is a 1.3 mm x 1.3 mm square contact.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For ease of convention, I&#x27;ll label this square pad as &lt;code&gt;Pin 1&lt;&#x2F;code&gt;, though I don&#x27;t know what the official nomenclature is.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Based on this numbering scheme, &lt;code&gt;Pin 5&lt;&#x2F;code&gt; and &lt;code&gt;Pin 6&lt;&#x2F;code&gt; are mechanically the same contact rectangle, and therefore electrically common.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Unlike the body side mount, the lens mount&#x2F;bayonet is not electrically common with &lt;code&gt;Pin 5&lt;&#x2F;code&gt; and &lt;code&gt;Pin 6&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;One interesting point to note - the pinout for the GF 45mm (top) doesn&#x27;t use all 12 contacts that the body provides, while the GF 110mm (bottom) does.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;lens-contact-differences.jpg&quot; alt=&quot;Two lenses on table showing the bayonet mount, smaller first lens has 7 visible contacts, the second has 11&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;body-side&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#body-side&quot; aria-label=&quot;Anchor link for: body-side&quot;&gt;Body Side&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;The spring section of the pins have a 1.0 mm diameter, and a maximum achievable travel of 0.8 mm.&lt;&#x2F;li&gt;
&lt;li&gt;The spring pins have a conical&#x2F;round tip.&lt;&#x2F;li&gt;
&lt;li&gt;The pins are spaced 6° apart, for a total span&#x2F;range of 66°. There is no pin on the vertical axis, and from a vertical datum aligned with the center of the lens, the outermost edge pins are aligned to +33° and -33°.&lt;&#x2F;li&gt;
&lt;li&gt;The mount (metal ring&#x2F;bayonet assembly) is electrically common with the exposed metal inside the battery compartment, as well as &lt;code&gt;Pin 5&lt;&#x2F;code&gt; and &lt;code&gt;Pin 6&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now lets start opening up the extension tube to learn more...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tube-design&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tube-design&quot; aria-label=&quot;Anchor link for: tube-design&quot;&gt;Tube design&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;From the rear, a few screws remove the bayonet mount (i.e. the &#x27;lens side mount&#x27;). The weathersealing gasket slides off with it, and we can see the simple internal design of the extention tube.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;bayonet-removed.jpg&quot; alt=&quot;Machined metal ring with 3 overhang features for retention&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;tube-baffle-exposed.jpg&quot; alt=&quot;Black metal tube sitting inside black lens mount assembly with visible gap between the tubes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Looking into the cavity, there are some small screws which allow the removal of the internal baffle cylinder piece.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;baffle-removed.jpg&quot; alt=&quot;Machined cylinder, internal walls appear corrugated&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &#x27;female&#x27; flange assembly which is found on the camera body has a machined mating face and orange lens alignment dot, backed by a thin spring plate to provide preload against the incoming lens bayonet features.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;lens-mount-front-iso.jpg&quot; alt=&quot;Side view of metal ring with polished silver appearance, flexible retention plate&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;lens-mount-rings.jpg&quot; alt=&quot;Top down views of lens mount ring and thin spring ring&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The lens release is a simple spring loaded post that just rests against the main tube assembly.&lt;&#x2F;p&gt;
&lt;p&gt;The main tube assembly is actually two pieces - the thin exterior &#x27;skin&#x27;, and a thicker machined aluminium piece which has most of the mounting geometry for the mounting flanges and electrical sub-assembly.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;tube-shell.jpg&quot; alt=&quot;Top down view of black anodized extension tube with most parts removed&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cad-models&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#cad-models&quot; aria-label=&quot;Anchor link for: cad-models&quot;&gt;CAD Models&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I took a handful of measurements of each mount and attempted to draw mechanically compatible lens and body mount designs in Solidworks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;mount-render-iso.png&quot; alt=&quot;3D render of lens and body mount flanges&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not 100% on the accuracy of either design, but a motion study showed them mating successfully and I&#x27;m confident I&#x27;d be able to use these as a starting point for a more manufacture-friendly design.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;flex-pcb&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#flex-pcb&quot; aria-label=&quot;Anchor link for: flex-pcb&quot;&gt;Flex PCB&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;As we expected before the tear-down, the extension tube only provides a dumb pass-through to the lens mount, there&#x27;s no active electronics.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;tube-exposed.jpg&quot; alt=&quot;Angled view of extension tube and exposed flex PCB connecting to spring contacts&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The pad sections of the flex are held captive against a plastic a ring which supports some tiny pogo-pins.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;flex-bracket-removed.jpg&quot; alt=&quot;Plastic bracket with spring contacts removed from camera, top down view&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Hindsight tells us that unscrewing the plastic retention bracket behind the pogo-pins is a mistake - I spent the better part of an hour trying to guide the springs back into place with a handmade jig of needles.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;pogo-pin-size.jpg&quot; alt=&quot;Size comparison between 1mm metal slug and 1x4mm spring against a thumb&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We now have some good hints of which pins are responsible for power, and those which are intended for data.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;flex-bottom.jpg&quot; alt=&quot;Top-down view of flex PCB separate from assemblies, mix of thin and thick traces&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;flex-top.jpg&quot; alt=&quot;Back view of flex-PCB, two thick traces occupy 60% of visible surface area&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;attaching-debug-probes&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#attaching-debug-probes&quot; aria-label=&quot;Anchor link for: attaching-debug-probes&quot;&gt;Attaching debug probes&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;With the electrical sub-assemblies out of the tube we begin by removing the Kapton tape protecting the through-hole pins, solder silicone wires onto the camera side of the flex, and then re-apply fresh Kapton tape to protect the joins from electrical contact with the tube&#x2F;mount.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;gf-tube-wires.jpg&quot; alt=&quot;Flex PCB held in Stickvise, white wires soldered to contacts&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But you might be asking, &quot;how do you get the wires out of a sealed tube&quot;?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;tube-holes.jpg&quot; alt=&quot;Metal tube sections wrapped in masking tape, holes drilled in sides&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;tube-inner-hole.jpg&quot; alt=&quot;Inner tube section with hole in side, angled shot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;tube-outer-hole.jpg&quot; alt=&quot;Outer tube surface with hole drilled under lens release clip, angled shot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With the exit holes measured and drilled, I started re-assembling the extension tube.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;gf-tube-partial-assembly.jpg&quot; alt=&quot;Angled top view showing debug wires running through drilled external holes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;tube-reassembled.jpg&quot; alt=&quot;Reassembled macro tube with debug wires dangling out the side&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once the tube was re-assembled, I identified each debug wire by checking for continuity with the lens mount pins, and then soldered on a terminal strip to make debug connections easier.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;electrical-behaviour&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#electrical-behaviour&quot; aria-label=&quot;Anchor link for: electrical-behaviour&quot;&gt;Electrical Behaviour&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;We&#x27;ll start by identifying our power pins. Some immediate clues can be gleaned from looking at the flex PCB and by probing the pins on the camera.&lt;&#x2F;p&gt;
&lt;p&gt;The ground was assumed to be &lt;code&gt;Pin 5&lt;&#x2F;code&gt; as it has higher-current traces and is common with Pin 6 on the lens mount side. It&#x27;s also electrically common with the GFX body mount.&lt;&#x2F;p&gt;
&lt;p&gt;After poking around with a multimeter and oscilloscope for a few minutes, we have a rough pinout:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Pin&lt;&#x2F;th&gt;&lt;th&gt;Voltage&lt;&#x2F;th&gt;&lt;th&gt;State&lt;&#x2F;th&gt;&lt;th&gt;Scope&#x2F;Notes&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;~0V&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Never triggers scope, even with varied stimulus&#x2F;settings.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;5.32V&lt;&#x2F;td&gt;&lt;td&gt;DC&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;6.72V&lt;&#x2F;td&gt;&lt;td&gt;DC&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;8.01V&lt;&#x2F;td&gt;&lt;td&gt;DC&lt;&#x2F;td&gt;&lt;td&gt;Battery Voltage. ~100mV ripple when focus motor engages.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;Used as ground connection.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;Electrically common with Pin 5&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;3.4V&lt;&#x2F;td&gt;&lt;td&gt;Normally high&lt;&#x2F;td&gt;&lt;td&gt;Infrequent squarewave. No recognisable pattern.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;3.38V&lt;&#x2F;td&gt;&lt;td&gt;Normally high&lt;&#x2F;td&gt;&lt;td&gt;High speed edges, infrequently triggered.&lt;br &#x2F;&gt;Pulses LOW for approx 100-350ns at a 10ms interval.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;0V&lt;&#x2F;td&gt;&lt;td&gt;Normally low&lt;&#x2F;td&gt;&lt;td&gt;Squarewave, data line.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;3.3V&lt;&#x2F;td&gt;&lt;td&gt;Normally high&lt;&#x2F;td&gt;&lt;td&gt;Squarewave, clock line at 1.5MHz.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;0V&lt;&#x2F;td&gt;&lt;td&gt;Normally low&lt;&#x2F;td&gt;&lt;td&gt;Squarewave, data line.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;3.3V&lt;&#x2F;td&gt;&lt;td&gt;Normally high&lt;&#x2F;td&gt;&lt;td&gt;Squarewave, goes low when iris closes.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;I now know what&#x27;s safe to connect to the logic analyser and could start sniffing for communications between the body and lens.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;logic-sniffing.jpg&quot; alt=&quot;Camera with tube and lens, connected to Saleae logic analyser&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;signal-analysis&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#signal-analysis&quot; aria-label=&quot;Anchor link for: signal-analysis&quot;&gt;Signal analysis&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;A capture of some simple camera operation will start off our analysis:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Power up,&lt;&#x2F;li&gt;
&lt;li&gt;Focus, then focus+photo&lt;&#x2F;li&gt;
&lt;li&gt;Power off&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;basic-behaviour.png&quot; alt=&quot;Logic analyser waveform capture of signal pins&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-lines&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-lines&quot; aria-label=&quot;Anchor link for: data-lines&quot;&gt;Data Lines&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Lets start by looking into the data lines first. We can see some one-way data transfers, as well as request&#x2F;response style behaviour. This lets us make the following observations about these data pins:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Pin 9&lt;&#x2F;code&gt; is the body&#x27;s DATA OUT line,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Pin 10&lt;&#x2F;code&gt; is a 1.5MHz SPI-style clock signal,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Pin 11&lt;&#x2F;code&gt; is the body&#x27;s DATA IN line,&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;controller-peripheral-evidence.png&quot; alt=&quot;Packet capture showing clock and two data waveforms&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With this in mind, lets identify the properties of the communications bus and determine if it&#x27;s a fairly typical SPI or some Fuji special sauce:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A transaction seems to consist of 32-bits at minimum,
&lt;ul&gt;
&lt;li&gt;Almost all transactions are 32-bits long.&lt;&#x2F;li&gt;
&lt;li&gt;During startup, a pair of 1048-bit long transactions occur with a 3ms gap - these are the longest identified transactions.&lt;&#x2F;li&gt;
&lt;li&gt;As the division of  &lt;code&gt;1048&lt;&#x2F;code&gt; and the potential bits-per-transfer should be an integer, we can reasonably throw out &lt;code&gt;16&lt;&#x2F;code&gt; and &lt;code&gt;32&lt;&#x2F;code&gt; bit transfer sizes.&lt;&#x2F;li&gt;
&lt;li&gt;Therefore it&#x27;s reasonable to assume byte-level layout of packets.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;We can also determine the clock behaviour, by looking at the first falling edge and any 8-bit aligned end:
&lt;ul&gt;
&lt;li&gt;The clock is high when inactive (CPOL = 1).&lt;&#x2F;li&gt;
&lt;li&gt;Data appears to be timed for the clock&#x27;s trailing edge (CPHA = 1)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;mcex-45g-teardown&#x2F;clock-phase-evidence.png&quot; alt=&quot;Analysis capture of clock waveform&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-io&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#other-io&quot; aria-label=&quot;Anchor link for: other-io&quot;&gt;Other IO&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;Pin 1&lt;&#x2F;code&gt; is intended as a signalling line due to the trace thickness, but I saw no activity.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Pin 7&lt;&#x2F;code&gt; seems to be related to auto-focus motor activation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Pin 12&lt;&#x2F;code&gt; correlates to the iris closing.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;protocol-analysis&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#protocol-analysis&quot; aria-label=&quot;Anchor link for: protocol-analysis&quot;&gt;Protocol Analysis&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;We can now sniff the packets being sent between the lens and body. From a few test captures, there&#x27;s a few key packet sequences that are immediately obvious.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;startup-identification-packets&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#startup-identification-packets&quot; aria-label=&quot;Anchor link for: startup-identification-packets&quot;&gt;Startup&#x2F;Identification packets&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;After the camera is powered on with a GF 45mm F2.8 lens, a series of &lt;code&gt;131B&lt;&#x2F;code&gt; transactions occur (each sent twice 3ms apart). These transactions are from the lens to the body and &lt;strong&gt;describe the lens&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The first transaction starts with &lt;code&gt;0x00 0x00&lt;&#x2F;code&gt;, the second transaction starts with &lt;code&gt;0xFF 0xFF&lt;&#x2F;code&gt;. Both end with what I&#x27;m assuming is a single checksum byte.&lt;&#x2F;p&gt;
&lt;p&gt;The payload (hex formatted) looks like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;4c52 3130 3641 0000 4653 534e 5730 3036
&lt;&#x2F;span&gt;&lt;span&gt;4746 3435 6d6d 4632 2e38 2052 2057 5200
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;3234 3033 3338 3636 3035 0156 0100 0100
&lt;&#x2F;span&gt;&lt;span&gt;0100 0100 c801 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Doing a little bit of conversion we find:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The first chunk of data is ASCII: &lt;code&gt;LR106A  FSSNW006GF45mmF2.8 R WR&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;Not sure what the first string section means yet.&lt;&#x2F;li&gt;
&lt;li&gt;Part of the last section is obvious as the lens is officially labelled as &lt;code&gt;GF45mmF2.8 R WR&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The second block of data in the payload is likely some combination of binary data and potentially ASCII formatted numbers with no obvious meaning.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Sniffing the GF 110mm F2 startup packet we see similar behaviour:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;4c52 3130 3441 0000 4653 534e 5731 3034
&lt;&#x2F;span&gt;&lt;span&gt;4746 3131 306d 6d46 3220 5220 4c4d 2057
&lt;&#x2F;span&gt;&lt;span&gt;5200 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;3035 4330 3030 3234 0000 0160 0110 0110
&lt;&#x2F;span&gt;&lt;span&gt;0110 0110 c801 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;The first section of data is ASCII: &lt;code&gt;LR104A  FSSNW104GF110mmF2 R LM WR&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The second block is different and similarly unrecognisable.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After the lens packets, and &lt;strong&gt;only when the GF110mm is mounted&lt;&#x2F;strong&gt;, the camera body describes itself to the lens.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;5350 5833 0000 0000 0000 4746 5820 3530
&lt;&#x2F;span&gt;&lt;span&gt;5200 0000 0000 0000 0000 0000 0000 4746
&lt;&#x2F;span&gt;&lt;span&gt;5820 3530 5200 0000 0000 0000 0035 3933
&lt;&#x2F;span&gt;&lt;span&gt;3533 3433 3833 3633 3131 3831 3131 3339
&lt;&#x2F;span&gt;&lt;span&gt;3744 3031 3031 3130 3834 3102 2001 3501
&lt;&#x2F;span&gt;&lt;span&gt;0001 0001 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;span&gt;0000 0000 0000 0000 0000 0000 0000 0000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;The first section of data is ASCII: &lt;code&gt;SPX3  GFX 50R  GFX 50R&lt;&#x2F;code&gt; (whitespace trimmed)
&lt;ul&gt;
&lt;li&gt;Unsure of what &lt;code&gt;SPX3&lt;&#x2F;code&gt; represents.&lt;&#x2F;li&gt;
&lt;li&gt;The repeated pair of &lt;code&gt;GFX 50R&lt;&#x2F;code&gt; string sequences match the body under test.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The second chunk of data is another unknown mix of potentially ASCII, and unprintable bytes.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;idle-packets&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#idle-packets&quot; aria-label=&quot;Anchor link for: idle-packets&quot;&gt;&#x27;Idle&#x27; packets&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;When the camera is powered on but is otherwise sitting idle, we see a burst of transactions occur every 40ms.&lt;&#x2F;p&gt;
&lt;p&gt;These packets represent the bulk of &#x27;noise&#x27; when reading packet traces, so understanding, decoding and then filtering them represents a worthwhile effort.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Transmission #&lt;&#x2F;th&gt;&lt;th&gt;Camera&lt;&#x2F;th&gt;&lt;th&gt;Lens&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00 0x00 0x08 0x20&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x?? 0x10 0x80 0x??&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x08 0x00 0x88 0x32&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x03 0x80 0x08 0x3C&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x08 0x00 0x88 0x??&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x?? 0x00 0x80 0x??&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;On every third burst (120ms interval), we have 2 additional transactions for a total of 6 total.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Transmission #&lt;&#x2F;th&gt;&lt;th&gt;Camera&lt;&#x2F;th&gt;&lt;th&gt;Lens&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00 0x00 0x08 0x20&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x?? 0x10 0x80 0x??&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x08 0x00 0x88 0x32&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00 0x00 0x09 0xA6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x03 0x80 0x08 0x3C&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x?? 0x00 0x88 0x??&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x?? 0x00 0x89 0x??&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00 0x15 0x09 0x9A&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x08 0x00 0x89 0xB8&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x?? 0x00 0x80 0x??&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;For both the 4 and 6 packet bursts, when I marked the first bytes as &lt;code&gt;0x??&lt;&#x2F;code&gt; this was to represent them varying between subsequent bursts. Sampling 5 random sequences of packets gives the impression that there isn&#x27;t obvious packet counting behaviour though.&lt;&#x2F;p&gt;
&lt;p&gt;The final bytes marked &lt;code&gt;0x??&lt;&#x2F;code&gt; are an assumed CRC byte which is changing due to the cycling first byte...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;iris-packets&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#iris-packets&quot; aria-label=&quot;Anchor link for: iris-packets&quot;&gt;Iris packets&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Looking for packets we don&#x27;t recognise around the IRIS control IO line (&lt;code&gt;Pin 12&lt;&#x2F;code&gt;) changing state, I  found the following series of transactions. This whole sequence spans 275 ms.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Transmission #&lt;&#x2F;th&gt;&lt;th&gt;Camera&lt;&#x2F;th&gt;&lt;th&gt;Lens&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x12 0x40 0x18 0xBA&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x09 0x10 0x80 0x2A&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x08 0x00 0x98 0xB6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00 0x00 0x3F 0xC6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x12 0x40 0x18 0xBA&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x0A 0x00 0x98 0x86&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x09 0x00 0xBF 0xE0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;Pin 12&lt;&#x2F;code&gt; (IRIS) low&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00 0x00 0x00 0x00&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00 0x00 0x3F 0xC6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x08 0x00 0xBF 0xD8&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x0A 0x00 0x80 0x22&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Silent for 40ms&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;6 bursts of IDLE packets&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;Pin 12&lt;&#x2F;code&gt; (IRIS) high&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;These packets add some confidence to a gut feel that the first byte is acting as some kind of identifier - we can see the camera send packets to the lens and receive packets in matching order, however the middle two bytes vary.&lt;&#x2F;p&gt;
&lt;p&gt;To get any deeper meaning out of this I think I&#x27;m going to make&#x2F;find some better tools for packet analysis and experimentation.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Anchor link for: what-s-next&quot;&gt;What&#x27;s next?&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;blockquote&gt;
&lt;p&gt;2024 Update: I&#x27;ve made the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Scottapotamas&#x2F;fuji-G-mount&quot;&gt;GitHub repo public&lt;&#x2F;a&gt; as a few people have asked questions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;posts&#x2F;mk-zoom-gf-mod&#x2F;&quot;&gt;Related mechanical post continues the process&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;There are three key areas which need to progress as part of the reverse engineering effort:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;del&gt;3D print or machine some test lens mount assemblies to check compatibility,&lt;&#x2F;del&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Better understand the behaviour of the extra IO signals, and measure current consumption on the various DC supply lines in anticipation of making functional interface electronics,&lt;&#x2F;li&gt;
&lt;li&gt;Develop a SPI man-in-the-middle bridge to build out tooling and firmware as part of reverse-engineering the communications protocol.
&lt;ul&gt;
&lt;li&gt;Being able to detect, log and then filter out common packets should make finding unique packets easier, and give clues as to what might be inside.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building an offsite Proxmox Backup Server</title>
        <published>2022-06-10T00:00:00+00:00</published>
        <updated>2022-06-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Scott
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/hp-microserver-gen10plus/"/>
        <id>/posts/hp-microserver-gen10plus/</id>
        
        <content type="html" xml:base="/posts/hp-microserver-gen10plus/">&lt;h1 id=&quot;why-an-offsite-pbs&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-an-offsite-pbs&quot; aria-label=&quot;Anchor link for: why-an-offsite-pbs&quot;&gt;Why an offsite PBS&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;VM backups can be done to external SMB&#x2F;CIFS drives directly from Proxmox. I was using an older QNAP NAS for backups but had a few workflow issues I wanted to resolve, namely the full-copy for each backup run presenting two issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a month&#x27;s backups would consume ~3TB, and&lt;&#x2F;li&gt;
&lt;li&gt;waking up to hear the backup still running after it&#x27;s automated midnight start&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.proxmox.com&#x2F;en&#x2F;proxmox-backup-server&quot;&gt;Proxmox Backup Server&lt;&#x2F;a&gt; (PBS) is a companion service which provides offsite de-duplicated backups for Proxmox VE container and virtual machine images.&lt;&#x2F;p&gt;
&lt;p&gt;The main benefit of running a PBS instance over adding some networked storage to Proxmox is integration and control:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;de-duplicated backups reduce raw disk space over longer timeframes
&lt;ul&gt;
&lt;li&gt;especially pronounced for large VM images containing static content&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Chunking means that only deltas are sent,&lt;&#x2F;li&gt;
&lt;li&gt;Compression on each end makes internet-based backups viable with Australian internet connections&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Also, better integration with Proxmox&#x27;s UI makes managing backups and restoration easier.&lt;&#x2F;p&gt;
&lt;p&gt;With more than two dozen LXC and VM instances running on my main VM machine, I was wanting to get something running soon.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;hardware&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#hardware&quot; aria-label=&quot;Anchor link for: hardware&quot;&gt;Hardware&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;I picked up 4 WD 14TB external drives for a reasonable price - not &#x2F;r&#x2F;datahorder bargains, but pretty affordable for Australia&#x27;s e-retailers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;wd-14tb.jpg&quot; alt=&quot;A stack of four 3.5inch harddrives&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For a small, reasonably quiet and turnkey server, I picked up a HP Microserver Gen10+ with an Intel Xeon E-2224 and 16GB of RAM.&lt;&#x2F;p&gt;
&lt;p&gt;I used a PCIe to M.2 card for internal storage, and loaded the drives.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;disks-installed.jpg&quot; alt=&quot;A HP microserver with removed front-panel, 4 disks installed&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;hpems-running.jpg&quot; alt=&quot;Running microserver on a desk&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Overall, pretty happy with the compact footprint and build quality of the G10+, though I&#x27;d love an internal M.2 slot...&lt;&#x2F;p&gt;
&lt;h1 id=&quot;overcomplicating-it&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#overcomplicating-it&quot; aria-label=&quot;Anchor link for: overcomplicating-it&quot;&gt;Overcomplicating it&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;The destination for this backup server is offsite (a friend&#x27;s house) - so there are some considerations for remote access that force some key software choices, as well as a desire to allow &#x27;multi-tennant&#x27; operation where simple VM hosting and storage is allocated for use as a NAS.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, I wanted to make the unit as close to set and forget as possible - no specific network setup, port-forwarding required. Therefore,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Solid ZFS support is a must,&lt;&#x2F;li&gt;
&lt;li&gt;Some kind of virtualisation is needed for multi-user containers&lt;&#x2F;li&gt;
&lt;li&gt;A site-to-site VPN will be needed to allow the Proxmox VE server and PBS instances to communicate,&lt;&#x2F;li&gt;
&lt;li&gt;Networks and services should be sufficiently isolated that no access to either &#x27;home&#x27; network can leak into any other,&lt;&#x2F;li&gt;
&lt;li&gt;I need the ability to access Proxmox&#x27;s management plane remotely,&lt;&#x2F;li&gt;
&lt;li&gt;and what about remote access to HP&#x27;s iLO management interface?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I tried TrueNAS at first, motivated by the ability to run the OS from a USB on the internal USB port, and wanting to see what everyone&#x27;s raving about.&lt;&#x2F;p&gt;
&lt;p&gt;While it&#x27;s fine, it didn&#x27;t feel like the correct solution for me, but I can see the appeal of setting ZFS and network shares from a GUI.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;proxmox-setup&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#proxmox-setup&quot; aria-label=&quot;Anchor link for: proxmox-setup&quot;&gt;Proxmox Setup&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Sticking with the tried and true Proxmox for a hypervisor was an easy choice - adding multiple users with pools of containers&#x2F;VMs solves the multi-tenant requirements reasonably well, and ZFS volumes can be shared to the various containers with bind-mounts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zfs-storage&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#zfs-storage&quot; aria-label=&quot;Anchor link for: zfs-storage&quot;&gt;ZFS Storage&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;ZFS &lt;em&gt;raidz1&lt;&#x2F;em&gt; will span the 4*14TB disks, supporting a single disk failure without loss of data, along with the benefits of bitrot detection, compression and CoW benefits...&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;raidz1&lt;&#x2F;em&gt; is thought of as a&quot;diagonal parity RAID&quot;,  where parity blocks are distributed across all disks, with a total  quantity of parity equal to one disk.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;The main storage zpool is called &lt;code&gt;tank&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;datasets on &lt;code&gt;tank&lt;&#x2F;code&gt; provide segregated storage called &lt;code&gt;user1&lt;&#x2F;code&gt;, &lt;code&gt;pbs&lt;&#x2F;code&gt; and &lt;code&gt;user2&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The internal nvme boot disk also uses single-disk ZFS. Called &lt;code&gt;rpool&lt;&#x2F;code&gt; on the host.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Identify the disks,&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;# ls &#x2F;dev&#x2F;disk&#x2F;by-id
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;ata-WDC_WD140EDGZ-11_REDACTED_5UG
&lt;&#x2F;span&gt;&lt;span&gt;ata-WDC_WD140EDGZ-11_REDACTED_3WG
&lt;&#x2F;span&gt;&lt;span&gt;ata-WDC_WD140EDGZ-11_REDACTED_L2N
&lt;&#x2F;span&gt;&lt;span&gt;ata-WDC_WD140EDGZ-11_REDACTED_DAC
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Create the zfs pool with those disk ID&#x27;s, and do some minimal config&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;zpool create -f tank -o ashift=12 raidz1 ata-WDC_x_5UG ata-WDC_x_3WG ata-WDC_x_L2N ata-WDC_..._DAC
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;zfs set compression=lz4 tank
&lt;&#x2F;span&gt;&lt;span&gt;zfs set atime=off tank
&lt;&#x2F;span&gt;&lt;span&gt;zfs set acltype=posixacl tank
&lt;&#x2F;span&gt;&lt;span&gt;zfs set xattr=sa tank
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The idea is to create nested zfs file system datasets for  each type or group of data. This helps with isolation, tuning, backups etc.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;zfs create tank&#x2F;user1
&lt;&#x2F;span&gt;&lt;span&gt;zfs create tank&#x2F;user2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These should be visible inside the default mount points on root, i.e. &lt;code&gt;ls &#x2F;tank&#x2F;user1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Additional datasets can be nested using the same path notation. ZFS allows datasets to have different  compression&#x2F;encryption&#x2F;block size parameters, and I use the deepest dataset level as the &#x27;thing I&#x27;d pass to into a container&#x27;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sharing-storage-via-bind-mount&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#sharing-storage-via-bind-mount&quot; aria-label=&quot;Anchor link for: sharing-storage-via-bind-mount&quot;&gt;Sharing storage via bind-mount&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;To make filesharing half sane with various subsystems, create a series of groups &lt;strong&gt;on the host&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;These groups then have users assigned. These users are also created in the relevant end-user VM or LXC with the same GID:UID  properties, allowing for sane permissions management and mapping. This adds a level of control over the downstream user&#x27;s access to various sections of the storage solution.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;i.e. a &#x27;fileserver&#x27; LXC user responsible for providing network access via SAMBA&#x2F;NFS shares the user:group permissions of directories&#x2F;shares which make sense to expose as shares, whereas a gameserver container would only be provided access and permissions to a  specific dataset or subfolder etc.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We manually specify the group ID&#x27;s &lt;strong&gt;on the host&lt;&#x2F;strong&gt; to make things a bit easier to track. These are offset by &lt;code&gt;10000&lt;&#x2F;code&gt; to account for LXC unprivileged containers. On priv containers those groups can be created as needed.&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;code&gt;getent group&lt;&#x2F;code&gt; to list the groups and their ID&#x27;s.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;addgroup --gid 101020 storage-user1
&lt;&#x2F;span&gt;&lt;span&gt;addgroup --gid 101030 storage-user2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Use &lt;code&gt;groupdel group_name&lt;&#x2F;code&gt; to delete a group.&lt;&#x2F;p&gt;
&lt;p&gt;To apply the group over a directory, set permissions, and set the access control list:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;chgrp -R storage-user1 &#x2F;tank&#x2F;user1&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;chmod -R 2775 &#x2F;tank&#x2F;user1
&lt;&#x2F;span&gt;&lt;span&gt;# Optional if supported (not on the datasets I created this time)
&lt;&#x2F;span&gt;&lt;span&gt;  setfacl -Rm g:storage-user1:rwx,d:g:storage-user1:rwx &#x2F;tank&#x2F;user1
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;chgrp -R storage-user2 &#x2F;tank&#x2F;user2&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;chmod -R 2775 &#x2F;tank&#x2F;user2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When access to storage is needed in a LXC, bind mount setup is pretty straightforward.&lt;&#x2F;p&gt;
&lt;p&gt;From the &lt;strong&gt;host&#x27;s console&lt;&#x2F;strong&gt;, navigate to &lt;code&gt;&#x2F;etc&#x2F;pve&#x2F;lxc&lt;&#x2F;code&gt; and edit the &lt;code&gt;101.conf&lt;&#x2F;code&gt; or file matching the LXC we just made. Add the mount points as required as a new line each:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;mp0: &#x2F;tank&#x2F;user1,mp=&#x2F;mnt&#x2F;user1,size=0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Start the container up, and navigating to &lt;code&gt;&#x2F;mnt&lt;&#x2F;code&gt; should show the bound folder folder. We then need to map the UID and GID between the host and the container to allow consistent file permissions on the mapped directories. On the LXC,&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;addgroup --gid 1020 storage-user1
&lt;&#x2F;span&gt;&lt;span&gt;usermod -aG storage-user1 root
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Log-out and back in so the permissions can take effect. Test access by navigating to &lt;code&gt;&#x2F;mnt&#x2F;user1&lt;&#x2F;code&gt; and create&#x2F;edit some simple files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nas-container&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#nas-container&quot; aria-label=&quot;Anchor link for: nas-container&quot;&gt;NAS container&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Providing access to the file system for non-PBS backups is a partial use-case, so Samba and rsync are needed. I setup a tiny Ubuntu LXC to handle these roles.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;cockpit-project.org&quot;&gt;Red Hat&#x27;s Cockpit&lt;&#x2F;a&gt; is a lightweight, reasonably unobtrusive way to monitor and administer linux systems with a web GUI. It&#x27;s strength is the design philosophy of using standard Linux services&#x2F;config files, and only runs while a socket is made to the server.&lt;&#x2F;p&gt;
&lt;p&gt;Ubuntu &lt;a href=&quot;https:&#x2F;&#x2F;cockpit-project.org&#x2F;running#ubuntu&quot;&gt;instructions are here&lt;&#x2F;a&gt;, but as a quick reference:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;apt install cockpit curl
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It will run on port &lt;code&gt;9090&lt;&#x2F;code&gt; and uses the container&#x27;s Linux account credentials system for login.&lt;&#x2F;p&gt;
&lt;p&gt;45drives maintain some cockpit plugins to make identity and samba management easier.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;45Drives&#x2F;cockpit-identities&quot;&gt;45drives&#x2F;cockpit-identities&lt;&#x2F;a&gt;  and &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;45Drives&#x2F;cockpit-file-sharing&quot;&gt;45Drives&#x2F;cockpit-file-sharing&lt;&#x2F;a&gt; need to be installed.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;curl -sSL https:&#x2F;&#x2F;repo.45drives.com&#x2F;setup | sudo bash
&lt;&#x2F;span&gt;&lt;span&gt;apt update
&lt;&#x2F;span&gt;&lt;span&gt;apt install -y cockpit-identities cockpit-file-sharing cockpit-navigator
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For optional Windows&#x2F;network discover-ability, install &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;christgau&#x2F;wsdd&quot;&gt;wsdd&lt;&#x2F;a&gt; from Ubuntu&#x27;s package manager directly.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;apt install wsdd
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Samba share setup is reasonably standard at this point (i.e. frustrating to get perfect).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;network-setup&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#network-setup&quot; aria-label=&quot;Anchor link for: network-setup&quot;&gt;Network Setup&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;isolation-by-design&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#isolation-by-design&quot; aria-label=&quot;Anchor link for: isolation-by-design&quot;&gt;Isolation by design&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;At home, I segregate end-user devices from servers and management interfaces with VLANs, but I was keen to avoid a similar approach on the remote site to separate the &#x27;backup DMZ&#x27; from the local network.&lt;&#x2F;p&gt;
&lt;p&gt;The plan is reasonably intuitive:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Assign a second network adaptor to act as my &#x27;backup DMZ&#x27;&lt;&#x2F;li&gt;
&lt;li&gt;Setup a site-to-site VPN with Wireguard to connect the remote and home networks.&lt;&#x2F;li&gt;
&lt;li&gt;Allow traffic flow across the Wireguard bridge,&lt;&#x2F;li&gt;
&lt;li&gt;Setup a static route on my local network to allow me to access the remote DMZ network as if it were local.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Because the Microserver has 4 gigabit ethernet ports in addition to the management interface, I can also connect directly to the &#x27;isolated&#x27; network if I have hardware access. This would also make a lot of sense in a multi-wan environment.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&#x27;m aware this might be considered sub-optimal from a best-practices standpoint, but I&#x27;m happy enough with the level of security for a homelab use-case.&lt;&#x2F;p&gt;
&lt;p&gt;Talescale is an alternative option that can provide machine-to-machine connections without the same network bridging.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;site-to-site-vpn&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#site-to-site-vpn&quot; aria-label=&quot;Anchor link for: site-to-site-vpn&quot;&gt;Site-to-site VPN&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;To remotely access the backup server and it&#x27;s network, I run a Wireguard container which automatically attempts to connect to the Wireguard instance running on my VM host at home.&lt;&#x2F;p&gt;
&lt;p&gt;Because the connection is outbound only (aka a road-warrior), I don&#x27;t need to configure port-forwarding on the remote network, and it&#x27;s a controlled single point of contact between my &#x27;backup DMZ&#x27; and the local network it&#x27;s squatting in.&lt;&#x2F;p&gt;
&lt;p&gt;In Proxmox&#x27;s network page, I created an additional Linux bridge which was attached to the second ethernet adaptor, and assigned it &lt;code&gt;192.168.20.1&#x2F;24&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;proxmox-network.png&quot; alt=&quot;Proxmox network configuration page has two Linux bridges for two hardware ethernet ports&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;code&gt;vmbr1&lt;&#x2F;code&gt; interface is intended to act as the only network interface to my containers. Due to the &#x27;no remote network configuration&#x27; requirement, I did need to provide both interfaces to the Wireguard container for internet access.&lt;&#x2F;p&gt;
&lt;p&gt;By adding the adaptor in this manner, Proxmox makes it&#x27;s management interface available at &lt;code&gt;192.168.20.1&lt;&#x2F;code&gt;, which is useful if connecting via hardware on &lt;code&gt;eno2&lt;&#x2F;code&gt;, and will be useful later when we want to access Proxmox over our bridge.&lt;&#x2F;p&gt;
&lt;p&gt;First, we&#x27;ll add another client to the existing onsite Wireguard container to allow remote access,&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;### begin hpems-offsite ###
&lt;&#x2F;span&gt;&lt;span&gt;[Peer]
&lt;&#x2F;span&gt;&lt;span&gt;PublicKey = Gredacted=
&lt;&#x2F;span&gt;&lt;span&gt;PresharedKey = EredactedA=
&lt;&#x2F;span&gt;&lt;span&gt;AllowedIPs = 10.6.0.8&#x2F;32, 192.168.20.1&#x2F;24
&lt;&#x2F;span&gt;&lt;span&gt;PersistentKeepalive = 25
&lt;&#x2F;span&gt;&lt;span&gt;### end hpems-offsite ###
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then start preparing the offsite container.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;offsite-setup&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#offsite-setup&quot; aria-label=&quot;Anchor link for: offsite-setup&quot;&gt;Offsite setup&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;A simple Debian LXC container was spun up, and both Proxmox virtual bridges were added to it&#x27;s network configuration.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;vpn-networks.png&quot; alt=&quot;VPN container has both virtual networks passed in&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once wireguard was installed, the &lt;code&gt;&#x2F;etc&#x2F;wireguard&#x2F;wg0.conf&lt;&#x2F;code&gt; configuration looks something like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;[Interface]
&lt;&#x2F;span&gt;&lt;span&gt;PrivateKey = Gredacted2=
&lt;&#x2F;span&gt;&lt;span&gt;Address = 10.6.0.8&#x2F;24
&lt;&#x2F;span&gt;&lt;span&gt;MTU = 1200
&lt;&#x2F;span&gt;&lt;span&gt;DNS = 192.168.1.1, 9.9.9.9
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
&lt;&#x2F;span&gt;&lt;span&gt;PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
&lt;&#x2F;span&gt;&lt;span&gt;PostUp = iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;# Push two packets across the tunnel after opening it
&lt;&#x2F;span&gt;&lt;span&gt;PostUp = ping -c2 192.168.1.154
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
&lt;&#x2F;span&gt;&lt;span&gt;PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
&lt;&#x2F;span&gt;&lt;span&gt;PostDown = iptables -t nat -D POSTROUTING -o eth1 -j MASQUERADE
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;[Peer]
&lt;&#x2F;span&gt;&lt;span&gt;PublicKey = EredactedK=
&lt;&#x2F;span&gt;&lt;span&gt;PresharedKey = FredactedA=
&lt;&#x2F;span&gt;&lt;span&gt;Endpoint = redacted.duckdns.org:51820
&lt;&#x2F;span&gt;&lt;span&gt;AllowedIPs = 10.6.0.8&#x2F;24, 0.0.0.0&#x2F;0
&lt;&#x2F;span&gt;&lt;span&gt;PersistentKeepAlive=15
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The interface and peer are reasonably normal, but we&#x27;ve got a few extra bits of &lt;code&gt;iptables&lt;&#x2F;code&gt; network configuration in the &lt;code&gt;PostUp&lt;&#x2F;code&gt; and section which allow NAT traversal between the &lt;code&gt;eth0&lt;&#x2F;code&gt; and &lt;code&gt;eth1&lt;&#x2F;code&gt; interfaces.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, once the link is up, we ping the onsite VPN container to ensure some traffic is flowing over the VPN. The &lt;code&gt;PostDown&lt;&#x2F;code&gt; sections provide cleanup of the &lt;code&gt;PostUp&lt;&#x2F;code&gt; changes.&lt;&#x2F;p&gt;
&lt;p&gt;We also need to edit &lt;code&gt;&#x2F;etc&#x2F;sysctl.conf&lt;&#x2F;code&gt; and uncomment &lt;code&gt;net.ipv4.ip_forward=1&lt;&#x2F;code&gt; to allow IPv4 forwarding across the container&#x27;s networks. Activate the change with &lt;code&gt;sysctl -p&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Enable the VPN with &lt;code&gt;wg-quick up wg0&lt;&#x2F;code&gt; and &lt;code&gt;wg-quick down wg0&lt;&#x2F;code&gt; as typical. Also remember to open the wireguard link at startup.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sudo systemctl enable wg-quick@wg0.service
&lt;&#x2F;span&gt;&lt;span&gt;sudo systemctl daemon-reload
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;I originally had &lt;code&gt;wg-quick&lt;&#x2F;code&gt; fail with &lt;code&gt;&#x2F;usr&#x2F;bin&#x2F;wg-quick: line 32: resolvconf: command not found&lt;&#x2F;code&gt;. This was resolved by providing systemd&#x27;s resolver. I did this via symlink,&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;ln -s &#x2F;usr&#x2F;bin&#x2F;resolvectl &#x2F;usr&#x2F;local&#x2F;bin&#x2F;resolvconf
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;onsite-setup&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#onsite-setup&quot; aria-label=&quot;Anchor link for: onsite-setup&quot;&gt;Onsite Setup&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;We&#x27;ll also need to make sure traffic can be forwarded across the VPN,&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;# Masquerade rules
&lt;&#x2F;span&gt;&lt;span&gt;PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
&lt;&#x2F;span&gt;&lt;span&gt;PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On my home network, I setup a static route on my Unifi USG router to allow traffic flow between my local Wireguard container&#x27;s IP and the subnet used on the bridge network backing the remote DMZ (&lt;code&gt;192.168.20.0&#x2F;24&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;unifi-static-route.png&quot; alt=&quot;Unifi static route configuration provides next-hop between the local VPN container&amp;#39;s IP and the &quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This means that traffic attempting to access IP addresses in the remote DMZ subnet will be routed to the onsite Wireguard container.&lt;&#x2F;p&gt;
&lt;p&gt;We can see this redirection in action by running a traceroute between my workstation on the local network and a container on the remote DMZ,&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;scott@octagonal ~ $ traceroute 192.168.20.2
&lt;&#x2F;span&gt;&lt;span&gt;traceroute to 192.168.20.2 (192.168.20.2), 64 hops max
&lt;&#x2F;span&gt;&lt;span&gt;  1   192.168.1.1  0.410ms  0.327ms  0.331ms 
&lt;&#x2F;span&gt;&lt;span&gt;  2   192.168.1.154  0.843ms  0.403ms  0.392ms 
&lt;&#x2F;span&gt;&lt;span&gt;  3   192.168.20.2  9.962ms  8.651ms  9.945ms 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can also access the remote Proxmox management interface by browsing to &lt;code&gt;https:&#x2F;&#x2F;192.168.20.1:8006&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;accessing-the-internet-in-remote-dmz-containers&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#accessing-the-internet-in-remote-dmz-containers&quot; aria-label=&quot;Anchor link for: accessing-the-internet-in-remote-dmz-containers&quot;&gt;Accessing the internet in remote DMZ containers&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Because the remote machine has a separate but bridged network for all of my services, they don&#x27;t have direct access to the local internet (by design).&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, because there&#x27;s no software router running on the &lt;code&gt;192.168.20.1&#x2F;24&lt;&#x2F;code&gt; subnet, the remote containers need to be told how to access the &#x27;onsite&#x27; &lt;code&gt;192.168.1.1&lt;&#x2F;code&gt; resources via the bridge available at &lt;code&gt;192.168.20.2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;For ubuntu&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;ip route add 192.168.1.0&#x2F;24 via 192.168.20.2 dev eth0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;For debian&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;ip route add 192.168.1.0&#x2F;24 via 192.168.20.2 dev eth0 onlink
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This does have the minor downside that internet traffic on these remote containers is taking a pretty indirect route to the internet, but it&#x27;s only really for software updates.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;pbs&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#pbs&quot; aria-label=&quot;Anchor link for: pbs&quot;&gt;PBS&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;The setup of &lt;a href=&quot;https:&#x2F;&#x2F;forum.proxmox.com&#x2F;threads&#x2F;proxmox-backup-server-on-lxc-with-external-nas.79489&#x2F;&quot;&gt;PBS in an LXC&lt;&#x2F;a&gt; was fast and easy, so I won&#x27;t go into too much depth,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Provisioned a Debian container with 2 cores and 256MB of RAM&lt;&#x2F;li&gt;
&lt;li&gt;Installed PBS installed via the official channels.&lt;&#x2F;li&gt;
&lt;li&gt;Setup a bind-mount for a ZFS volume, and configured a datastore at the path in &lt;code&gt;&#x2F;mnt&#x2F;pbs&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Get the PBS fingerprint from the dashboard, and use it to add a new storage volume to the Proxmox VE machine pointing at the container&#x27;s IP.&lt;&#x2F;li&gt;
&lt;li&gt;Configure backup frequency and rules,&lt;&#x2F;li&gt;
&lt;li&gt;On the PBS webpage, setup prune and verification jobs to run periodically on the datastore.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The first backup ran overnight as the HP microserver only has a gigabit link, but since then I&#x27;ve been running remote backups every Monday, Wednesday and Saturday starting at 12:30am.&lt;&#x2F;p&gt;
&lt;p&gt;With my 50Mbps upload speed, the incremental backups normally take an hour or two to send the ~40GB deltas.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;isp-chart.png&quot; alt=&quot;Graph showing upload occurring in the early morning&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The PBS interface is reasonably well laid out, allowing visibility of the various containers&#x2F;VM&#x27;s and the different snapshots.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;pbs-list.png&quot; alt=&quot;List showing container backups in the datastore&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One neat benefit is the ability to introspect a LXC container&#x27;s file system from the web interface, which might be useful to cherrypick a specific file instead of running a full restoration of that container.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;hp-microserver-gen10plus&#x2F;lxc-filesystem.png&quot; alt=&quot;Browsing the file system of a LXC&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;closing-thoughts&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#closing-thoughts&quot; aria-label=&quot;Anchor link for: closing-thoughts&quot;&gt;Closing thoughts&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Whilst not the cheapest or most practical for all home-labs, I&#x27;ve got a far greater level of comfort by both improving the backup experience for Proxmox, as well as adding offsite file storage.&lt;&#x2F;p&gt;
&lt;p&gt;The setup of a full-time bridged remote network was a first for me, and I can&#x27;t say enough good things about the stability of the system and functionality available with modern open-source options.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Update: More than a year later everything is still going strong. I wouldn&#x27;t have changed my approach, other than setting up ZFS send&#x2F;recv for backing up my other files with snapshot support, instead of relying on rsync.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve restored a few containers without issue, and average a de-duplication factor of about 12.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tearing down a dead NEMA-23 Clearpath SC</title>
        <published>2021-12-22T00:00:00+00:00</published>
        <updated>2021-12-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Scott
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/clearpath-sc-teardown/"/>
        <id>/posts/clearpath-sc-teardown/</id>
        
        <content type="html" xml:base="/posts/clearpath-sc-teardown/">&lt;h1 id=&quot;but-how&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#but-how&quot; aria-label=&quot;Anchor link for: but-how&quot;&gt;But how???&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Cause of death - 6+ months of infrequent exposure to &#x27;fresh&#x27; water.&lt;&#x2F;p&gt;
&lt;p&gt;This particular model did have the additional waterproofing shaft seal, but the electrical connectors weren&#x27;t sealed with much care.&lt;&#x2F;p&gt;
&lt;p&gt;When it started throwing tracking error faults randomly, it was time to replace it.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;looking-inside-a-wet-clearpath&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#looking-inside-a-wet-clearpath&quot; aria-label=&quot;Anchor link for: looking-inside-a-wet-clearpath&quot;&gt;Looking inside a wet Clearpath&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;ve used a handful of different sized Teknic Clearpath servos from the MC, SD and SC ranges, and an opportunity to take a peek inside the integrated drive mounted to the back of the servo was too hard to resist.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;clearpath-motors.jpg&quot; alt=&quot;Clearpath SC servos mount the drive electronics inside a cast aluminium enclosure on the back of the motor&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Undoing the screws lets us pull the integrated drive unit off the back of the motor and frame.&lt;&#x2F;p&gt;
&lt;p&gt;Mounted to the servo side of the assembly is a PCB which acts as a mounting interface for the optical encoder and interfaces to the motor&#x27;s windings. The rest of the IO and drive electronics sit in the cast heatsink.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;drive-stack-split-from-encoder.jpg&quot; alt=&quot;Exposed PCB stack mounted to heatsink, 3 wires connected to a PCB on the motor assembly&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can already see some corrosion products sitting near the &#x27;bottom&#x27; of the heatsink.&lt;&#x2F;p&gt;
&lt;p&gt;Removing 6 more hex-screws separates the electronics stack.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;drive-stack-exposed.jpg&quot; alt=&quot;Electronics removed from heatsink is a 2-PCB setup using a board-to-board connector&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A better look at the extent of the corrosion products...&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;corrosion.jpg&quot; alt=&quot;White corrosion&#x2F;salts accumulated on bottom of both PCBs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &#x27;front&#x27; board has the optical encoder, IO and some power conditioning. The back of said board has mostly IO conditioning optocouplers etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;pcb-io-encoder.jpg&quot; alt=&quot;Internal PCB on page of paper, hole cutout for encoder shaft, black Molex Microfit connectors for IO and power&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;pcb-io-internal.jpg&quot; alt=&quot;Back face of encoder PCB with optocouplers, various SMD passives and some discrete regulation components&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The control microcontroller, gate drivers&#x2F;current shunts&#x2F;FETs are on the rear-most PCB.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;pcb-cpu-internal.jpg&quot; alt=&quot;Internal PCB with large microcontroller, board-to-board connector, 3 gate-driver ICs and 6 surface mount mosfets&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The rear-face of the control PCB has a cute thermal interface from the rest of the FETs, to a nicely machined step on the cast heatsink.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;thermal-pads.jpg&quot; alt=&quot;Rear of PCB with mosfets covered by white and orange thermal interface pad, electrolytic capacitors near edges, USB connector and LED&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The USB config port is also mounted here, along with some bulk capacitors which have pockets in the heatsink.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;posts&#x2F;clearpath-sc-teardown&#x2F;heatsink-internal.jpg&quot; alt=&quot;Cast aluminium heatsink with a vertical flat face with machining marsks, corrosion residue around corners and walls&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;closing-thoughts&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#closing-thoughts&quot; aria-label=&quot;Anchor link for: closing-thoughts&quot;&gt;Closing thoughts&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Running this servo so far out of spec in a wet environment worked far better than it had any right to, and packing the IO connectors of the replacement servo with dielectric grease seems to have prevented any repeated damage.&lt;&#x2F;p&gt;
&lt;p&gt;For the price, I&#x27;ve found the form factor and reliability of the Clearpath servos to make them a good choice for precision positioning, provided the mechanical system has sufficient external gearing and low total backlash.&lt;&#x2F;p&gt;
&lt;p&gt;The internal electronics design and integration reflects the solid design and build quality. Just wish the config and tuning software ran on something other than Windows...&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
