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

<channel>
	<title>Paul Bupe Jr, PhD</title>
	<atom:link href="https://paulbupejr.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://paulbupejr.com/</link>
	<description>Hardware, software, and everything in between</description>
	<lastBuildDate>Thu, 18 Apr 2024 16:50:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://paulbupejr.com/wp-content/uploads/2019/07/cropped-paul_logo@2x-32x32.png</url>
	<title>Paul Bupe Jr, PhD</title>
	<link>https://paulbupejr.com/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>R&#038;D Case Study: Developing the OptiGap Sensor System</title>
		<link>https://paulbupejr.com/developing-the-optigap-sensor-system/</link>
					<comments>https://paulbupejr.com/developing-the-optigap-sensor-system/#comments</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Wed, 10 Apr 2024 18:30:19 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Robotics]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[3d printer filament]]></category>
		<category><![CDATA[air gap]]></category>
		<category><![CDATA[bend localization]]></category>
		<category><![CDATA[fiber]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[localization]]></category>
		<category><![CDATA[microcontroller]]></category>
		<category><![CDATA[optigap]]></category>
		<category><![CDATA[optigap sensor system]]></category>
		<category><![CDATA[raspberry pi]]></category>
		<category><![CDATA[research]]></category>
		<category><![CDATA[robotics]]></category>
		<category><![CDATA[sensor]]></category>
		<category><![CDATA[Serial]]></category>
		<category><![CDATA[soft robotics]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[zeromq]]></category>
		<guid isPermaLink="false">https://paulbupejr.com/?p=890</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 9</span> <span class="rt-label rt-postfix">minutes</span></span>Update: You can follow the discussion of this article around the web on HN, Adafruit, Hackaday, and Hackster.io! This article explores the research and development journey behind my new sensor system, OptiGap, a key component of my PhD research. I&#8217;m writing this in a storytelling format to offer insights into my decision-making process and the &#8230; <a href="https://paulbupejr.com/developing-the-optigap-sensor-system/" class="more-link">Continue reading <span class="screen-reader-text">R&#38;D Case Study: Developing the OptiGap Sensor System</span></a></p>
<p>The post <a href="https://paulbupejr.com/developing-the-optigap-sensor-system/">R&amp;D Case Study: Developing the OptiGap Sensor System</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 9</span> <span class="rt-label rt-postfix">minutes</span></span>
<p><strong>Update</strong>: You can follow the discussion of this article around the web on <a href="https://news.ycombinator.com/item?id=40003710" target="_blank" rel="noreferrer noopener">HN</a>, <a href="https://blog.adafruit.com/2024/04/12/making-sensors-for-soft-robotic-applications/" target="_blank" rel="noreferrer noopener">Adafruit</a>, <a href="https://hackaday.com/2024/04/13/__trashed-9/" target="_blank" rel="noreferrer noopener">Hackaday</a>, and <a href="https://www.hackster.io/news/optigap-turns-3d-printer-filament-into-a-bend-sensing-and-localization-system-for-soft-robots-e3352509838d" target="_blank" rel="noreferrer noopener">Hackster.io</a>!</p>



<p>This article explores the research and development journey behind my new sensor system, <a href="https://ieeexplore.ieee.org/document/10161357" target="_blank" rel="noreferrer noopener">OptiGap</a>, a key component of my PhD research. I&#8217;m writing this in a storytelling format to offer insights into my decision-making process and the evolution leading to the final implementation. It should hopefully provide a glimpse into the sometimes-shrouded world of PhD research and may appeal to those curious about the process. For a deeper dive into technical specifics, simulations, and existing research on this subject, my dissertation is <a href="https://ir.library.louisville.edu/etd/4213/" target="_blank" rel="noreferrer noopener">available online here</a>.</p>



<span id="more-890"></span>



<h3 class="wp-block-heading">What does it do?</h3>



<p>In very general terms, this sensor is basically a rope that if bent can tell you where along its length you bent it. The fancy term for that is &#8220;bend localization.&#8221;</p>



<p>OptiGap&#8217;s application is mainly within the realm of soft robotics, which typically involves compliant (or &#8216;squishy&#8217;) systems, where the use of<a href="https://paulbupejr.com/autonomous-robot-design/"> traditional sensors</a> is often not practical. The name OptiGap, a fusion of &#8220;optical&#8221; and &#8220;gap,&#8221; reflects its core principle of utilizing air gaps within flexible optical light pipes to generate coded patterns essential for bend localization. </p>



<h2 class="wp-block-heading">How the OptiGap Sensor System Started</h2>



<p>The idea for OptiGap came about while I was experimenting with light transmission through various light pipes (optical cables) for use as a bend detection sensor. I was initially trying to see how I could effectively &#8220;slow down&#8221; light through the fiber&#8230;a seemingly straightforward task, right?</p>



<p>During this process, I attached a section of clear 3D printer filament (1.75mm TPU) to a piece of tape measure for an experiment and incidentally discovered that when I bent the tape measure (and filament) at the spot where the electrical tape was attached, there was a significant drop in light transmission. I hypothesized that this was because the sticky residue of the electrical tape was causing the filament to stretch, which in turn reduced the light transmission.</p>



<p>To verify this hypothesis, I attached a longer piece of TPU to a tape measure and began bending it at various points to observe how light transmission would change.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e94e6b2&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e94e6b2" class="aligncenter size-large wp-lightbox-container"><img fetchpriority="high" decoding="async" width="768" height="1024" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/black_tape-768x1024.jpg" alt="Tape measure experiment for OptiGap" class="wp-image-891" style="aspect-ratio:4/3;object-fit:cover" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/black_tape-768x1024.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/black_tape-225x300.jpg 225w, https://paulbupejr.com/wp-content/uploads/2024/04/black_tape-1152x1536.jpg 1152w, https://paulbupejr.com/wp-content/uploads/2024/04/black_tape-1536x2048.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/black_tape-scaled.jpg 1920w" sizes="(max-width: 768px) 100vw, 768px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Tape measure experiment with clear TPU filament.</figcaption></figure>
</div>


<p>I wrote a small Linux I2C driver for the <a href="https://www.st.com/en/imaging-and-photonics-solutions/vl53l0x.html">VL53L0X </a>ToF sensor to run on a <a href="https://zeromq.org/" target="_blank" rel="noreferrer noopener">Raspberry Pi</a> and push the data to a socket using <a href="https://zeromq.org/">ZeroMQ</a>. I then created a rough GUI in Python to pull the sensor data from the socket and visualize the light transmission data in realtime, shown in the GIF below, which very quickly validated my hypothesis. This validation marked the &#8220;Eureka!&#8221; moment that sparked the eventual development of the OptiGap sensor.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/tape.gif" alt="Initial OptiGap discovery" class="wp-image-893"/><figcaption class="wp-element-caption">My excited face while validating my discovery.</figcaption></figure>



<h2 class="wp-block-heading">The OptiGap Realization</h2>



<p>I realized that since I could control where the light was being attenuated, I could use this to encode information about the position of the bend on the sensor. Using electrical tape was not a practical solution, so I started looking for a more reliable and consistent way to create these attenuations. This led me to the idea of cutting the filament and then reattaching it together using a flexible rubber (silicone) sleeve, leaving a small air gap, as shown in the image below.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e94ef70&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e94ef70" class="wp-block-image size-large wp-lightbox-container"><img decoding="async" width="1024" height="337" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/tpu_gap-1024x337.jpg" alt="Proof-of-concept showing a light pipe with an air in a silicone sleeve." class="wp-image-895" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/tpu_gap-1024x337.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/tpu_gap-300x99.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/tpu_gap-768x252.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/tpu_gap-1536x505.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/tpu_gap.jpg 1600w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Proof-of-concept showing a light pipe with an air gap in a silicone sleeve.</figcaption></figure>



<p>The main working principle of the air gap is that translation and/or rotation of one light pipe face relative to the other changes the fraction of light transmitted across the gap. The greater the bend angle, the more light escapes across the gap. The resulting change in intensity of the optical signal can then be correlated with known patterns for use as a sensor.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e94f2be&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e94f2be" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="633" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/operating_principle-1024x633.png" alt="OptiGap operating principle" class="wp-image-896" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/operating_principle-1024x633.png 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/operating_principle-300x185.png 300w, https://paulbupejr.com/wp-content/uploads/2024/04/operating_principle-768x474.png 768w, https://paulbupejr.com/wp-content/uploads/2024/04/operating_principle-1536x949.png 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/operating_principle-825x510.png 825w, https://paulbupejr.com/wp-content/uploads/2024/04/operating_principle.png 1693w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">This image is from a COMSOL simulation I made.</figcaption></figure>



<h2 class="wp-block-heading">The Big Idea</h2>



<p>I then proceeded to test this idea by creating multiple air gaps in a row and bending the filament to measure the attenuation.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e94f688&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e94f688" class="wp-block-image size-large is-style-default wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="631" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/tpu_tof-1-1024x631.jpg" alt="Multiple air gaps along a single TPU lightpipe" class="wp-image-898" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/tpu_tof-1-1024x631.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/tpu_tof-1-300x185.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/tpu_tof-1-768x474.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/tpu_tof-1-1536x947.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/tpu_tof-1-2048x1263.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Multiple air gaps along a single TPU lightpipe.</figcaption></figure>



<p>As depicted in the GIF below, the optical intensity decreases at each air gap, with a more noticeable decrease as the bend angle increases. This initial experimentation served as proof of concept, demonstrating the feasibility of the idea. It led to the formulation of my final hypothesis of <strong>utilizing a pattern of these air gaps to encode information regarding the sensor&#8217;s bending and employing a naive Bayes classifier on a microcontroller to decode the bend location.</strong></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/gaps.gif" alt="Validating the attenuation at the air gaps." class="wp-image-899"/><figcaption class="wp-element-caption">Validating the attenuation at the air gaps.</figcaption></figure>



<p>This concept resembles the functionality of a linear encoder. Linear encoders gauge an object&#8217;s linear movement, typically comprising a slider rail with a coded scale akin to a measuring ruler and a sensing head that moves across this scale to read it. Linear (absolute) encoders emit a distinct code at each position, ensuring consistent identification of displacement.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e94fb13&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e94fb13" class="aligncenter size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="519" height="417" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/block_diagram.png" alt="OptiGap system overview." class="wp-image-900" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/block_diagram.png 519w, https://paulbupejr.com/wp-content/uploads/2024/04/block_diagram-300x241.png 300w" sizes="auto, (max-width: 519px) 100vw, 519px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">OptiGap system overview.</figcaption></figure>
</div>


<p>The OptiGap system, functioning like an absolute encoder, would encode absolute positions using patterns of bend-sensitive air gaps along parallel light pipes, effectively serving as a singular fiber optic sensor.</p>



<h3 class="wp-block-heading"><strong>Encoding the Bend Location using Inverse Gray Code</strong></h3>



<p>Absolute encoders commonly employ Gray code, a binary system where two successive values differ in only one bit. This property allows for various applications, including error checking. However, Gray code isn&#8217;t optimal for the OptiGap sensor system. Here, we aim for consecutive values to differ by the maximum number of bits to facilitate easier differentiation. This necessity gave rise to Inverse Gray code.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img loading="lazy" decoding="async" width="300" height="180" src="https://paulbupejr.com/wp-content/uploads/2024/04/Gray-Code-300x180.jpg" alt="" class="wp-image-902" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/Gray-Code-300x180.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/Gray-Code-1024x615.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/Gray-Code-768x461.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/Gray-Code.jpg 1176w" sizes="auto, (max-width: 300px) 100vw, 300px" /></figure>
</div>


<p>Inverse Gray code is a binary code where two successive values differ by the maximum (n-1) number of bits. To implement this, I simply create cuts in the filament wherever there&#8217;s a &#8220;1&#8221; in the Inverse Gray code sequence. This approach can scale to any bit number. For the prototype, I utilized 3 bits, providing 8 possible positions.</p>



<h3 class="wp-block-heading">Visualization of the OptiGap Sensor System</h3>



<p>The illustration below depicts the signal patterns of the OptiGap sensor system for each bend position using three fibers. By employing a naive Bayes classifier, the sensor system can discern bend positions based on signal patterns. The third graph represents actual sensor data from the prototype system, utilized for training the classifier on the microcontroller.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e9500b0&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e9500b0" class="aligncenter size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="519" height="448" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/signal_patterns.png" alt="OptiGap bending patterns." class="wp-image-903" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/signal_patterns.png 519w, https://paulbupejr.com/wp-content/uploads/2024/04/signal_patterns-300x259.png 300w" sizes="auto, (max-width: 519px) 100vw, 519px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">OptiGap bending patterns.</figcaption></figure>
</div>


<h2 class="wp-block-heading">The OptiGap Prototype</h2>



<p>I proceeded to construct a prototype of the OptiGap sensor system, utilizing 3 strands of clear TPU 3D printer filament, each featuring a distinct pattern of air gaps. The image below showcases the filament just before cutting, with the cut pattern indicated on a piece of tape.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e950477&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e950477" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="156" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/making_cuts-1024x156.jpg" alt="Beginning stages of an OptiGap sensor prototype." class="wp-image-905" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/making_cuts-1024x156.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/making_cuts-300x46.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/making_cuts-768x117.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/making_cuts-1536x234.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/making_cuts-2048x312.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Beginning stages of an OptiGap sensor prototype.</figcaption></figure>



<p>For the prototype, I employed a commercial 3:1 fiber optic coupler to merge the light from the 3 strands into a single fiber optic cable, resulting in the completion of the sensor prototype, as depicted below.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e9507e5&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e9507e5" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="842" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/first_assembled_prototype-1024x842.jpg" alt="Assembled sensing head of an OptiGap sensor." class="wp-image-906" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/first_assembled_prototype-1024x842.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/first_assembled_prototype-300x247.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/first_assembled_prototype-768x632.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/first_assembled_prototype-1536x1264.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/first_assembled_prototype-2048x1685.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Assembled sensing head of an OptiGap sensor.</figcaption></figure>



<p>This marked the final phase of validating the hypothesis and operational theory behind the OptiGap sensor.</p>



<h3 class="wp-block-heading">Reducing the Physical Size</h3>



<p>The initial prototype proved to be large and bulky, primarily due to the size of the 3D printer filament used. Drawing from previous experience, I recognized that PMMA (plastic) optical fiber offered a smaller and more flexible alternative suitable for this application. Consequently, I assessed 500, 750, and 1000 micron unjacketed PMMA optical fibers from Industrial Fiber Optics, Inc. for the sensor strands, resulting in a significant reduction in sensor size.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e950b9e&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e950b9e" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="544" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/fiber_label-1024x544.jpg" alt="500 micron PMMA fiber spool." class="wp-image-907" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/fiber_label-1024x544.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/fiber_label-300x159.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/fiber_label-768x408.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/fiber_label-1536x815.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/fiber_label-2048x1087.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">500 micron PMMA fiber spool.</figcaption></figure>



<p>I conducted tests on all three types of fibers to evaluate their light transmission and flexibility. Among them, the 500 micron fiber emerged as the optimal choice overall, although all three exhibited sufficient flexibility for this application.</p>



<h3 class="wp-block-heading"><strong>Reducing the Optical Transceiver Complexity</strong></h3>



<p>I decided to switch from using the complex VL53L0X ToF sensor to a simple photodiode and IR LED setup to reduce the complexity of the system and to increase modularity. This also allowed me to use a &nbsp;microcontroller to read the sensor data, which was a significant improvement over the initial prototype.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e950f54&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e950f54" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="792" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/new_fiber_tx-1024x792.jpg" alt="IR LED prototype board." class="wp-image-908" style="aspect-ratio:4/3;object-fit:cover" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/new_fiber_tx-1024x792.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/new_fiber_tx-300x232.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/new_fiber_tx-768x594.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/new_fiber_tx-1536x1188.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/new_fiber_tx-2048x1584.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">IR LED prototype board with 1000 micron PMMA fiber.</figcaption></figure>



<p>I then created a demo system for the sensor based around an STM32 microcontroller and a photodiode/IR LED setup.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e9512c4&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e9512c4" class="aligncenter size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="519" height="298" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/demo_system.png" alt="Full OptiGap demo system using 500 micron PMMA fiber." class="wp-image-909" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/demo_system.png 519w, https://paulbupejr.com/wp-content/uploads/2024/04/demo_system-300x172.png 300w" sizes="auto, (max-width: 519px) 100vw, 519px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Full OptiGap demo system using 500 micron PMMA fiber.</figcaption></figure>
</div>


<h2 class="wp-block-heading"><strong>Realtime Machine Learning on a Microcontroller</strong></h2>



<p>The final stage in developing the OptiGap sensor system involved integrating a naive Bayes classifier onto the STM32 microcontroller to decode the bend location from the sensor data. <strong><em>I opted for a naive Bayes classifier due to its efficiency compared to if-statements or lookup tables, its capability to handle new or previously unseen data, and its potential for increased accuracy by considering relationships between multiple input variables.</em></strong></p>



<p>Implementing the naive Bayes classifier proved to be relatively straightforward. This classifier is a probabilistic model based on applying Bayes&#8217; theorem to determine how a measurement can be assigned to a particular class, with the class representing the bend location in this context. I utilized the <a href="https://www.arm.com/technologies/cmsis">Arm CMSIS-DSP library</a> for the classifier implementation.</p>



<h3 class="wp-block-heading">Fitting the Sensor Data</h3>



<p>The initial step in integrating the classifier was to fit the sensor data to a Gaussian distribution for each air gap pattern. To expedite this process, I developed a Python GUI for rapid labeling and fitting of the data using GNB (Gaussian Naive Bayes) from the scikit-learn library.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e9516cc&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e9516cc" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="452" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/ui_2-1024x452.jpg" alt="Initial data labeling and fitting UI." class="wp-image-910" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/ui_2-1024x452.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/ui_2-300x132.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/ui_2-768x339.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/ui_2.jpg 1431w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Initial data labeling and fitting UI.</figcaption></figure>



<p>I later improved this UI to be more general and to allow for more complex data fitting.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e951a0f&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e951a0f" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="511" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/ui-1024x511.jpg" alt="Improved UI." class="wp-image-911" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/ui-1024x511.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/ui-300x150.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/ui-768x383.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/ui.jpg 1453w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Improved UI.</figcaption></figure>



<p>The probabilities for each class were computed and saved as a header for use on the microcontroller.</p>



<h3 class="wp-block-heading">Filtering the Sensor Data</h3>



<p>To enhance the accuracy of the classifier, I implemented a two-stage filtering process on the STM32 . The initial stage involved a basic moving average filter, followed by a Kalman filter in the second stage. </p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e951dd6&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e951dd6" class="aligncenter size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="554" height="190" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/dsp.jpg" alt="Signal filtering stages." class="wp-image-913" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/dsp.jpg 554w, https://paulbupejr.com/wp-content/uploads/2024/04/dsp-300x103.jpg 300w" sizes="auto, (max-width: 554px) 100vw, 554px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Signal filtering stages. Noise reduction relative to input signal.</figcaption></figure>
</div>


<h2 class="wp-block-heading">The OptiGap Sensor System Demo</h2>



<p>The GIFs provided below illustrate various stages of the OptiGap sensor system, encompassing assembly and the operational demonstration of the final sensor system.</p>



<h4 class="wp-block-heading has-text-align-center">System Overview</h4>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/System_Overview.gif" alt="" class="wp-image-914"/></figure>



<h4 class="wp-block-heading has-text-align-center">Assembly of an OptiGap Sensor using TPU Filament</h4>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/Assembly.gif" alt="" class="wp-image-915"/></figure>



<h4 class="wp-block-heading has-text-align-center">Attenuation of Light through the OptiGap Sensor</h4>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/Attenuation.gif" alt="" class="wp-image-916"/></figure>



<h4 class="wp-block-heading has-text-align-center"><strong>Fitting of the Sensor Data</strong></h4>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/Training.gif" alt="" class="wp-image-918"/></figure>



<h4 class="wp-block-heading has-text-align-center"><strong>Segment Classification using PMMA Optical Fiber</strong></h4>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/Segment_Classification.gif" alt="" class="wp-image-919"/></figure>



<h4 class="wp-block-heading has-text-align-center"><strong>Segment Classification using TPU Filament</strong></h4>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/Validation.gif" alt="" class="wp-image-920"/></figure>



<h4 class="wp-block-heading has-text-align-center"><strong>Underwater Operation</strong></h4>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="450" src="https://paulbupejr.com/wp-content/uploads/2024/04/Underwater_Validation.gif" alt="" class="wp-image-921"/></figure>



<h2 class="wp-block-heading">OptiGap Design Specifications</h2>



<h3 class="wp-block-heading has-text-align-center">Key Properties &amp; Parameters</h3>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="191" src="https://paulbupejr.com/wp-content/uploads/2024/04/properties-1024x191.png" alt="" class="wp-image-979" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/properties-1024x191.png 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/properties-300x56.png 300w, https://paulbupejr.com/wp-content/uploads/2024/04/properties-768x143.png 768w, https://paulbupejr.com/wp-content/uploads/2024/04/properties.png 1176w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading has-text-align-center">Material Recommendations</h3>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="636" src="https://paulbupejr.com/wp-content/uploads/2024/04/materails-1024x636.png" alt="" class="wp-image-980" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/materails-1024x636.png 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/materails-300x186.png 300w, https://paulbupejr.com/wp-content/uploads/2024/04/materails-768x477.png 768w, https://paulbupejr.com/wp-content/uploads/2024/04/materails.png 1174w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h2 class="wp-block-heading">Next Steps</h2>



<p>I&#8217;ve made significant progress on the OptiGap system beyond what&#8217;s documented here, including its integration into another modular actuation and sensing system I developed called EneGate.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e9529d4&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e9529d4" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="814" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap-1024x814.jpg" alt="" class="wp-image-922" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap-1024x814.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap-300x239.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap-768x611.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap-1536x1221.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap-2048x1628.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">My EneGate PCB integrating an OptiGap sensor.</figcaption></figure>



<p>This has involved custom PCB design and systems integration, detailed in my dissertation. Additionally, I&#8217;ve prototyped miniature PCB versions of the optics to interface with the PCBs for the EneGate system.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e952d62&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e952d62" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="768" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" data-id="924" src="https://paulbupejr.com/wp-content/uploads/2024/04/daughterboard-1024x768.jpg" alt="" class="wp-image-924" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/daughterboard-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2024/04/daughterboard-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/daughterboard-768x576.jpg 768w, https://paulbupejr.com/wp-content/uploads/2024/04/daughterboard-1536x1152.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2024/04/daughterboard.jpg 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Mini OptiGap PCB</figcaption></figure>



<figure data-wp-context="{&quot;imageId&quot;:&quot;69e7b5e9530bf&quot;}" data-wp-interactive="core/image" data-wp-key="69e7b5e9530bf" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="907" height="599" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on-window--resize="callbacks.setButtonStyles" data-id="923" src="https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap_pcb.jpg" alt="" class="wp-image-923" srcset="https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap_pcb.jpg 907w, https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap_pcb-300x198.jpg 300w, https://paulbupejr.com/wp-content/uploads/2024/04/enegate_optigap_pcb-768x507.jpg 768w" sizes="auto, (max-width: 907px) 100vw, 907px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			aria-label="Enlarge"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.imageButtonRight"
			data-wp-style--top="state.imageButtonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">Another mini OptiGap PCB</figcaption></figure>
</figure>



<p>I&#8217;ve also validated OptiGap on a real-world soft robotic system, with full details set to be presented in an upcoming RoboSoft paper titled &#8220;<strong><em>Embedded Optical Waveguide Sensors for Dynamic Behavior Monitoring in Twisted-Beam Structures.</em></strong>&#8220;</p>



<h3 class="wp-block-heading"><strong>Commercialization</strong></h3>



<p>There&#8217;s an ongoing commercialization aspect to this research as well. Feel free to reach out if you&#8217;re interested in further details.</p>



<h2 class="wp-block-heading">That&#8217;s it for now!</h2>



<p>I don&#8217;t want to make this too long so I&#8217;ll end here. I hope this provided some insight into the research and development process involved in something like this. If you have any questions or would like to learn more, don&#8217;t hesitate to contact me!</p>
<p>The post <a href="https://paulbupejr.com/developing-the-optigap-sensor-system/">R&amp;D Case Study: Developing the OptiGap Sensor System</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/developing-the-optigap-sensor-system/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Disable TP-Link Tapo Camera IR LEDs</title>
		<link>https://paulbupejr.com/disable-tp-link-tapo-camera-ir-leds/</link>
					<comments>https://paulbupejr.com/disable-tp-link-tapo-camera-ir-leds/#comments</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Wed, 20 Dec 2023 00:32:59 +0000</pubDate>
				<category><![CDATA[Repairs]]></category>
		<category><![CDATA[TP-Link]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[ir led]]></category>
		<category><![CDATA[security camera]]></category>
		<category><![CDATA[soldering]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[tapo c110]]></category>
		<category><![CDATA[tp-link tapo]]></category>
		<guid isPermaLink="false">https://paulbupejr.com/?p=858</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 3</span> <span class="rt-label rt-postfix">minutes</span></span>This post quickly covers how I disabled (removed) the IR LEDs on several Tapo C110 cameras I own. This was to use them behind a window without the IR LEDs&#8217; glare ruining the video. The Tapo C110 is an excellent small WiFi security camera, boasting up to 2K resolution, local continuous SD card recording, and &#8230; <a href="https://paulbupejr.com/disable-tp-link-tapo-camera-ir-leds/" class="more-link">Continue reading <span class="screen-reader-text">Disable TP-Link Tapo Camera IR LEDs</span></a></p>
<p>The post <a href="https://paulbupejr.com/disable-tp-link-tapo-camera-ir-leds/">Disable TP-Link Tapo Camera IR LEDs</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 3</span> <span class="rt-label rt-postfix">minutes</span></span>
<p>This post quickly covers how I disabled (removed) the IR LEDs on several Tapo C110 cameras I own. This was to use them behind a window without the IR LEDs&#8217; glare ruining the video. The Tapo C110 is an excellent small WiFi security camera, boasting up to 2K resolution, local continuous SD card recording, and two local RSTP streams. Most importantly, it works perfectly fine without an internet connection once configured, fitting my use-case. A significant drawback of the camera is the need to completely disable the night vision mode to turn off the IR LEDs. This means you can&#8217;t use the night vision mode while the camera is behind a window. Thankfully its easy to disable Tapo camera IR LEDs!</p>



<span id="more-858"></span>



<h2 class="wp-block-heading has-medium-font-size">The Official (lack of a) Solution</h2>



<p>A <a href="https://community.tp-link.com/en/smart-home/forum/topic/256060">discussion has been ongoing</a> since 2021 on the TP-Link forum regarding this issue. The official TP-Link support recommends disabling night vision mode entirely. Meanwhile, the most popular suggestion among forum users involves covering the LEDs with tape. However, this is often ineffective due to light leaking around and through the tape since the LEDs are inset. <strong><em>My guess for why this hasn&#8217;t been addressed with a straightforward firmware update is that the camera&#8217;s design links the digital output controlling the IR filter to the IR LEDs.</em></strong> As a result, they cannot be independently deactivated, representing a significant design flaw if true!</p>



<h2 class="wp-block-heading has-medium-font-size">Opening the Camera</h2>



<p>Opening the camera is just a matter of using a prying tool along the front edge of the camera and the front plate will pop off &#8212; there are four clips, one along each side. It&#8217;s okay to use a bit of force, you won&#8217;t break it (don&#8217;t quote me on that). Conveniently, the LEDs are on a daughter board that connects to the PCB.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="618" src="https://paulbupejr.com/wp-content/uploads/2023/12/tapo-1-1-1024x618.jpg" alt="" class="wp-image-871" srcset="https://paulbupejr.com/wp-content/uploads/2023/12/tapo-1-1-1024x618.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2023/12/tapo-1-1-300x181.jpg 300w, https://paulbupejr.com/wp-content/uploads/2023/12/tapo-1-1-768x464.jpg 768w, https://paulbupejr.com/wp-content/uploads/2023/12/tapo-1-1-1536x928.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2023/12/tapo-1-1-2048x1237.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading has-medium-font-size">The Simple (slightly broken) Solution to Disable Tapo Camera IR LEDs</h2>



<p><strong><em>If you don&#8217;t mind losing the microphone and indicator LED</em></strong> you can simply remove the daughter board PCB entirely and the camera will still function. This allows the use of night vision mode without the IR LEDs causing reflections on the glass.</p>



<h2 class="wp-block-heading has-medium-font-size">The Less Simple (more functional) Solution to Disable Tapo Camera IR LEDs</h2>



<p>A more comprehensive approach involves desoldering the IR LEDs. This is relatively straightforward with tools like a hot air tool, heat gun, toaster oven, or even a stove and pan. I wouldn&#8217;t recommend using a soldering iron; the PCB&#8217;s heat sink properties mean that the LEDs may be damaged before the solder melts enough. I used a hot air tool on the PCB&#8217;s rear, directly behind an LED, and gently pulled on the LED with tweezers. The LEDs detached after a few seconds of heating.<strong> KEEP THE LEDs</strong>!</p>



<p>There are two hardware versions of the C110. Version 1 has three LEDs, while version 2 has two. I have one of each version, and found the LEDs in both easy to remove.</p>



<h2 class="wp-block-heading has-medium-font-size">Reversing the Changes</h2>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="621" src="https://paulbupejr.com/wp-content/uploads/2023/12/tapo-3-1-1024x621.jpg" alt="" class="wp-image-873" srcset="https://paulbupejr.com/wp-content/uploads/2023/12/tapo-3-1-1024x621.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2023/12/tapo-3-1-300x182.jpg 300w, https://paulbupejr.com/wp-content/uploads/2023/12/tapo-3-1-768x465.jpg 768w, https://paulbupejr.com/wp-content/uploads/2023/12/tapo-3-1-1536x931.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2023/12/tapo-3-1-2048x1241.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>If you decide to reverse these modifications, you can easily solder the LEDs back on or reattach the PCB. I ultimately reversed this change for all my cameras once they were no longer needed for window surveillance. Resoldering the LEDs is doable without extra solder, but I suggest using at least a bit of flux for better results. I personally applied a small dab of solder paste. For the resoldering process, I used a hot plate. It&#8217;s crucial to align the pads on the PCB with that on the LED by size to ensure correct polarity.</p>
<p>The post <a href="https://paulbupejr.com/disable-tp-link-tapo-camera-ir-leds/">Disable TP-Link Tapo Camera IR LEDs</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/disable-tp-link-tapo-camera-ir-leds/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Soldering to Shape Memory Alloy (SMA) Wire is Really Hard</title>
		<link>https://paulbupejr.com/soldering-to-shape-memory-alloy-sma-wire-is-really-hard/</link>
					<comments>https://paulbupejr.com/soldering-to-shape-memory-alloy-sma-wire-is-really-hard/#respond</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Mon, 23 May 2022 18:26:08 +0000</pubDate>
				<category><![CDATA[Theory]]></category>
		<category><![CDATA[anisotropic]]></category>
		<category><![CDATA[nitinol]]></category>
		<category><![CDATA[nitinol wire]]></category>
		<category><![CDATA[SCRAM]]></category>
		<category><![CDATA[scrambots]]></category>
		<category><![CDATA[sem]]></category>
		<category><![CDATA[shape memory alloy]]></category>
		<category><![CDATA[shape memory alloy wire]]></category>
		<category><![CDATA[sma]]></category>
		<category><![CDATA[sma flux]]></category>
		<category><![CDATA[sma solder]]></category>
		<category><![CDATA[sma soldering]]></category>
		<category><![CDATA[sma wire]]></category>
		<category><![CDATA[solder]]></category>
		<guid isPermaLink="false">https://paulbupejr.com/?p=813</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 2</span> <span class="rt-label rt-postfix">minutes</span></span>Over the past couple of years we&#8217;ve been working on a rather cool new class of robots called Soft Curved Reconfigurable Anisotropic Mechanism(s), or SCRAM, under this National Science Foundation EFRI project. For my latest paper, Electronically Reconfigurable Virtual Joints by Shape Memory Alloy-Induced Buckling of Curved Sheets, I spent a lot of time working &#8230; <a href="https://paulbupejr.com/soldering-to-shape-memory-alloy-sma-wire-is-really-hard/" class="more-link">Continue reading <span class="screen-reader-text">Soldering to Shape Memory Alloy (SMA) Wire is Really Hard</span></a></p>
<p>The post <a href="https://paulbupejr.com/soldering-to-shape-memory-alloy-sma-wire-is-really-hard/">Soldering to Shape Memory Alloy (SMA) Wire is Really Hard</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 2</span> <span class="rt-label rt-postfix">minutes</span></span>
<p>Over the past couple of years<a href="https://www.scrambots.com/team" target="_blank" rel="noreferrer noopener"> we&#8217;ve</a> been working on a rather cool new class of robots called Soft Curved Reconfigurable Anisotropic Mechanism(s), or SCRAM, under this <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=1935324&amp;HistoricalAwards=false" target="_blank" rel="noreferrer noopener">National Science Foundation EFRI project</a>. For my latest paper, <a href="https://ieeexplore.ieee.org/document/9763962" target="_blank" rel="noreferrer noopener">Electronically Reconfigurable Virtual Joints by Shape Memory Alloy-Induced Buckling of Curved Sheets</a>, I spent a lot of time working with shape memory alloy (SMA) wire while developing a SCRAM device. Much of this time was spent trying to figure out exactly how to solder to SMA wire, specifically a nickel (Ni) &#8211; titanium (Ti) alloy called nitinol. My conclusion after all that time? Soldering to SMA wire is really hard! </p>



<span id="more-813"></span>



<h4 class="wp-block-heading">Visualizing an SMA Wire Solder Joint</h4>



<p>Soldering to SMA wire is hard due to the tough oxide layer on the surface. Solder beads off the wire as if trying to solder to glass! This can be seen in the two SEM images below (shout-out to the research facilities at the University of Louisville). I prepared two samples by tying some stranded wire around a piece of SMA wire (with the oxide layer ground off) and a piece of standard hook-up wire (tin-coated copper). I then applied some non-acidic flux followed by a healthy blob of tin/silver solder. Finally, I ground down one surface of each wire in order to perform some cross-sectional imaging. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="459" src="https://paulbupejr.com/wp-content/uploads/2022/05/comparison-1024x459.png" alt="Soldering to sma wire" class="wp-image-826" srcset="https://paulbupejr.com/wp-content/uploads/2022/05/comparison-1024x459.png 1024w, https://paulbupejr.com/wp-content/uploads/2022/05/comparison-300x134.png 300w, https://paulbupejr.com/wp-content/uploads/2022/05/comparison-768x344.png 768w, https://paulbupejr.com/wp-content/uploads/2022/05/comparison.png 1313w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>It&#8217;s apparent from the images that there is no bond to the SMA wire  (right) while the regular wire (left) has a great bond! </p>



<p></p>



<h4 class="wp-block-heading">Soldering to SMA wire</h4>



<p>The &#8220;easy&#8221; solution is to use a really aggressive acidic flux to eat away the oxide layer when soldering. The main disadvantage of this is the need to <strong>thoroughly </strong>wash the joint with water after soldering. Acidic flux will keep eating away long after soldering so it must be completely washed off! Another option is to use an inert gas as shielding while soldering (as in MIG welding) after grinding away the oxide layer. This again is not practical for most applications. </p>



<p>Here are some tips for soldering to SMA wire without acidic flux based on my aforementioned soldering adventures:</p>



<ul class="wp-block-list"><li>Grind off the oxide layer first to improve wetting. </li><li>Crimping is king. If possible, join wires with a crimp and then apply solder. This produces the most reliable connections.</li><li>&#8220;Tie&#8221; the wire once around the SMA first to create a mechanical hold then apply solder.</li><li>Use a silver alloy solder to increase the chances of proper wetting.</li><li>Use the lowest temperature possible for the solder since heating up the SMA too high will cause an oxide buildup.</li></ul>



<p><a href="https://superiorflux.com/soldering-stainless-steel-components-pcb/" target="_blank" rel="noreferrer noopener">These techniques</a> for soldering to stainless steel actually apply to SMA wire as well so they are worth studying. </p>



<hr class="wp-block-separator"/>



<p><a href="https://harnettlab.org/join-the-lab/" target="_blank" rel="noreferrer noopener">If you enjoy research and things like this interest you then take a look at our lab page for some potential opportunities!</a></p>
<p>The post <a href="https://paulbupejr.com/soldering-to-shape-memory-alloy-sma-wire-is-really-hard/">Soldering to Shape Memory Alloy (SMA) Wire is Really Hard</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/soldering-to-shape-memory-alloy-sma-wire-is-really-hard/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Easy Raspberry Pi Pico Microcontroller C / C++ Programming on Windows</title>
		<link>https://paulbupejr.com/raspberry-pi-pico-windows-development/</link>
					<comments>https://paulbupejr.com/raspberry-pi-pico-windows-development/#comments</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Tue, 02 Feb 2021 01:06:35 +0000</pubDate>
				<category><![CDATA[Raspberry Pi Pico]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[encoder]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[pico pio]]></category>
		<category><![CDATA[raspberry pi pico]]></category>
		<category><![CDATA[visual studio code]]></category>
		<guid isPermaLink="false">http://paulbupejr.com/?p=734</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 6</span> <span class="rt-label rt-postfix">minutes</span></span>This tutorial covers setting up a pretty painless Raspberry Pi Pico C / C++ SDK development workflow on Windows using the Windows Subsystem for Linux (WSL) and Visual Studio Code (VS Code) with IntelliSense code completion! With the Raspberry Pi Pico microcontroller being so new the current C / C++ SDK development process on Windows &#8230; <a href="https://paulbupejr.com/raspberry-pi-pico-windows-development/" class="more-link">Continue reading <span class="screen-reader-text">Easy Raspberry Pi Pico Microcontroller C / C++ Programming on Windows</span></a></p>
<p>The post <a href="https://paulbupejr.com/raspberry-pi-pico-windows-development/">Easy Raspberry Pi Pico Microcontroller C / C++ Programming on Windows</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 6</span> <span class="rt-label rt-postfix">minutes</span></span>
<p>This tutorial covers setting up a pretty painless Raspberry Pi Pico C / C++ SDK development workflow on Windows using the Windows Subsystem for Linux (WSL) and Visual Studio Code (VS Code) with IntelliSense code completion!  </p>



<p>With the Raspberry Pi Pico microcontroller being so new the current C / C++ SDK development process on Windows <a href="https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf" target="_blank" rel="noreferrer noopener">is a bit cumbersome</a>. This tutorial should hopefully give you some ideas on how to go about programming the Raspberry Pi Pico the easy way with WSL and VS Code.</p>



<p><strong><em>Note: This is not a beginner tutorial and assumes some minimal development experience.</em></strong></p>



<span id="more-734"></span>



<p>The Raspberry Pi Pico is an exciting new microcontroller board <a href="https://www.raspberrypi.org/blog/raspberry-pi-silicon-pico-now-on-sale/" target="_blank" rel="noreferrer noopener">launched on January 21, 2021</a>. It&#8217;s based on the RP2040 microcontroller (by the Raspberry Pi Foundation) sporting a <strong>dual-core</strong> ARM Cortex-M0+ running at 133 MHz. The most exciting feature is the Programmable I/O, or PIO, that has 8 independent processors (simple state machines). This is huge for robotics where there&#8217;s a need to ingest real-time sensor data in the background while performing other tasks. <em>Keep an eye out for my tutorial on reading multiple DC motor quadrature encoders at the same time without messing with lots of timers and interrupts using the PIO!</em></p>



<h2 class="wp-block-heading">Prerequisites</h2>



<ol class="wp-block-list"><li>Enable <a href="https://docs.microsoft.com/windows/wsl/install-win10" target="_blank" rel="noreferrer noopener"><strong>Windows Subsystem for Linux</strong></a> and install the latest Ubuntu image (20); follow the &#8220;Manual Installation&#8221; steps. WSL is a built-in feature of Windows 10 and brings most of the power of developing on a Linux machine natively into Windows! Be sure to install Windows Terminal for an even better experience (instructions towards the end of the link above). </li><li>Install <strong><a href="https://code.visualstudio.com/download" target="_blank" rel="noreferrer noopener">Visual Studio Code</a></strong> and install the following extensions:<a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl" target="_blank" rel="noreferrer noopener"> Remote &#8211; WSL</a>, <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools" target="_blank" rel="noreferrer noopener">C/C++</a>, and <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools" target="_blank" rel="noreferrer noopener">CMake Tools</a>. You can search for these extensions by name directly in VS Code. </li></ol>



<h2 class="wp-block-heading" id="configurewsl">Configure WSL</h2>



<h5 class="wp-block-heading">Setup Script</h5>



<p>If you are in a bit of a rush I&#8217;ve created a setup script that will perform all the WSL configuration tasks for you. Just open up WSL, run the following commands, then <a href="#configurecode">skip to setting up Visual Studio Code</a>! </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">cd ~
git clone https://github.com/74ls04/pico-wsl-setup.git
cd pico-wsl-setup
./pico_wsl_setup.sh</pre></div>



<p><strong>This script will install the SDK in <code>~/pico</code></strong> and also installs a few Pico extras from the Raspberry Pi Pico repos. </p>



<h5 class="wp-block-heading">Install Dependencies</h5>



<p><em>Note: I&#8217;m using Ubuntu 18 for this demo but if you&#8217;re starting from scratch use 20 to avoid issues with CMake compatibility.</em></p>



<p>First, open up the WSL Ubuntu terminal and go to the home directory.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">cd ~</pre></div>



<p> Then install the required build dependencies </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">sudo apt update
sudo apt install git cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential</pre></div>



<p>That&#8217;s all there is for dependencies!</p>



<h5 class="wp-block-heading" id="sdkinstall">Install the Raspberry Pi Pico C / C++ SDK</h5>



<p>While still in the home directory create a directory called <code>pico</code> and go into the <code>pico</code> directory</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">mkdir pico
cd pico</pre></div>



<p>After that clone the SDK and examples git repositories.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">git clone -b master https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk
git submodule update --init
cd ..
git clone -b master https://github.com/raspberrypi/pico-examples.git</pre></div>



<p><em>The <code>git submodule</code> command basically pulls in a separate Raspberry Pi repository from <code>https://github.com/raspberrypi/tinyusb.git</code> and downloads those files.</em></p>



<p>Here is what all the commands look like after execution.</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="906" height="575" src="https://paulbupejr.com/wp-content/uploads/2021/01/sdk_install.png" alt="Raspberry Pi Pico Toolchain" class="wp-image-750" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/sdk_install.png 906w, https://paulbupejr.com/wp-content/uploads/2021/01/sdk_install-300x190.png 300w, https://paulbupejr.com/wp-content/uploads/2021/01/sdk_install-768x487.png 768w" sizes="auto, (max-width: 906px) 100vw, 906px" /></figure></div>



<h2 class="wp-block-heading" id="configurecode">Configure and Build with Visual Studio Code</h2>



<p>Now we&#8217;re going to configure VS Code and build the following &#8220;blink&#8221; example. </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-c++src&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C++&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;cpp&quot;}">#include &quot;pico/stdlib.h&quot;

int main() {
    const uint LED_PIN = 25;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    while (true) {
        gpio_put(LED_PIN, 1);
        sleep_ms(250);
        gpio_put(LED_PIN, 0);
        sleep_ms(250);
    }
}</pre></div>



<p>So far you should have the following directories:</p>



<pre class="wp-block-code"><code>~/pico
~/pico/pico-sdk
~/pico/pico-examples</code></pre>



<p>Move into the <code>pico-examples</code> directory</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">cd pico-examples</pre></div>



<p>Now here is where the integration of VS Code and WSL really shines. Open VS Code into this directory </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">code .</pre></div>



<p>This command will launch VS Code and automatically link it to the WSL instance. You should see a green connection label in the bottom left. This process also creates a hidden .vscode sub-directory that will hold the VS Code configuration for this workspace.</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="584" height="63" src="https://paulbupejr.com/wp-content/uploads/2021/01/green-connected.png" alt="" class="wp-image-751" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/green-connected.png 584w, https://paulbupejr.com/wp-content/uploads/2021/01/green-connected-300x32.png 300w" sizes="auto, (max-width: 584px) 100vw, 584px" /></figure></div>



<p></p>



<p>If this is your first time using VS Code with WSL <a href="https://code.visualstudio.com/docs/remote/wsl#_managing-extensions" target="_blank" rel="noreferrer noopener">follow these quick instructions</a> to make sure the three extensions mentioned at the top are also installed in WSL. At this point you may see a notification asking if you would like to configure the project &#8212; click on &#8220;Not now&#8221; as we need to set up a few things first.</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="582" height="207" src="https://paulbupejr.com/wp-content/uploads/2021/01/configure_project.png" alt="" class="wp-image-752" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/configure_project.png 582w, https://paulbupejr.com/wp-content/uploads/2021/01/configure_project-300x107.png 300w" sizes="auto, (max-width: 582px) 100vw, 582px" /></figure></div>



<h5 class="wp-block-heading">Configure CMake Extension</h5>



<p>Click the gear icon in the bottom left and select <code>Settings</code>.</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1024" height="390" src="https://paulbupejr.com/wp-content/uploads/2021/01/settings.png" alt="" class="wp-image-753" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/settings.png 1024w, https://paulbupejr.com/wp-content/uploads/2021/01/settings-300x114.png 300w, https://paulbupejr.com/wp-content/uploads/2021/01/settings-768x293.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p></p>



<p>Expand the Extensions tree, select CMake Tools configuration, and then click <code>Add Item</code> under &#8220;<em>Cmake: Build Environment</em>&#8221; to add the SDK path as shown below. If you followed the directory structure in this tutorial your <code>PICO_SDK_PATH</code> will be <code>/home/$USER/pico/pico-sdk</code> where <strong><span class="has-inline-color has-medium-pink-color">$USER is your WSL username</span></strong>. In this case my tutorial username is &#8220;main.&#8221;</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="844" height="530" src="https://paulbupejr.com/wp-content/uploads/2021/01/sdk_path.png" alt="Raspberry Pi Pico SDK Path" class="wp-image-754" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/sdk_path.png 844w, https://paulbupejr.com/wp-content/uploads/2021/01/sdk_path-300x188.png 300w, https://paulbupejr.com/wp-content/uploads/2021/01/sdk_path-768x482.png 768w" sizes="auto, (max-width: 844px) 100vw, 844px" /></figure></div>



<h5 class="wp-block-heading">Configure IntelliSense (Code Completions)</h5>



<p>Open the Command Palette, <code><span class="has-inline-color has-medium-pink-color">Ctrl+Shift+P</span></code>, and start typing &#8220;C/C++&#8221; then select <strong>C/C++: Edit Configurations (JSON)</strong>. </p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="890" height="363" src="https://paulbupejr.com/wp-content/uploads/2021/01/cpp.png" alt="" class="wp-image-756" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/cpp.png 890w, https://paulbupejr.com/wp-content/uploads/2021/01/cpp-300x122.png 300w, https://paulbupejr.com/wp-content/uploads/2021/01/cpp-768x313.png 768w" sizes="auto, (max-width: 890px) 100vw, 890px" /></figure></div>



<p>This will create the following file: </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}"> /home/$USER/pico/pico-examples/.vscode/c_cpp_properties.json</pre></div>



<p>Change the file to match the following settings. <strong>Keep in mind that these settings are purely for code-completion and have nothing to do with the actual compiling</strong>.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
    &quot;configurations&quot;: [
        {
            &quot;name&quot;: &quot;Linux&quot;,
            &quot;includePath&quot;: [
                &quot;${workspaceFolder}/**&quot;,
                &quot;/home/$USER/projects/pico/pico-sdk/**&quot;,
                &quot;/usr/lib/gcc/arm-none-eabi/**&quot;
            ],
            &quot;defines&quot;: [],
            &quot;compilerPath&quot;: &quot;arm-none-eabi-gcc&quot;,
            &quot;cStandard&quot;: &quot;c11&quot;,
            &quot;cppStandard&quot;: &quot;c++17&quot;,
            &quot;intelliSenseMode&quot;: &quot;gcc-arm&quot;,
            &quot;configurationProvider&quot;: &quot;ms-vscode.cmake-tools&quot;
        }
    ],
    &quot;version&quot;: 4
}</pre></div>



<p class="has-text-align-center"><span class="has-inline-color has-medium-pink-color"><strong>Replace $USER with your WSL username under &#8220;includePath&#8221;!</strong></span></p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="947" height="523" src="https://paulbupejr.com/wp-content/uploads/2021/01/completion_settings.png" alt="Raspberry Pi Pico Intellisense" class="wp-image-755" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/completion_settings.png 947w, https://paulbupejr.com/wp-content/uploads/2021/01/completion_settings-300x166.png 300w, https://paulbupejr.com/wp-content/uploads/2021/01/completion_settings-768x424.png 768w" sizes="auto, (max-width: 947px) 100vw, 947px" /></figure></div>



<p></p>



<p>Close VS Code and relaunch it again from the terminal with</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">code .</pre></div>



<p>This time when CMake asks whether you&#8217;d like to configure the project select &#8220;Yes&#8221; and wait for it to finish configuring.</p>



<h5 class="wp-block-heading">Configure Compiler and Build</h5>



<p>Tell VS Code which compiler to use by clicking the &#8220;<em>No Kit Selected</em>&#8221; text at the bottom </p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="671" height="37" src="https://paulbupejr.com/wp-content/uploads/2021/02/compiler-sel.png" alt="Raspberry Pi Pico Compiler Select" class="wp-image-768" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/compiler-sel.png 671w, https://paulbupejr.com/wp-content/uploads/2021/02/compiler-sel-300x17.png 300w" sizes="auto, (max-width: 671px) 100vw, 671px" /></figure></div>



<p>Then selecting <code>GCC for arm-none-eabi...</code> If using Ubuntu 20 your compiler version will be different since I&#8217;m using 18. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="724" height="405" src="https://paulbupejr.com/wp-content/uploads/2021/02/compiler.png" alt="Raspberry Pi Pico Compiler Menu" class="wp-image-769" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/compiler.png 724w, https://paulbupejr.com/wp-content/uploads/2021/02/compiler-300x168.png 300w" sizes="auto, (max-width: 724px) 100vw, 724px" /></figure>



<p></p>



<p>Open up the &#8220;blink.c&#8221; example file using the explorer menu on the left, <code><span class="has-inline-color has-medium-pink-color">CTRL+SHIFT+E</span></code>. You should see no errors highlighted in the file and code hints should be working as well. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="694" height="425" src="https://paulbupejr.com/wp-content/uploads/2021/02/codehint.png" alt="Raspberry Pi Pico Code Completion" class="wp-image-770" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/codehint.png 694w, https://paulbupejr.com/wp-content/uploads/2021/02/codehint-300x184.png 300w" sizes="auto, (max-width: 694px) 100vw, 694px" /></figure>



<p></p>



<p>Tell CMake which project to build by clicking on <code>[all]</code> at the bottom</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="671" height="37" src="https://paulbupejr.com/wp-content/uploads/2021/02/build-sel.png" alt="Raspberry Pi Pico Project Select" class="wp-image-771" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/build-sel.png 671w, https://paulbupejr.com/wp-content/uploads/2021/02/build-sel-300x17.png 300w" sizes="auto, (max-width: 671px) 100vw, 671px" /></figure>



<p></p>



<p>Then scroll until you see &#8220;blink.&#8221;</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="667" height="432" src="https://paulbupejr.com/wp-content/uploads/2021/02/project-sel.png" alt="Raspberry Pi Pico Project Select Menu" class="wp-image-772" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/project-sel.png 667w, https://paulbupejr.com/wp-content/uploads/2021/02/project-sel-300x194.png 300w" sizes="auto, (max-width: 667px) 100vw, 667px" /></figure>



<p></p>



<p>You should now see <code>[blink]</code> instead of <code>[all]</code>. Click on &#8220;Build&#8221; to build the project!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="757" height="37" src="https://paulbupejr.com/wp-content/uploads/2021/02/build.png" alt="Raspberry Pi Pico Build Select" class="wp-image-774" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/build.png 757w, https://paulbupejr.com/wp-content/uploads/2021/02/build-300x15.png 300w" sizes="auto, (max-width: 757px) 100vw, 757px" /></figure>



<p></p>



<p>VS Code will automatically create a build directory and spit out the project binaries into that directory. </p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="720" height="464" src="https://paulbupejr.com/wp-content/uploads/2021/02/build-done.png" alt="Raspberry Pi Pico Build" class="wp-image-775" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/build-done.png 720w, https://paulbupejr.com/wp-content/uploads/2021/02/build-done-300x193.png 300w" sizes="auto, (max-width: 720px) 100vw, 720px" /></figure></div>



<p><em>Keep in mind this built the debug configuration, you can change it to release by clicking on <code>CMake: [Debug]: Ready</code> at the bottom.</em></p>



<h5 class="wp-block-heading">Upload to Raspberry Pi Pico</h5>



<p>Uploading the binary to the Pico is just a matter of dragging the <code>.uf2</code> file into the folder that opens when you plug in the Pico while holding down the <code>BOOTSEL</code> button.</p>



<p>The file to transfer is:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">/home/main/pico/pico-examples/build/blink/blink.uf2</pre></div>



<p>To open the directory you can either right clock on the directory name in VS Code then click &#8220;Reveal in Explorer&#8221; or just type </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">explorer.exe .</pre></div>



<p>in the WSL terminal to open that directory in Windows Explorer. <em>That&#8217;s one of the most useful WSL commands!</em></p>



<p>Plug in the Raspberry Pi Pico while holding down the <code>BOOTSEL</code> button and then drag over the <code>.uf2</code> file to the Pico folder. </p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/uploads/2021/02/transfer.png" alt="Raspberry Pi Pico Upload" class="wp-image-776" width="728" height="331" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/transfer.png 970w, https://paulbupejr.com/wp-content/uploads/2021/02/transfer-300x136.png 300w, https://paulbupejr.com/wp-content/uploads/2021/02/transfer-768x349.png 768w" sizes="auto, (max-width: 728px) 100vw, 728px" /></figure>



<p>It will automatically disconnect after transferring and immediately start running the program! </p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/uploads/2021/02/pico-2-1024x696.jpg" alt="Raspberry Pi Pico" class="wp-image-781" width="512" height="348" srcset="https://paulbupejr.com/wp-content/uploads/2021/02/pico-2-1024x696.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2021/02/pico-2-300x204.jpg 300w, https://paulbupejr.com/wp-content/uploads/2021/02/pico-2-768x522.jpg 768w, https://paulbupejr.com/wp-content/uploads/2021/02/pico-2-1536x1044.jpg 1536w, https://paulbupejr.com/wp-content/uploads/2021/02/pico-2-2048x1392.jpg 2048w" sizes="auto, (max-width: 512px) 100vw, 512px" /></figure></div>



<p>It&#8217;s also pretty easy to configure VS Code to automatically move the file after building but for the sake of keeping this short I&#8217;ll save that for another time.</p>



<h2 class="wp-block-heading">More to come!</h2>



<p>This should hopefully give you an idea of how the current development process is for the Raspberry Pi Pico. My goal is to create another robotics-focused Pico tutorial in the coming months starting from scratch and using the PIO &#8212; maybe in conjunction with a <a href="https://paulbupejr.com/raspberry-pi-serial-console/">Raspberry</a> <a href="https://paulbupejr.com/autonomous-robot-design/">Pi</a>!</p>



<p>Feel free to ask any questions or offer suggestions in the comments!</p>



<p>Updated: 2/11/2021</p>
<p>The post <a href="https://paulbupejr.com/raspberry-pi-pico-windows-development/">Easy Raspberry Pi Pico Microcontroller C / C++ Programming on Windows</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/raspberry-pi-pico-windows-development/feed/</wfw:commentRss>
			<slash:comments>28</slash:comments>
		
		
			</item>
		<item>
		<title>Raspberry Pi Headless Access Using Built-in Serial Console</title>
		<link>https://paulbupejr.com/raspberry-pi-serial-console/</link>
					<comments>https://paulbupejr.com/raspberry-pi-serial-console/#comments</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Sun, 24 Jan 2021 18:14:51 +0000</pubDate>
				<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[raspberry pi]]></category>
		<category><![CDATA[Serial]]></category>
		<guid isPermaLink="false">http://paulbupejr.com/?p=706</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 3</span> <span class="rt-label rt-postfix">minutes</span></span>It&#8217;s not very well known that the Raspberry Pi has a built-in serial console that provides a fully working Linux terminal over serial. This allows for network-free headless access, including the absolutely necessary tab auto-complete! This feature is extremely useful for those projects that don&#8217;t use a screen or need network access. It&#8217;s also quite &#8230; <a href="https://paulbupejr.com/raspberry-pi-serial-console/" class="more-link">Continue reading <span class="screen-reader-text">Raspberry Pi Headless Access Using Built-in Serial Console</span></a></p>
<p>The post <a href="https://paulbupejr.com/raspberry-pi-serial-console/">Raspberry Pi Headless Access Using Built-in Serial Console</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 3</span> <span class="rt-label rt-postfix">minutes</span></span>
<p>It&#8217;s not very well known that the Raspberry Pi has a built-in serial console that provides a fully working Linux terminal over serial. This allows for network-free headless access, including the absolutely necessary tab auto-complete! This feature is extremely useful for those projects that don&#8217;t use a screen or need network access. It&#8217;s also quite necessary when you are using a Pi as a wireless access point for a LAN without internet sharing.</p>



<span id="more-706"></span>



<p>Quick disclaimer: This article assumes basic familiarity with the Raspberry Pi and the basics of interfacing with serial devices. I&#8217;m using Windows to demonstrate but this works equally well on Linux and Mac. </p>



<h2 class="wp-block-heading">Hardware</h2>



<p>You&#8217;ll need a Raspberry Pi (of course) and a USB -to-Serial device (<a href="https://www.adafruit.com/product/954" target="_blank" rel="noreferrer noopener">like this one from Adafruit</a>).</p>



<p>Firstly, connect the RX of the USB-to-Serial device to <code><span class="has-inline-color has-purple-color">Pin 8</span></code> of the Pi (physical <code><span class="has-inline-color has-purple-color">Pin 8</span></code>, not the GPIO pin number) and TX of the USB-to-Serial device to <code><span class="has-inline-color has-purple-color">Pin 10</span></code> of the Pi. </p>



<p>Remember, for UART communication you do not match up TX &lt;&#8211;&gt; TX and RX &lt;&#8211;&gt; RX, it&#8217;s the opposite (TX &#8211;&gt; RX and RX &lt;&#8211; TX) since one device transmits and the other receives. </p>



<div class="wp-block-image"><figure class="aligncenter size-medium"><img loading="lazy" decoding="async" width="297" height="300" src="https://paulbupejr.com/wp-content/uploads/2021/01/Pinout-297x300.png" alt="Raspberry Pi Pinout" class="wp-image-717" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/Pinout-297x300.png 297w, https://paulbupejr.com/wp-content/uploads/2021/01/Pinout-45x45.png 45w, https://paulbupejr.com/wp-content/uploads/2021/01/Pinout.png 731w" sizes="auto, (max-width: 297px) 100vw, 297px" /><figcaption>https://pinout.xyz/pinout/uart#</figcaption></figure></div>



<p></p>



<p>Finally, connect the ground of the USB-to-Serial device to <span class="has-inline-color has-purple-color"><code>Pin 6</code></span> of the Pi (ground).</p>



<p><strong><span class="has-inline-color has-medium-pink-color">NOTE: Do NOT connect the 5V power wire from the USB-to-Serial adapter to the 5V power pin of the Pi.</span></strong> <a href="https://raspberrypi.stackexchange.com/questions/28310/whats-the-problem-with-backfeeding" target="_blank" rel="noreferrer noopener">This can backpower the Pi and destroy it</a>. All that&#8217;s necessary is that the USB-to-Serial adapter and Pi share the same ground reference. Using the<a href="https://www.adafruit.com/product/954" target="_blank" rel="noreferrer noopener"> Adafruit adapter</a>, the connections look like the picture at the top of the page.</p>



<h2 class="wp-block-heading">Software</h2>



<p>To enable the serial console just add the line:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">enable_uart=1</pre></div>



<p>to <code>/boot/config.txt</code> on the Pi.  <code>/boot/</code> is also mounted automatically on Windows so you can do this on a fresh image immediately after burning to the SD card (you may need to take it out and re-insert it first). </p>



<p>After connecting the USB-to-Serial adapter you can figure out the serial COM port using device manager.</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="582" height="429" src="https://paulbupejr.com/wp-content/uploads/2021/01/piserial-2.jpg" alt="Device manager" class="wp-image-722" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/piserial-2.jpg 582w, https://paulbupejr.com/wp-content/uploads/2021/01/piserial-2-300x221.jpg 300w" sizes="auto, (max-width: 582px) 100vw, 582px" /></figure></div>



<p></p>



<p>The serial port needs to be configured with the settings below. Generally everything below but the baud rate are the default on most systems so that&#8217;s all you need to specify. </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">    Speed (baud rate): 115200
    Bits: 8
    Parity: None
    Stop Bits: 1
    Flow Control: None</pre></div>



<p>In this case I&#8217;m using PuTTY to connect to the Pi as shown:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="452" height="442" src="https://paulbupejr.com/wp-content/uploads/2021/01/piserial-3.jpg" alt="Putty" class="wp-image-723" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/piserial-3.jpg 452w, https://paulbupejr.com/wp-content/uploads/2021/01/piserial-3-300x293.jpg 300w, https://paulbupejr.com/wp-content/uploads/2021/01/piserial-3-45x45.jpg 45w" sizes="auto, (max-width: 452px) 100vw, 452px" /></figure></div>



<p></p>



<p>After connecting you should be met with a blank screen, simply press <code>ENTER</code> to send a character and you&#8217;ll see the familiar login prompt. Enter the login credentials and you&#8217;re in, just like you SSH&#8217;d in!</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="661" height="418" src="https://paulbupejr.com/wp-content/uploads/2021/01/piserial-4.jpg" alt="Raspberry Pi Login" class="wp-image-725" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/piserial-4.jpg 661w, https://paulbupejr.com/wp-content/uploads/2021/01/piserial-4-300x190.jpg 300w" sizes="auto, (max-width: 661px) 100vw, 661px" /></figure>



<p></p>



<p>To demonstrate that this is a fully working terminal you can even launch the &#8220;graphical&#8221; <code>raspi-config</code> utility.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="661" height="418" src="https://paulbupejr.com/wp-content/uploads/2021/01/piserial-5.jpg" alt="" class="wp-image-726" srcset="https://paulbupejr.com/wp-content/uploads/2021/01/piserial-5.jpg 661w, https://paulbupejr.com/wp-content/uploads/2021/01/piserial-5-300x190.jpg 300w" sizes="auto, (max-width: 661px) 100vw, 661px" /></figure>



<h2 class="wp-block-heading">That&#8217;s it!</h2>



<p>This should hopefully be a useful bit of info for the more advanced projects that don&#8217;t use the Pi with a screen and mouse/keyboard connected. </p>
<p>The post <a href="https://paulbupejr.com/raspberry-pi-serial-console/">Raspberry Pi Headless Access Using Built-in Serial Console</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/raspberry-pi-serial-console/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Indoor Localization &#8211; An Introduction</title>
		<link>https://paulbupejr.com/indoor-localization/</link>
					<comments>https://paulbupejr.com/indoor-localization/#respond</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Mon, 06 Jul 2020 16:19:42 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[lidar]]></category>
		<guid isPermaLink="false">http://paulbupejr.com/?p=658</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 6</span> <span class="rt-label rt-postfix">minutes</span></span>Localization, in the context of robotics, is the process of determining the location of something within an environment. This article serves as a basic introduction to indoor localization, covering the commonly used techniques and technologies. The most well known and widely used method of localization is GPS. Even with its widespread use, GPS is not &#8230; <a href="https://paulbupejr.com/indoor-localization/" class="more-link">Continue reading <span class="screen-reader-text">Indoor Localization &#8211; An Introduction</span></a></p>
<p>The post <a href="https://paulbupejr.com/indoor-localization/">Indoor Localization &#8211; An Introduction</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 6</span> <span class="rt-label rt-postfix">minutes</span></span>


<p>Localization, in the context of robotics, is the process of determining the location of something within an environment. This article serves as a basic introduction to indoor localization, covering the commonly used techniques and technologies. </p>



<span id="more-658"></span>



<p>The most well known and widely used method of localization is GPS. Even with its widespread use, GPS is not suitable for all applications because it largely relies on line-of-sight (LOS) communication to GPS satellites. In indoor environments, these signals are greatly attenuated by walls and roofs, meaning that GPS often does not work indoors. Even when signals from at least four satellites are received indoors, the localization accuracy is too low to be useful. In lieu of GPS, a large number of indoor localization techniques and real-time locating systems (RTLS) have been developed. These can be grouped into two broad categories: radio-frequency (RF) based (<em>wireless</em>), and non-RF based (<em>non-wireless</em>). </p>



<p>Non-wireless techniques generally use cameras and sensors like Inertial Measurement Units (IMU) and laser distance finders (like <a aria-label="undefined (opens in a new tab)" href="https://en.wikipedia.org/wiki/Lidar" target="_blank" rel="noreferrer noopener">LiDAR</a>) for localization. Cameras can use markers or extract visual features from an environment to perform localization using various techniques including the very common technique known as simultaneous localization and mapping (<a aria-label="undefined (opens in a new tab)" href="https://en.wikipedia.org/wiki/Simultaneous_localization_and_mapping" target="_blank" rel="noreferrer noopener">SLAM</a>). This technique involves building a map of an environment while at the same time localizing in that environment. Data from an IMU and laser scans can also be fused with the visual data to improve accuracy. These techniques are very computationally heavy, require specialized hardware, and are typically used in robotics or autonomous navigation applications (see <a href="https://www.tesla.com/autopilotAI">Tesla</a>, <a aria-label="undefined (opens in a new tab)" href="https://www.bostondynamics.com/spot" target="_blank" rel="noreferrer noopener">Boston Dynamics</a>). This is the same type of localization technique I <a aria-label="undefined (opens in a new tab)" href="https://paulbupejr.com/autonomous-robot-design/" target="_blank" rel="noreferrer noopener">used in my last robot</a> and  <strong><em>I will cover this in more detail in a separate article.</em></strong></p>



<p>Wireless techniques utilize technologies such as Wi-Fi, radio-frequency identification (RFID), Bluetooth, and ultra-wideband (UWB). These technologies are useful for indoor localization because they are already found in existing infrastructure and can be set up at very low cost. Wireless localization techniques can be classified as <strong>range-based</strong>, or <strong>range-free</strong>. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="708" height="262" src="https://paulbupejr.com/wp-content/uploads/2020/07/localization_types-1.png" alt="Indoor Localization type - Paul Bupe Jr" class="wp-image-666" title="Indoor Localization Types" srcset="https://paulbupejr.com/wp-content/uploads/2020/07/localization_types-1.png 708w, https://paulbupejr.com/wp-content/uploads/2020/07/localization_types-1-300x111.png 300w" sizes="auto, (max-width: 708px) 100vw, 708px" /></figure>



<h2 class="wp-block-heading">Ranged-based Indoor Localization</h2>



<p>Range-based (or distance-based) techniques are more accurate than range-free and involve measuring the distance from the unknown node being localized to some fixed nodes with known locations, typically called anchors. Most range-based localization algorithms utilize one of the common measurement techniques which fall into two categories: <em>angle-based</em> and <em>distance-based</em>. The most common angle-based measurement technique is Angle of Arrival (AoA) and the main distance measurement techniques are Time of Arrival (ToA), Time Difference of Arrival (TDoA) and Received Signal Strength (RSS).</p>



<h4 class="wp-block-heading">Angle-based Measurement</h4>



<p>AoA measurement techniques calculate the angle (bearing) between the unlocalized node and a fixed anchor with a known location. These measurements are obtained using two main techniques that include (1) measuring the amplitude response of the receiving antenna and (2) measuring the phase response of the receiving antenna. The location of the unknown node is a line having a certain angle from an anchor node &#8212; this requires at least two nodes to calculate the position as shown in the figure below. </p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="767" height="428" src="https://paulbupejr.com/wp-content/uploads/2020/07/aoa-1.png" alt="Angle of Arrival - Paul Bupe Jr" class="wp-image-667" title="Angle of Arrival" srcset="https://paulbupejr.com/wp-content/uploads/2020/07/aoa-1.png 767w, https://paulbupejr.com/wp-content/uploads/2020/07/aoa-1-300x167.png 300w" sizes="auto, (max-width: 767px) 100vw, 767px" /></figure></div>



<p>The accuracy of these measurements is affected by the directivity of the antenna and the environmental NLOS and multipath effects. Since AoA measures angles, it requires direct LOS between the receiver and transmitter because a reflected signal arriving at the receiver can be interpreted as coming from a completely different direction, which can result in very large errors in the measurement.</p>



<h4 class="wp-block-heading">Distance-based Measurement</h4>



<h4 class="has-text-align-center wp-block-heading"><strong>Time of Arrival</strong></h4>



<p>Time of Arrival (ToA) is a technique that calculates distance based on the measured time of arrival of a signal from a transmitting node to a receiving one. This is more formally referred to as a one way propagation time measurement. The primary drawback to this technique is that it requires perfect time synchronization between the clocks of the transmitter and receiver nodes; any difference between the two clocks can become a large error in the distance calculation. Assuming normal conditions (air as the medium and radio waves traveling at the speed of light) a small clock synchronization error of 1ns will relate to a distance measurement error of 0.3m. </p>



<p>One way of overcoming this issue is by measuring the round trip propagation time instead of the one way propagation. The first node sends a signal to a second node which in turn immediately sends that signal back to the first node and the distance is calculated using the round trip time. This removes the need for the transmitter and receiver to have synchronized clocks. The primary issue with this round trip method is the processing delay accrued from the second node receiving the signal then sending it back in turn. This delay is usually known and specified by the manufacturer (or during a calibration process) so it can be subtracted from the measurement at the first node.</p>



<h4 class="has-text-align-center wp-block-heading"><strong>Time Difference of Arrival</strong></h4>



<p>Time Difference of Arrival (TDoA) is another technique that measures propagation time but in this case the difference between the arrival time of a signal at two different fixed receivers is measured. This requires that the location of the two receivers are known and those two receivers also have synchronized clocks. Unlike ToA, there is no need for the clocks between the transmitter and receivers to be in perfect sync.</p>



<h4 class="has-text-align-center wp-block-heading"><strong>Received Signal Strength</strong></h4>



<p>There are two main methods of estimating distance using the Received Signal Strength (RSS): using the path loss log-normal shadowing model and RSS fingerprinting. Distance estimation using the path loss model is accomplished by measuring the signal attenuation as it propagates from the transmitting node to the receiving node. The relationship between distance and signal attenuation is heavily dependent on channel characteristics and as a result requires a very accurate propagation model in order to have acceptable results. The standard log-normal model used in this technique is as follows:</p>



<p><p class="ql-center-displayed-equation" style="line-height: 43px;"><span class="ql-right-eqno"> (1) </span><span class="ql-left-eqno"> &nbsp; </span><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-e3a126c90c9732dcbd49aa8ef7c5378c_l3.png" height="43" width="406" class="ql-img-displayed-equation quicklatex-auto-format" alt="&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;&#80;&#95;&#114;&#40;&#100;&#41;&#91;&#100;&#66;&#109;&#93;&#32;&#61;&#32;&#80;&#95;&#48;&#40;&#100;&#95;&#48;&#41;&#91;&#100;&#66;&#109;&#93;&#32;&#45;&#32;&#49;&#48;&#110;&#95;&#112;&#92;&#108;&#111;&#103;&#95;&#123;&#49;&#48;&#125;&#92;&#108;&#101;&#102;&#116;&#40;&#92;&#102;&#114;&#97;&#99;&#123;&#100;&#125;&#123;&#100;&#95;&#48;&#125;&#92;&#114;&#105;&#103;&#104;&#116;&#41;&#32;&#43;&#32;&#88;&#95;&#123;&#92;&#115;&#105;&#103;&#109;&#97;&#125;&#92;&#101;&#110;&#100;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;" title="Rendered by QuickLaTeX.com"/></p></p>



<p>with <img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-ff805bc00924fd4f222accc3247403aa_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="&#80;&#95;&#48;&#40;&#100;&#95;&#48;&#41;&#91;&#100;&#66;&#109;&#93;" title="Rendered by QuickLaTeX.com" height="19" width="97" style="vertical-align: -5px;"/> being the reference power at distance <img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-5fe8174ada8a5c941edeea39af840862_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="&#100;&#95;&#48;" title="Rendered by QuickLaTeX.com" height="15" width="16" style="vertical-align: -3px;"/> from the transmitter, <img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-49a560f549b27afd9f22c619dc9456ec_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="&#110;&#95;&#112;" title="Rendered by QuickLaTeX.com" height="14" width="18" style="vertical-align: -6px;"/> being the path loss exponent measuring the rate at which the RSS decreases with distance, and <img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-a8a29ec3c3fc8bd634260fbcf692875d_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="&#88;&#95;&#123;&#92;&#115;&#105;&#103;&#109;&#97;&#125;" title="Rendered by QuickLaTeX.com" height="15" width="23" style="vertical-align: -3px;"/> being a zero mean Gaussian random variable with standard deviation <img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-1c9cc40f96a1492e298e7da85a2c1692_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="&#92;&#115;&#105;&#103;&#109;&#97;" title="Rendered by QuickLaTeX.com" height="8" width="11" style="vertical-align: 0px;"/> which accounts for random showing effects.</p>



<h3 class="wp-block-heading">Multilateration</h3>



<p>Multilateration is a core technique for estimating the location of a node using the measured distances to multiple anchors. Traditionally, this is achieved using 3 anchors (for 2D localization) and is referred to as trilateration. The locations of the anchors is assumed to be known and the location of the unknown node is the intersection of the three circles with the center at the location of each anchor and radius equal to the measured distance to the unknown node.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="465" height="403" src="https://paulbupejr.com/wp-content/uploads/2020/07/trilat.png" alt="Trilateration - Paul Bupe Jr" class="wp-image-672" title="Trilateration" srcset="https://paulbupejr.com/wp-content/uploads/2020/07/trilat.png 465w, https://paulbupejr.com/wp-content/uploads/2020/07/trilat-300x260.png 300w" sizes="auto, (max-width: 465px) 100vw, 465px" /></figure></div>



<p>An example of the relationship between the node and anchors is shown in the figure above. In practice the measurements aren&#8217;t always accurate so the circles don&#8217;t intersect at a single point, as shown below.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="476" height="435" src="https://paulbupejr.com/wp-content/uploads/2020/07/trilat2.png" alt="Trilateration 2 - Paul Bupe Jr" class="wp-image-673" title="Trilateration 2" srcset="https://paulbupejr.com/wp-content/uploads/2020/07/trilat2.png 476w, https://paulbupejr.com/wp-content/uploads/2020/07/trilat2-300x274.png 300w" sizes="auto, (max-width: 476px) 100vw, 476px" /></figure></div>



<p>In this case with the locations of the anchors and the estimated distances between the anchors and node known, trilateration then becomes a problem of solving three nonlinear circle equations</p>



<p><p class="ql-center-displayed-equation" style="line-height: 78px;"><span class="ql-right-eqno"> (2) </span><span class="ql-left-eqno"> &nbsp; </span><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-ee166ac9cd2b44705bee982e28deb883_l3.png" height="78" width="200" class="ql-img-displayed-equation quicklatex-auto-format" alt="&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#97;&#108;&#105;&#103;&#110;&#101;&#100;&#125;&#40;&#120;&#32;&#45;&#32;&#120;&#95;&#49;&#41;&#94;&#50;&#32;&#43;&#32;&#40;&#121;&#32;&#45;&#32;&#121;&#95;&#49;&#41;&#94;&#50;&#32;&#61;&#32;&#114;&#95;&#49;&#94;&#50;&#92;&#92;&#40;&#120;&#32;&#45;&#32;&#120;&#95;&#50;&#41;&#94;&#50;&#32;&#43;&#32;&#40;&#121;&#32;&#45;&#32;&#121;&#95;&#50;&#41;&#94;&#50;&#32;&#61;&#32;&#114;&#95;&#50;&#94;&#50;&#92;&#92;&#40;&#120;&#32;&#45;&#32;&#120;&#95;&#51;&#41;&#94;&#50;&#32;&#43;&#32;&#40;&#121;&#32;&#45;&#32;&#121;&#95;&#51;&#41;&#94;&#50;&#32;&#61;&#32;&#114;&#95;&#51;&#94;&#50;&#92;&#101;&#110;&#100;&#123;&#97;&#108;&#105;&#103;&#110;&#101;&#100;&#125;&#92;&#101;&#110;&#100;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;" title="Rendered by QuickLaTeX.com"/></p></p>



<p>where <img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-662ad98ad51ca9c464529fd64dbea5d4_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="&#40;&#120;&#95;&#49;&#44;&#32;&#121;&#95;&#49;&#41;" title="Rendered by QuickLaTeX.com" height="19" width="54" style="vertical-align: -5px;"/>, <img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-043a1f099556a13e92a2cafd268fdd68_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="&#40;&#120;&#95;&#50;&#44;&#32;&#121;&#95;&#50;&#41;" title="Rendered by QuickLaTeX.com" height="19" width="54" style="vertical-align: -5px;"/>, and <img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-851e6d8b95f1d4a3fc1d50bc2eb7b3ae_l3.png" class="ql-img-inline-formula quicklatex-auto-format" alt="&#40;&#120;&#95;&#51;&#44;&#32;&#121;&#95;&#51;&#41;" title="Rendered by QuickLaTeX.com" height="19" width="54" style="vertical-align: -5px;"/>, are the coordinates of anchors 1, 2, and 3. These equations can be linearized into the form</p>



<p><p class="ql-center-displayed-equation" style="line-height: 13px;"><span class="ql-right-eqno"> (3) </span><span class="ql-left-eqno"> &nbsp; </span><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-86f417d36197d170b2ff6acb5b3ada46_l3.png" height="13" width="55" class="ql-img-displayed-equation quicklatex-auto-format" alt="&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;&#65;&#120;&#32;&#61;&#32;&#98;&#92;&#101;&#110;&#100;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;" title="Rendered by QuickLaTeX.com"/></p></p>



<p>with</p>



<p><p class="ql-center-displayed-equation" style="line-height: 42px;"><span class="ql-right-eqno"> (4) </span><span class="ql-left-eqno"> &nbsp; </span><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-baa133486baa86058590fea5d1e7d73e_l3.png" height="42" width="227" class="ql-img-displayed-equation quicklatex-auto-format" alt="&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#65;&#125;&#32;&#61;&#32;&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#98;&#109;&#97;&#116;&#114;&#105;&#120;&#125;&#50;&#40;&#120;&#95;&#49;&#45;&#120;&#95;&#51;&#41;&#32;&#38;&#50;&#40;&#121;&#95;&#49;&#45;&#121;&#95;&#51;&#41;&#32;&#92;&#92;&#50;&#40;&#120;&#95;&#50;&#45;&#120;&#95;&#51;&#41;&#32;&#38;&#50;&#40;&#121;&#95;&#50;&#45;&#121;&#95;&#51;&#41;&#32;&#92;&#92;&#92;&#101;&#110;&#100;&#123;&#98;&#109;&#97;&#116;&#114;&#105;&#120;&#125;&#92;&#101;&#110;&#100;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;" title="Rendered by QuickLaTeX.com"/></p></p>



<p><br><p class="ql-center-displayed-equation" style="line-height: 43px;"><span class="ql-right-eqno"> (5) </span><span class="ql-left-eqno"> &nbsp; </span><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-cb42c97db1e27229f2c6d74c2191efa5_l3.png" height="43" width="260" class="ql-img-displayed-equation quicklatex-auto-format" alt="&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#98;&#125;&#32;&#61;&#32;&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#98;&#109;&#97;&#116;&#114;&#105;&#120;&#125;&#114;&#95;&#123;&#49;&#125;&#94;&#50;&#32;&#45;&#32;&#114;&#95;&#123;&#51;&#125;&#94;&#50;&#32;&#45;&#32;&#120;&#95;&#123;&#49;&#125;&#94;&#50;&#32;&#43;&#32;&#120;&#95;&#123;&#51;&#125;&#94;&#50;&#32;&#45;&#32;&#121;&#95;&#123;&#49;&#125;&#94;&#50;&#32;&#43;&#32;&#121;&#95;&#123;&#51;&#125;&#94;&#50;&#32;&#92;&#92;&#114;&#95;&#123;&#50;&#125;&#94;&#50;&#32;&#45;&#32;&#114;&#95;&#123;&#51;&#125;&#94;&#50;&#32;&#45;&#32;&#120;&#95;&#123;&#50;&#125;&#94;&#50;&#32;&#43;&#32;&#120;&#95;&#123;&#51;&#125;&#94;&#50;&#32;&#45;&#32;&#121;&#95;&#123;&#50;&#125;&#94;&#50;&#32;&#43;&#32;&#121;&#95;&#123;&#51;&#125;&#94;&#50;&#32;&#92;&#92;&#92;&#101;&#110;&#100;&#123;&#98;&#109;&#97;&#116;&#114;&#105;&#120;&#125;&#92;&#101;&#110;&#100;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;" title="Rendered by QuickLaTeX.com"/></p></p>



<p><br><p class="ql-center-displayed-equation" style="line-height: 42px;"><span class="ql-right-eqno"> (6) </span><span class="ql-left-eqno"> &nbsp; </span><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-4f207f69fd6d3722e6780aae67001dd5_l3.png" height="42" width="59" class="ql-img-displayed-equation quicklatex-auto-format" alt="&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#120;&#125;&#32;&#61;&#32;&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#98;&#109;&#97;&#116;&#114;&#105;&#120;&#125;&#92;&#104;&#97;&#116;&#123;&#120;&#125;&#32;&#92;&#92;&#92;&#104;&#97;&#116;&#123;&#121;&#125;&#32;&#92;&#92;&#92;&#101;&#110;&#100;&#123;&#98;&#109;&#97;&#116;&#114;&#105;&#120;&#125;&#92;&#101;&#110;&#100;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;" title="Rendered by QuickLaTeX.com"/></p></p>



<p>which can be solved using the least squares method:<br><p class="ql-center-displayed-equation" style="line-height: 22px;"><span class="ql-right-eqno"> (7) </span><span class="ql-left-eqno"> &nbsp; </span><img loading="lazy" decoding="async" src="https://paulbupejr.com/wp-content/ql-cache/quicklatex.com-157d0c8daccaf5be5619489f0d45303b_l3.png" height="22" width="149" class="ql-img-displayed-equation quicklatex-auto-format" alt="&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;&#120;&#32;&#61;&#32;&#40;&#65;&#94;&#123;&#84;&#125;&#65;&#41;&#94;&#123;&#45;&#49;&#125;&#40;&#65;&#94;&#84;&#98;&#41;&#92;&#101;&#110;&#100;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;" title="Rendered by QuickLaTeX.com"/></p></p>



<p><strong><em>Multilateration is not to be confused with triangulation which uses knowledge of the angles between the node and anchors to find the node-to-anchor distances using the law of sines.</em></strong></p>



<h2 class="wp-block-heading">Range-Free Indoor Localization</h2>



<p>Range-free techniques use the relative positions of existing nodes, connectivity information, or detecting the proximity of the unknown node to fixed anchors with known locations (using RFID or Bluetooth beacons) to localize. They are simpler, cheaper, and more energy efficient than range-based algorithms at the cost of having low localization accuracy. Because of this, range-free algorithms are generally only useful when coarse locations are desired.</p>



<h4 class="wp-block-heading">Connectivity-based</h4>



<p>Connectivity-based localization works by checking if a node is connected to another node. If each node is aware of all the connected nodes then coarse locations can be determined by counting the hops between nodes using an algorithm DV-Hop. Another technique is simply detecting the presence of a node near a knwon beacon, typically using RFID or Bluetooth.</p>



<h4 class="wp-block-heading">Profiling / Fingerprinting</h4>



<p>Another type of range free localization is the use of RSS profiling or fingerprinting in order to overcome the inaccuracies of RSS-based distance measurements. Fingerprinting involves taking RSS measurements at various locations and building a map of those measurements and their position. Localization then becomes a matter of matching RSS measurements, not distances, to the map in order to localize. This type of localization is very well suited for machine learning.</p>



<h2 class="wp-block-heading">Next Steps</h2>



<p>This should hopefully have been a quick introduction to the concept of localization and the common techniques currently in use. The next article will include some code samples for implementing some of these techniques using Python. </p>



<p>The content of this article is based off the work I did for my <a aria-label="undefined (opens in a new tab)" href="https://digitalcommons.georgiasouthern.edu/etd/2048/" target="_blank" rel="noreferrer noopener">Masters thesis</a>. </p>



<p></p>
<p>The post <a href="https://paulbupejr.com/indoor-localization/">Indoor Localization &#8211; An Introduction</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/indoor-localization/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Reflow Soldering in Unmodified Toaster Oven?</title>
		<link>https://paulbupejr.com/reflow-soldering-in-unmodified-toaster-oven/</link>
					<comments>https://paulbupejr.com/reflow-soldering-in-unmodified-toaster-oven/#respond</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Fri, 09 Aug 2019 02:00:13 +0000</pubDate>
				<category><![CDATA[Electrical]]></category>
		<category><![CDATA[PCB Design]]></category>
		<guid isPermaLink="false">http://paulbupejr.com/?p=548</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 2</span> <span class="rt-label rt-postfix">minutes</span></span>I&#8217;ve been designing a 4-layer PCB for a product for a few months now and I finally got to the stage of assembling the prototype after the PCB and components arrived. Most of the passive components I used were 0603 surface mount parts so reflow soldering was the only viable option (if I wanted to &#8230; <a href="https://paulbupejr.com/reflow-soldering-in-unmodified-toaster-oven/" class="more-link">Continue reading <span class="screen-reader-text">Reflow Soldering in Unmodified Toaster Oven?</span></a></p>
<p>The post <a href="https://paulbupejr.com/reflow-soldering-in-unmodified-toaster-oven/">Reflow Soldering in Unmodified Toaster Oven?</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 2</span> <span class="rt-label rt-postfix">minutes</span></span>
<p>I&#8217;ve been <a href="http://paulbupejr.com/4-layer-pcb-design/">designing a 4-layer PCB</a> for a product for a few months now and I finally got to the stage of assembling the prototype after the PCB and components arrived. Most of the passive components I used were 0603 surface mount parts so reflow soldering was the only viable option (if I wanted to maintain my sanity). </p>



<p>Since I don&#8217;t have a proper reflow oven, I decided to use the next best thing I own: No not my hot air rework station, a toaster oven! </p>



<span id="more-548"></span>



<figure class="wp-block-gallery columns-2 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/08/oven-1-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/08/oven-1-1024x768.jpg" alt="" data-id="551" data-link="http://paulbupejr.com/?attachment_id=551" class="wp-image-551" srcset="https://paulbupejr.com/wp-content/uploads/2019/08/oven-1-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/08/oven-1-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/08/oven-1-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">PCB with stencil</figcaption></figure></li><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/08/oven-2-1024x783.jpg"><img loading="lazy" decoding="async" width="1024" height="783" src="http://paulbupejr.com/wp-content/uploads/2019/08/oven-2-1024x783.jpg" alt="" data-id="552" data-link="http://paulbupejr.com/?attachment_id=552" class="wp-image-552" srcset="https://paulbupejr.com/wp-content/uploads/2019/08/oven-2-1024x783.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/08/oven-2-300x229.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/08/oven-2-768x587.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">PCB with components placed</figcaption></figure></li></ul></figure>



<p>There are, of course, <a href="https://hackaday.io/project/27900-reflowduino-wireless-reflow-controller-ecosystem">plenty of guides and tutorials online</a> for modifying a toaster oven for reflow soldering. They all involve a temperature PID loop to precisely control the heat profile for various solder types, components, etc,. </p>



<p>I really just wanted to see if I could just turn it on and see what happens. <strong>Spoiler Alert</strong>: It works. </p>



<p>I just preheated the toaster oven for a few minutes, stuck the PCB in there, and watched for the solder to start flowing. This took about 30 to 40 seconds. I wish there was more to this so I could do a more in-depth write-up but honestly that was it &#8212; nothing fancy and  no precise timing or temperature profiles.</p>



<p><strong>I gotta say, the final board is quite a beauty!</strong></p>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/08/oven-5.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/08/oven-5-1024x768.jpg" alt="" class="wp-image-555" srcset="https://paulbupejr.com/wp-content/uploads/2019/08/oven-5-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/08/oven-5-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/08/oven-5-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption>The final board</figcaption></figure>



<h2 class="wp-block-heading">The Fine Print</h2>



<p>Do this at your own risk!  I did it because I&#8217;m just building a prototype and the final board will be professionally assembled. In addition, I know what I&#8217;m doing and I read the datasheets of all my critical components. You&#8217;ll notice that I did not put the electrolytic capacitor in the oven &#8212; I could not guarantee not to violate the very precise timings and temperatures specified in the datasheet. Also, please mind the fumes. </p>
<p>The post <a href="https://paulbupejr.com/reflow-soldering-in-unmodified-toaster-oven/">Reflow Soldering in Unmodified Toaster Oven?</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/reflow-soldering-in-unmodified-toaster-oven/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Designing an Advanced Autonomous Robot: Goose</title>
		<link>https://paulbupejr.com/autonomous-robot-design/</link>
					<comments>https://paulbupejr.com/autonomous-robot-design/#comments</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Tue, 30 Jul 2019 23:37:01 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Robotics]]></category>
		<category><![CDATA[lidar]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[raspberry pi]]></category>
		<category><![CDATA[robotics]]></category>
		<category><![CDATA[solidworks]]></category>
		<guid isPermaLink="false">http://paulbupejr.com/?p=363</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 10</span> <span class="rt-label rt-postfix">minutes</span></span>Update: This article was featured on Hackaday.com and on SDP/SI&#8217;s &#8220;Featured People and Organizations&#8221; page. Goose is a mobile autonomous robot I designed and built over 6 months in my spare time for a robotics competition. This was a fully custom and challenging build that tested my competence in electrical engineering, mechanical engineering, control systems, &#8230; <a href="https://paulbupejr.com/autonomous-robot-design/" class="more-link">Continue reading <span class="screen-reader-text">Designing an Advanced Autonomous Robot: Goose</span></a></p>
<p>The post <a href="https://paulbupejr.com/autonomous-robot-design/">Designing an Advanced Autonomous Robot: Goose</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 10</span> <span class="rt-label rt-postfix">minutes</span></span>
<p><strong>Update</strong>: This article was featured on <a href="https://hackaday.com/2019/08/08/designing-an-advanced-autonomous-robot-goose/" target="_blank" rel="noreferrer noopener">Hackaday.com</a> and on SDP/SI&#8217;s <a href="https://sdp-si.com/features/sdpsi-features.php" target="_blank" rel="noreferrer noopener">&#8220;Featured People and Organizations&#8221; page</a>.</p>



<p>Goose is a mobile autonomous robot I designed and built over 6 months in my spare time for a robotics competition. This was a fully custom and challenging build that tested my competence in electrical engineering, mechanical engineering, control systems, and computer science.  </p>



<p>Instead of focusing heavily on the competition, the goal of this article is to <em>briefly</em> go through the system design process. I&#8217;ll touch on my various design choices and discuss how I chose to address some of the common issues in designing an autonomous robot. This is not a tutorial (those will be coming later) but more of a case study. </p>



<figure class="wp-block-gallery columns-2 is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-19-1024x733.jpg"><img loading="lazy" decoding="async" width="1024" height="733" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-19-1024x733.jpg" alt="" data-id="367" data-link="http://paulbupejr.com/goose-19/" class="wp-image-367" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-19-1024x733.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-19-300x215.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-19-768x550.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure></li><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-20-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-20-1024x768.jpg" alt="" data-id="366" data-link="http://paulbupejr.com/goose-20/" class="wp-image-366" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-20-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-20-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-20-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure></li></ul></figure>



<span id="more-363"></span>



<h2 class="wp-block-heading">Competition and Results</h2>



<p>The basic premise of the competition was to have an autonomous robot  navigate a square arena (enclosed by four walls) and collect / sort&nbsp; multi-colored cubes and balls. It had to avoid fixed obstacles and had a 3-minute time limit. The robot was also required to &#8220;orbit&#8221; around the center of the arena in a counterclockwise fashion while performing the aforementioned tasks. </p>



<p>Goose was in second place after the first round then suffered a catastrophic reverse polarity condition at my hands (<a href="https://en.wikipedia.org/wiki/Murphy%27s_law">thanks Murphy</a>) prior to the second run. I made two critical mistakes:</p>



<ol class="wp-block-list"><li>I daisy-chained the power rail going to my two motor controllers instead of tying each directly to my power bus. This set me up for the upcoming cascading failure.</li><li>After being awake for over 24 hour I somehow reverse polarized the power rail going to my motor controllers, which destroyed them both. </li></ol>



<p>Even without a second round run, Goose did well enough in the first round to finish fourth overall in the Open competition.</p>



<h2 class="wp-block-heading">Hardware Design</h2>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-12.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-12-1024x768.jpg" alt="" class="wp-image-374" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-12-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-12-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-12-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption>The underside of the machined base with wiring harnesses connected </figcaption></figure>



<p>The first hardware decision I made was selecting the type of drive system the robot would employ.  Since the robot was constrained to a  9&#8243; x 9&#8243; x 11&#8243; box, and once I realized that I was just building a glorified vacuum cleaner, my design ideas converged towards a very compact <a href="https://en.wikipedia.org/wiki/WALL-E">Wall-E</a> type chassis.  </p>



<p>Based on experience I chose a tracked differential drive system, i.e., <a href="https://en.wikipedia.org/wiki/Holonomic_(robotics)">non-holonomic</a> like a tank. As a general rule you want to avoid using omnidirectional wheels an autonomous robot unless you have a localization system that gives you an accurate pose. Using a two-motor differential drive system allowed me to achieve a compact design by placing the geared motors in the rear and directly driving the tracks.  </p>



<p><a href="https://sdp-si.com/">SDP/SI</a> was gracious enough to provide me with the timing belts and pulleys I used in my custom drivebase (shown in the image above) so thanks to them!  I also would not have been able to build this robot without the amazing engineering/manufacturing facilities at <a href="https://cec.georgiasouthern.edu/">Georgia Southern University</a> that have state of the art equipment (such as the waterjet and laser cutter I used) available to students.</p>



<h3 class="wp-block-heading">Prototyping and Base Build</h3>



<p>After getting a rough idea of the physical design of the robot I started prototyping using SolidWorks, my 3D printer, and a laser cutter. My prototyping workflow involved first sketching out parts on paper, creating them in SolidWorks, then 3D printing or laser cutting them as needed. In total I ended up creating around 232 SolidWorks parts by the end of the build.</p>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-2.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-2-1024x768.jpg" alt="Rapid prototyping robot base" class="wp-image-384" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-2-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-2-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-2-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption>Rapid prototyping with wood and acrylic</figcaption></figure>



<figure class="wp-block-gallery columns-2 is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-21-1024x546.jpg"><img loading="lazy" decoding="async" width="1024" height="546" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-21-1024x546.jpg" alt="" data-id="365" data-link="http://paulbupejr.com/goose-21/" class="wp-image-365" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-21-1024x546.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-21-300x160.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-21-768x410.jpg 768w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-21.jpg 1919w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">Partial SolidWorks 3D model</figcaption></figure></li><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-3-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-3-1024x768.jpg" alt="" data-id="383" data-link="http://paulbupejr.com/goose-3/" class="wp-image-383" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-3-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-3-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-3-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">Track prototype</figcaption></figure></li></ul></figure>



<p>The biggest issue I ran into was figuring out how to remove play from the shaft in the bearing. The inner race of the bearing would move when under tension which caused alignment issues with the belt.  The shaft was anchored at one end only&nbsp;because there was no room to add a second bearing (even a sleeve bearing) on the outer plate end due to the competition size constraints. </p>



<figure class="wp-block-gallery columns-2 is-cropped wp-block-gallery-5 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-7-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-7-1024x768.jpg" alt="" data-id="379" data-link="http://paulbupejr.com/goose-7/" class="wp-image-379" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-7-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-7-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-7-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">Bearing assembly with shaft</figcaption></figure></li><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-8-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-8-1024x768.jpg" alt="" data-id="378" data-link="http://paulbupejr.com/goose-8/" class="wp-image-378" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-8-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-8-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-8-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">3D printed bearing sleeves mounted on brackets</figcaption></figure></li></ul></figure>



<p>I was able to overcome this issue by designing a sturdy bearing mount that I mounted on the inside of the bracket then added a smaller acrylic mount with a sleeve bearing on the outside. This, along with shortening the shaft, was able to remove any play from the shaft under tension. I also added a very small lip to the pulleys to prevent the belt from slipping. The final base used aluminum which was machined using a <a href="https://www.omax.com/maxiem-waterjet/1515">MAXIEM 1515 waterjet cutter</a>. </p>



<figure class="wp-block-gallery columns-2 is-cropped wp-block-gallery-6 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-4-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-4-1024x768.jpg" alt="" data-id="382" data-link="http://paulbupejr.com/goose-4/" class="wp-image-382" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-4-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-4-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-4-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">Cutting aluminum on a waterjet</figcaption></figure></li><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-13-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-13-1024x768.jpg" alt="" data-id="373" data-link="http://paulbupejr.com/goose-13/" class="wp-image-373" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-13-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-13-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-13-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">The finished drivebase</figcaption></figure></li></ul></figure>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Goose &quot;Static Fire&quot; Test" width="660" height="371" src="https://www.youtube.com/embed/LapK2Nf0OVU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div><figcaption>Testing the right drive assembly at full power</figcaption></figure>



<p>The remaining parts were created using wood with the help of a laser cutter. </p>



<figure class="wp-block-gallery columns-3 is-cropped wp-block-gallery-7 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-25-1024x711.jpg"><img loading="lazy" decoding="async" width="1024" height="711" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-25-1024x711.jpg" alt="" data-id="403" data-link="http://paulbupejr.com/goose-25/" class="wp-image-403" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-25-1024x711.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-25-300x208.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-25-768x534.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">Cutting out wood</figcaption></figure></li><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-15-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-15-1024x768.jpg" alt="" data-id="371" data-link="http://paulbupejr.com/goose-15/" class="wp-image-371" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-15-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-15-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-15-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">First test fit</figcaption></figure></li><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-17-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-17-1024x768.jpg" alt="" data-id="369" data-link="http://paulbupejr.com/goose-17/" class="wp-image-369" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-17-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-17-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-17-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">Staining the wood</figcaption></figure></li></ul></figure>



<h2 class="wp-block-heading">Electronics</h2>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Electronics-1.png"><img loading="lazy" decoding="async" width="878" height="727" src="http://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Electronics-1.png" alt="" class="wp-image-388" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Electronics-1.png 878w, https://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Electronics-1-300x248.png 300w, https://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Electronics-1-768x636.png 768w" sizes="auto, (max-width: 878px) 100vw, 878px" /></a></figure>



<p>The electronics subsystem of Goose utilized an architecture that I have been tweaking for my autonomous robot designs over many years. The main idea is to minimize the cost of failure by isolating as many systems as possible and using generalized interfaces to connect the systems, i.e., modularization. All the supply rails are also individually fused with on/off switches and indicators. </p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="687" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-24-1024x687.jpg" alt="" class="wp-image-404" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-24-1024x687.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-24-300x201.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-24-768x515.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>Control panel</figcaption></figure>



<p>Some core safety features of my architecture include:</p>



<ul class="wp-block-list"><li>Proper fusing for overcurrent protection.</li><li><a href="https://en.wikipedia.org/wiki/Crowbar_(circuit)">Crowbar circuits</a> for overvoltage protection. Crowbar circuits require very careful design in order to avoid false triggers due to noise or a narrow operating band.  </li><li>High current <a href="https://www.analog.com/en/technical-articles/primer-on-powerpath-controllers-ideal-diodes-prioritizers.html">ideal diodes</a> for reverse polarity protection. <strong>I did not include this in Goose and of course suffered a competition ending reverse-polarity condition so I won&#8217;t skip it again</strong>!</li></ul>



<p>All these concepts are nothing new in electronics but striking the right balance between complexity and functionality for any one particular application can be tricky, especially when creating an autonomous robot.  </p>



<p>Even though this system did not contain any sensitive analog circuitry, I still isolated the noisy motor power rail from the rest of the circuitry, eventually tying everything together at a single point at the battery in the <a href="https://www.analog.com/en/analog-dialogue/articles/staying-well-grounded.html">&#8220;star ground&#8221;</a> configuration. It&#8217;s always important to have a good idea of the major current paths in your circuits so you can spot any potential issues like ground loops &#8212; this does not require advanced knowledge of mesh analysis! </p>



<h3 class="wp-block-heading">Mainboard</h3>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-18-e1560883236583.jpg"><img loading="lazy" decoding="async" width="1024" height="925" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-18-e1560883236583-1024x925.jpg" alt="" class="wp-image-368" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-18-e1560883236583-1024x925.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-18-e1560883236583-300x271.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-18-e1560883236583-768x694.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption>Custom circuit with various sensor interfaces and drivers.</figcaption></figure>



<p>I have made it a habit to always use soldered PCBs for my projects. While breadboards are useful in the very initial stages of prototyping, they should not be used for anything past initial testing and brainstorming &#8212; they are too unreliable and can be difficult to troubleshoot due to issues like intermittent connections. Depending on your level of experience most analog circuits can be designed using a <a href="https://www.analog.com/en/design-center/design-tools-and-calculators/ltspice-simulator.html">SPICE</a> simulator and some basic math.</p>



<p>I designed the board for GOOSE using a stripboard. Stripboards are easier to use than regular solderable PCBs for more complicated circuits because they have connected strips (thus the name) that you cut to break the circuit at a desired point. This means you don&#8217;t have to solder a lot of holes in order to make a power bus or run a signal to multiple pins. Just don&#8217;t forget to cut the traces or you&#8217;ll have a pretty bad day!</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="880" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-9-1024x880.jpg" alt="" class="wp-image-377" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-9-1024x880.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-9-300x258.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-9-768x660.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>The bottom of the stripboard before I cut the traces</figcaption></figure>



<p>The board contained the 5V and 3.3V power rails rated up to 2.5A, two PWM MOSFET driver circuits, a logic level converter, 9 DoF IMU, and the Teensy microcontroller. There are also a few other assorted supporting components. </p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="866" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-10-1024x866.jpg" alt="" class="wp-image-376" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-10-1024x866.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-10-300x254.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-10-768x650.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>Unpopulated stripboard</figcaption></figure>



<h3 class="wp-block-heading">Cabling and Wiring Harnesses</h3>



<p>One of the most important and necessary skills in robotics is being able to make cables and wiring harnesses that are custom to the robot. While the process can be tedious, it results in a more reliable and professional end product. I typically use 2.54mm JST-XH connectors and &#8220;Dupont&#8221; connectors for my wiring when working with prototype boards. There&#8217;s quite a lot behind the names of connectors so I encourage you to read <a href="http://tech.mattmillman.com/info/crimpconnectors/">this article</a> which does a great job summarizing most of what you&#8217;ll need to know about crimpers and connectors. For high current applications I used regular spade connectors and <a href="https://www.amazon.com/221-412-2-Conductor-Compact-Splicing-Connectors/dp/B00JB3U7Y6/ref=pd_lpo_sbs_60_t_1?_encoding=UTF8&amp;psc=1&amp;refRID=Z81BSPGB7V3S030DB7XS">Wago 221 connectors</a> for creating power busses. You can get generic versions of these on eBay and similar sites. </p>



<p>When creating long runs on this project I cannibalized a CAT5 cable and crimped on my own connectors to the ends. This was especially ideal because the twisted pairs meant I could effectively run differential signals if needed. </p>



<figure class="wp-block-gallery columns-2 is-cropped wp-block-gallery-8 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-16-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-16-1024x768.jpg" alt="" data-id="370" data-link="http://paulbupejr.com/goose-16/" class="wp-image-370" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-16-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-16-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-16-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">Properly crimped and insulated connectors</figcaption></figure></li><li class="blocks-gallery-item"><figure><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-23-1024x768.jpg"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-23-1024x768.jpg" alt="" data-id="405" data-link="http://paulbupejr.com/goose-23/" class="wp-image-405" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-23-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-23-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-23-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="blocks-gallery-item__caption">Wire harnesses from CAT5 cable</figcaption></figure></li></ul></figure>



<p>The <a href="https://standards.nasa.gov/standard/nasa/nasa-std-87394">NASA Standard for Crimping, Interconnecting Cables, Harnesses, And Wiring</a> is a great resource for learning from the pros. While most of the crimping tools they use cost in the hundreds of dollars on the low end, the information is still relevant and quite useful!</p>



<h3 class="wp-block-heading">Processing Subsystem</h3>



<p>I used two processing cores for Goose: a <a href="https://www.pjrc.com/teensy/techspecs.html">Teensy 3.2</a> (32 bit ARM Cortex-M4) microcontroller to handle all the deterministic logic, and a Debian-based <a href="https://www.raspberrypi.org/products/raspberry-pi-3-model-b-plus/">Raspberry Pi 3B+</a> for the more heavy computational work dealing with mapping and image processing. The Raspberry Pi was running the <a href="https://www.ros.org/">Robot Operating System</a> (ROS) and the Teensy communicated to the Pi via USB serial.</p>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-22.jpg"><img loading="lazy" decoding="async" width="1024" height="766" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-22-1024x766.jpg" alt="" class="wp-image-406" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-22-1024x766.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-22-300x224.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-22-768x574.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption>The two &#8220;brains&#8221; of Goose connected together.</figcaption></figure>



<p>Running at 96 MHz, the Teensy was fast enough to process data from two quadrature encoders and perform real-time odometry calculations; run an AHRS fusion algorithm from a 9 DoF IMU at about 2.1 kHz; run multiple PID loops; monitor two ultrasonic sensors at a high refresh rate, and send all this data to the Pi at a baud rate of 500,000. I had several ROS nodes running on the Teensy which communicated to the ROS Master on the Pi. As an example, I used the handler below to process messages from the Pi to the Teensy and then command the setpoint of the PID controllers:</p>



<pre class="wp-block-code"><code>void process_velocities(const geometry_msgs::Twist&amp; cmd_msg)
{
	double x = cmd_msg.linear.x;	// forward velocity
	double z = cmd_msg.angular.z;	// rotational velocity

	if (z == 0) { // going straight
		left_motor_setpoint = x * 60 / (PI*wheel_diameter);
		right_motor_setpoint = left_motor_setpoint;
	}
	else if (x == 0) // turning in place
	{
		left_motor_setpoint = z * track_width * 60 / (wheel_diameter* PI * 2);
		right_motor_setpoint = -left_motor_setpoint;
	}
	else 
	{
		left_motor_setpoint = x * 60 / (PI * wheel_diameter) - z * track_width * 60 / (wheel_diameter * PI * 2);
		right_motor_setpoint = x * 60 / (PI * wheel_diameter) + z * track_width * 60 / (wheel_diameter * PI * 2);
	}
} // process_velocities()</code></pre>



<p class="has-text-align-center has-small-font-size"><em>Handler used to process velocity messages from the Pi and command the PID setpoints</em></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>I initially considered and prototyped using a <a href="https://beagleboard.org/black">BeagleBone Black</a> since it contains two deterministic 32-bit PRU processing cores that can be accessed from the Linux system but I found the development overhead not worth it for one person with limited time. I wrote a few articles based on that experience <a href="http://paulbupejr.com/beaglebone-black-internet-over-usb/">here</a>, <a href="http://paulbupejr.com/change-cloud9-workspace/">here</a>, and <a href="http://paulbupejr.com/adding-swap-memory-to-the-beaglebone-black/">here</a>.</p>



<h3 class="wp-block-heading">Localization and Navigation Subsystem</h3>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/06/Goose-14-1024x768.jpg" alt="" class="wp-image-372" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/Goose-14-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-14-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/06/Goose-14-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The competition rules required the robot to move in large circles for the duration of the run which meant I couldn&#8217;t use encoder-based dead reckoning; the act of turning introduces errors due to drift and slippage which would accumulate to unacceptable levels over the course of the 3 minute run. </p>



<p>To counter this issue, I took advantage of the fact that the arena was enclosed by four walls in a square to develop a navigation system that used encoder odometry, IMU feedback, and LiDAR point cloud data to effectively pinpoint the location of the robot at all times.</p>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Localization.png"><img loading="lazy" decoding="async" width="868" height="665" src="http://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Localization.png" alt="" class="wp-image-387" srcset="https://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Localization.png 868w, https://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Localization-300x230.png 300w, https://paulbupejr.com/wp-content/uploads/2019/06/IEEEbot-Localization-768x588.png 768w" sizes="auto, (max-width: 868px) 100vw, 868px" /></a></figure>



<p>As shown in the figure above, the basic idea was to use a pre-made map of the environment and then use point cloud data from the LiDAR in addition to the pose esitmate from to localize using a particle filter algorithm. I created the map in Adobe Illustrator and then converted it to a pgm file for use in ROS. </p>



<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="300" height="300" src="http://paulbupejr.com/wp-content/uploads/2019/07/map-300x300.png" alt="" class="wp-image-469" srcset="https://paulbupejr.com/wp-content/uploads/2019/07/map-300x300.png 300w, https://paulbupejr.com/wp-content/uploads/2019/07/map-150x150.png 150w, https://paulbupejr.com/wp-content/uploads/2019/07/map-768x768.png 768w, https://paulbupejr.com/wp-content/uploads/2019/07/map-1024x1024.png 1024w, https://paulbupejr.com/wp-content/uploads/2019/07/map-45x45.png 45w, https://paulbupejr.com/wp-content/uploads/2019/07/map.png 1802w" sizes="auto, (max-width: 300px) 100vw, 300px" /><figcaption>Map used to generate an occupancy grid for navigation in ROS</figcaption></figure></div>



<p>Localization inside a square would be difficult using LiDAR only (since all corners look the same and corner matching would fail) so I incorporated the pose estimate generated by fusing the encoder odometry data and the 9 DoF IMU using an unscented Kalman filter. I used an unscented Kalman filter (as opposed to the extended Kalman filter) for handling the nonlinear data because it is <em>generally</em> more accurate and has less computational complexity since there&#8217;s no need to calculate the Jacobian matrix.</p>



<figure class="wp-block-embed-youtube aligncenter wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Differential Drive PID Test" width="660" height="371" src="https://www.youtube.com/embed/TZl-nySItxE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div><figcaption>Testing the tuning of the two motor PID loops</figcaption></figure>



<h4 class="wp-block-heading">Side note:</h4>



<p>I have written a paper that includes some experimentation on developing a computationally efficient 2D navigation algorithm (for a microcontroller-based autonomous robot) which I might revise and release when I have the time. The algorithm I developed had a time complexity of O(n). Below is a page from the paper showing part of my experimental setup and a mapping / vector generated by the algorithm. I used a <a href="http://en.benewake.com/product/detail/5c345e26e5b3a844c472329c.html">TFmini</a> short-range LiDAR module for these experiments. </p>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/07/paul_tfmini_experiments.png"><img loading="lazy" decoding="async" width="810" height="1013" src="http://paulbupejr.com/wp-content/uploads/2019/07/paul_tfmini_experiments.png" alt="" class="wp-image-433" srcset="https://paulbupejr.com/wp-content/uploads/2019/07/paul_tfmini_experiments.png 810w, https://paulbupejr.com/wp-content/uploads/2019/07/paul_tfmini_experiments-240x300.png 240w, https://paulbupejr.com/wp-content/uploads/2019/07/paul_tfmini_experiments-768x960.png 768w" sizes="auto, (max-width: 810px) 100vw, 810px" /></a></figure>



<h2 class="wp-block-heading">Final Thoughts</h2>



<p>This project was certainly fun and a lot of work! There&#8217;s so much more to this robot I haven&#8217;t even touched on in this article but for the sake of keeping it &#8220;brief&#8221; I will have to end it here. </p>



<p>If time permits I may write a separate article on each system of the robot along with any associated source code and hardware info; possibly a series on building an advanced autonomous robot. I would like to go into more details on the software side and the workflow I came up with for working easily with ROS on a Raspberry Pi and a Teensy microcontroller. </p>



<p>Let me know your thoughts on this build or if you&#8217;d like to see any tutorials based on what&#8217;s in this build or robotics in general!</p>
<p>The post <a href="https://paulbupejr.com/autonomous-robot-design/">Designing an Advanced Autonomous Robot: Goose</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/autonomous-robot-design/feed/</wfw:commentRss>
			<slash:comments>19</slash:comments>
		
		
			</item>
		<item>
		<title>4-Layer PCB Design in KiCad 5: Quick Thoughts</title>
		<link>https://paulbupejr.com/4-layer-pcb-design/</link>
					<comments>https://paulbupejr.com/4-layer-pcb-design/#comments</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Wed, 24 Jul 2019 14:08:31 +0000</pubDate>
				<category><![CDATA[PCB Design]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://paulbupejr.com/?p=500</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 2</span> <span class="rt-label rt-postfix">minutes</span></span>I recently had to design a 4-layer PCB and I finally decided to give KiCad another try (after hearing great things about version 5). I&#8217;ve known about KiCad for years and even tried it once a few years back but it never felt quite &#8220;there&#8221; yet. After spending a few months designing a 4-layer board &#8230; <a href="https://paulbupejr.com/4-layer-pcb-design/" class="more-link">Continue reading <span class="screen-reader-text">4-Layer PCB Design in KiCad 5: Quick Thoughts</span></a></p>
<p>The post <a href="https://paulbupejr.com/4-layer-pcb-design/">4-Layer PCB Design in KiCad 5: Quick Thoughts</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 2</span> <span class="rt-label rt-postfix">minutes</span></span>
<p>I recently had to design a 4-layer PCB and I finally decided to give <a href="http://www.kicad-pcb.org/">KiCad</a> another try (after hearing great things about version 5). I&#8217;ve known about KiCad for years and even tried it once a few years back but it never felt quite &#8220;there&#8221; yet. After spending a few months designing a 4-layer board I have to say it has certainly won me over.</p>



<span id="more-500"></span>



<p>I had to design a fairly complex PCB that included a switching supply, high currents, plenty of thermal vias, high frequency traces, and some mixed-signal work so I was really curious to see what KiCad could do. </p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="821" src="http://paulbupejr.com/wp-content/uploads/2019/07/b2-1024x821.jpeg" alt="" class="wp-image-509" srcset="https://paulbupejr.com/wp-content/uploads/2019/07/b2-1024x821.jpeg 1024w, https://paulbupejr.com/wp-content/uploads/2019/07/b2-300x241.jpeg 300w, https://paulbupejr.com/wp-content/uploads/2019/07/b2-768x616.jpeg 768w, https://paulbupejr.com/wp-content/uploads/2019/07/b2.jpeg 1140w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="768" src="http://paulbupejr.com/wp-content/uploads/2019/08/oven-4-1024x768.jpg" alt="" class="wp-image-554" srcset="https://paulbupejr.com/wp-content/uploads/2019/08/oven-4-1024x768.jpg 1024w, https://paulbupejr.com/wp-content/uploads/2019/08/oven-4-300x225.jpg 300w, https://paulbupejr.com/wp-content/uploads/2019/08/oven-4-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>One of the most useful features in my opinion is the ability to easily view an interactive 3D rendering of the board with no additional setup. The ability to hide the soldermask and view just the copper layer in the 3D view is a great sanity check on top of the DRC.</p>



<p>Another <strong>really really really</strong> great feature of KiCad is the ability to <strong><em>easily</em></strong> import any 3D model as an STL or wrl file and visually align and scale it to a footprint. This feature coupled with a site like <a href="https://www.3dcontentcentral.com/">3D Content Central</a> that allows you find 3D models from virtually any supplier for free makes accurate PCB design really stress free.</p>



<figure class="wp-block-image"><a href="http://paulbupejr.com/wp-content/uploads/2019/07/b3.jpeg"><img loading="lazy" decoding="async" width="1024" height="897" src="http://paulbupejr.com/wp-content/uploads/2019/07/b3-1024x897.jpeg" alt="" class="wp-image-512" srcset="https://paulbupejr.com/wp-content/uploads/2019/07/b3-1024x897.jpeg 1024w, https://paulbupejr.com/wp-content/uploads/2019/07/b3-300x263.jpeg 300w, https://paulbupejr.com/wp-content/uploads/2019/07/b3-768x673.jpeg 768w, https://paulbupejr.com/wp-content/uploads/2019/07/b3.jpeg 1068w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Another underrated KiCad &#8220;feature&#8221; I have come to love is just how easy it is to move or copy components around in the schematic editor without having to hold down a mouse button. I think this feature, coupled with the convenient shortcuts, saved me quite a bit of time. </p>



<p>Based on this experience I think I&#8217;ll definitely stick with KiCad for PCB design until the single license cost for Altium becomes more reasonable. Expect a few detailed KiCad tutorials from me in the near future!</p>
<p>The post <a href="https://paulbupejr.com/4-layer-pcb-design/">4-Layer PCB Design in KiCad 5: Quick Thoughts</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/4-layer-pcb-design/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Adding Swap Memory to the Beaglebone Black</title>
		<link>https://paulbupejr.com/adding-swap-memory-to-the-beaglebone-black/</link>
					<comments>https://paulbupejr.com/adding-swap-memory-to-the-beaglebone-black/#comments</comments>
		
		<dc:creator><![CDATA[paulbupe]]></dc:creator>
		<pubDate>Mon, 31 Dec 2018 22:48:37 +0000</pubDate>
				<category><![CDATA[BeagleBone Black]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[beaglebone]]></category>
		<category><![CDATA[beaglebone black]]></category>
		<category><![CDATA[linux]]></category>
		<guid isPermaLink="false">http://paulbupejr.com/?p=336</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 2</span> <span class="rt-label rt-postfix">minutes</span></span>I recently needed to build Python 3.6 from source on the BeagleBone Black for a robotics project and discovered that the build would always fail after running out of memory. Who could have figured that 512MB of RAM wasn&#8217;t enough to build Python from source?! While I could have set up cross-compilation and performed the &#8230; <a href="https://paulbupejr.com/adding-swap-memory-to-the-beaglebone-black/" class="more-link">Continue reading <span class="screen-reader-text">Adding Swap Memory to the Beaglebone Black</span></a></p>
<p>The post <a href="https://paulbupejr.com/adding-swap-memory-to-the-beaglebone-black/">Adding Swap Memory to the Beaglebone Black</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 2</span> <span class="rt-label rt-postfix">minutes</span></span>
<p>I recently needed to build Python 3.6 from source on the BeagleBone Black for a robotics project and discovered that the build would always fail after running out of memory. Who could have figured that 512MB of RAM wasn&#8217;t enough to build Python from source?! While I could have set up cross-compilation and performed the heavy lifting on my computer with more resources, I figured this was a perfect problem to solve by adding swap memory to the BeagleBone Black.</p>



<span id="more-336"></span>



<h2 class="wp-block-heading">What is a swap space?</h2>



<p>At a very high level, a swap space (usually in the form of a partition) allows the system to move some of the &#8220;lower priority&#8221; memory pages (blocks of memory) to the partition or file so that higher priority tasks can use the memory. The combined size of the physical memory and swap space is called <em>virtual memory</em>. Gary Sims has a great primer on swap spaces over at <a href="https://www.linux.com/news/all-about-linux-swap-space">linux.com</a></p>



<p>In this case, the BeagleBone Black only has 512MB of RAM so I&#8217;ll be adding ~1GB of swap space to my SD card in the form of a swap file. This will allow it to perform more memory-intensive tasks without running out of memory (at a cost of slower access times).</p>



<h2 class="wp-block-heading">Creating a swap file</h2>



<p>Creating a swap space is a fairly simple process that involves creating a file (and filling it with zeros) then telling the system to use that file as a swap space. Finally, the system has to be configured to load that file on startup.</p>



<h5 class="wp-block-heading">Check if you already have a swap file</h5>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">sudo swapon -s</pre></div>



<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="670" height="77" src="http://paulbupejr.com/wp-content/uploads/2018/12/swapon.png" alt="" class="wp-image-343" srcset="https://paulbupejr.com/wp-content/uploads/2018/12/swapon.png 670w, https://paulbupejr.com/wp-content/uploads/2018/12/swapon-300x34.png 300w" sizes="auto, (max-width: 670px) 100vw, 670px" /></figure></div>



<p>In my case I already created the file so it&#8217;s shown. The assumptions is that you&#8217;re performing these steps because you don&#8217;t have a swap space.</p>



<h5 class="wp-block-heading">Create the swap file</h5>



<p>Use the <code>dd </code>utility to create a file with a fixed size and fill it with &#8220;zeroes&#8221;. In this case I&#8217;m moving 1000 &#8220;zeroes&#8221; from <code>/dev/zero</code> in block sizes of 1024k (1MB) into my file at&nbsp;<code>/var/cache/swap/swapfile</code>. This will result in a swap file of around 1 gigabyte. <em>Keep in mind that the swap file is actually named &#8220;swapfile&#8221; with no extension</em>.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">sudo dd if=/dev/zero of=/var/cache/swap/swapfile bs=1024k count=1000</pre></div>



<p>use <code>chmod </code>to change the file permissions of the new swap file.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">sudo chmod 0600 /var/cache/swap/swapfile</pre></div>



<p>Use the <code>mkswap&nbsp; </code>command to create the swap area using our newly created swap file.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">sudo mkswap /var/cache/swap/swapfile</pre></div>



<p>Finally, enable the swap area with the <code>swapon </code>command</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">sudo swapon /var/cache/swap/swapfile</pre></div>



<h5 class="wp-block-heading">Configure the swap file to automatically mount on boot</h5>



<p>Open up the <code>/etc/fstab</code> file with the <code>nano </code>editor.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">sudo nano /etc/fstab</pre></div>



<p>Append the following line to the file:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">/var/cache/swap/swapfile    none   swap   sw   0   0</pre></div>



<p>That is all there is to it for this specific case &#8211; adding swap memory to the BeagleBone Black is pretty straightforward! </p>



<div class="wp-block-image wp-image-344 size-full"><figure class="aligncenter"><img loading="lazy" decoding="async" width="689" height="227" src="http://paulbupejr.com/wp-content/uploads/2018/12/top2.png" alt="" class="wp-image-344" srcset="https://paulbupejr.com/wp-content/uploads/2018/12/top2.png 689w, https://paulbupejr.com/wp-content/uploads/2018/12/top2-300x99.png 300w" sizes="auto, (max-width: 689px) 100vw, 689px" /><figcaption>The newly created swap space being heavily during building</figcaption></figure></div>
<p>The post <a href="https://paulbupejr.com/adding-swap-memory-to-the-beaglebone-black/">Adding Swap Memory to the Beaglebone Black</a> appeared first on <a href="https://paulbupejr.com">Paul Bupe Jr, PhD</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://paulbupejr.com/adding-swap-memory-to-the-beaglebone-black/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)

Served from: paulbupejr.com @ 2026-04-21 13:37:45 by W3 Total Cache
-->