<?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>Micro Controller &#8211; Erik Makes Things</title>
	<atom:link href="https://erikmakesthings.ddns.net/category/micro-controller/feed/" rel="self" type="application/rss+xml" />
	<link>https://erikmakesthings.ddns.net</link>
	<description></description>
	<lastBuildDate>Fri, 12 Dec 2025 16:21:07 +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://erikmakesthings.ddns.net/wp-content/uploads/2025/06/cropped-E-3-32x32.png</url>
	<title>Micro Controller &#8211; Erik Makes Things</title>
	<link>https://erikmakesthings.ddns.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>IoT Honeypot Capstone Project</title>
		<link>https://erikmakesthings.ddns.net/iot-honeypot-capstone-project/</link>
					<comments>https://erikmakesthings.ddns.net/iot-honeypot-capstone-project/#comments</comments>
		
		<dc:creator><![CDATA[Erik]]></dc:creator>
		<pubDate>Wed, 10 Dec 2025 20:11:50 +0000</pubDate>
				<category><![CDATA[Cybersecurity]]></category>
		<category><![CDATA[Micro Controller]]></category>
		<category><![CDATA[Homelab]]></category>
		<category><![CDATA[IoT]]></category>
		<guid isPermaLink="false">https://erikmakesthings.ddns.net/?p=314</guid>

					<description><![CDATA[Project Goal For our Capstone project, we built a multi-protocol IoT honeypot designed to help students understand modern home-lab security and how easily common IoT protocols can be explored or abused when controls are weak. The goal was to create a realistic-looking device that could safely log attacker-style interactions and turn them into something instructors [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Project Goal</h2>



<p>For our Capstone project, we built a multi-protocol IoT honeypot designed to help students understand modern home-lab security and how easily common IoT protocols can be explored or abused when controls are weak. The goal was to create a realistic-looking device that could safely log attacker-style interactions and turn them into something instructors and students could learn from in a controlled environment.</p>



<figure class="wp-block-image aligncenter size-large"><img fetchpriority="high" decoding="async" width="1024" height="601" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-15-38-03-1024x601.png" alt="" class="wp-image-352" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-15-38-03-1024x601.png 1024w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-15-38-03-300x176.png 300w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-15-38-03-768x451.png 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-15-38-03-1536x902.png 1536w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-15-38-03-2048x1203.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Hardware &amp; Architecture</h2>



<p>A key design constraint shaped the entire build: the Seeed Studio XIAO ESP32-C6 can’t run 2.4 GHz Wi-Fi and Zigbee (802.15.4) at the same time. To solve this, we split the honeypot into two identical ESP32-C6 boards.</p>



<ul class="wp-block-list">
<li><strong>Bottom board:</strong> Dedicated Zigbee coordinator with intentionally weak security to encourage join attempts. It converts Zigbee events into small JSON objects and sends them to the top board over UART.</li>



<li><strong>Top board:</strong> Acts like a multi-protocol gateway. It connects to Wi-Fi, exposes an HTTP dashboard, interacts with an MQTT broker, advertises a believable BLE GATT profile, and logs events from all four protocol surfaces (HTTP, MQTT, BLE, Zigbee).</li>
</ul>



<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 class="wp-block-image aligncenter size-large"><img decoding="async" width="2560" height="2560" data-id="351" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/bunchOparts-edited-scaled.jpg" alt="" class="wp-image-351" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/bunchOparts-edited-scaled.jpg 2560w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/bunchOparts-edited-300x300.jpg 300w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/bunchOparts-edited-1024x1024.jpg 1024w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/bunchOparts-edited-150x150.jpg 150w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/bunchOparts-edited-768x768.jpg 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/bunchOparts-edited-1536x1536.jpg 1536w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/bunchOparts-edited-2048x2048.jpg 2048w" sizes="(max-width: 2560px) 100vw, 2560px" /></figure>
</figure>



<h2 class="wp-block-heading">Designing the Enclosure</h2>



<p>To make the honeypot practical and portable, I designed a custom case in FreeCAD around the boards’ dimensions and mounting needs. The enclosure was 3D printed in HYPER-PLA on my Ender 3. To simplify maintenance, I included magnet-based snap-fit closure using 10 mm × 3 mm magnets instead of screws. I also integrated a lid mount for a small 5 V solar panel, then finished the chassis with a yellow paint job and honeycomb theme to visually reinforce the “honeypot” identity during demos.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:25%">
 [<a href="https://erikmakesthings.ddns.net/iot-honeypot-capstone-project/">See image gallery at erikmakesthings.ddns.net</a>] 
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<div class="wp-block-cover" style="min-height:323px;aspect-ratio:unset;"><video class="wp-block-cover__video-background intrinsic-ignore" autoplay muted loop playsinline src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/3dPrinters-1.mp4" data-object-fit="cover"></video><span aria-hidden="true" class="wp-block-cover__background has-background-dim"></span><div class="wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow">
<p class="has-text-align-center has-large-font-size"></p>
</div></div>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:25%">
 [<a href="https://erikmakesthings.ddns.net/iot-honeypot-capstone-project/">See image gallery at erikmakesthings.ddns.net</a>] 
</div>
</div>



<h2 class="wp-block-heading">How it works</h2>



<p>The top board is where the honeypot feels like a real device to an attacker. On boot, the firmware starts serial, connects to Wi-Fi, configures time using NTP, initializes the HTTP server, MQTT client, BLE stack, and then brings up the Serial1 UART link to the Zigbee board. It also generates a short unique ID based on the board’s MAC address so multiple nodes can be deployed without manual topic configuration. It then continuously services HTTP requests, processes MQTT traffic, and reads Zigbee JSON messages from the UART link.</p>



<p>Because the microcontroller has limited memory, the system avoids long-term storage and instead uses separate ring buffers for each protocol. Each buffer stores the most recent 50 events, overwriting older entries as new ones arrive. Every entry includes a timestamp, event type, and protocol-specific details such as HTTP path, MQTT topic/payload, BLE address, or Zigbee</p>



<p>The MQTT component is designed to look believable to scanners and testers. The top board connects to a broker on the core VLAN, builds a client name and topic prefix from its MAC-derived ID, publishes an “online” status message, and subscribes to an input topic pattern. When messages arrive, a callback logs the event and echoes the content back to an output topic.</p>



<p>For BLE, the device uses the NimBLE stack to present as a plausible smart device named <em>“Honey-LightBLE.”</em> The advertised services include familiar standards like Device Information and Battery Service alongside a fake configuration-style service. Read/write callbacks record which characteristic UUID was accessed, the client’s BLE address when available, and both hex and ASCII representations of any data written. If a client writes to a state-like characteristic, the honeypot sends a notification back to simulate a real device response.</p>



<p>Rather than trying to merge all radios onto one chip at once, Zigbee events are forwarded from the bottom board using a clean, simple UART protocol. The top board reads Serial1 until it sees a newline, then attempts to parse the line as JSON. If the object contains an &#8220;evt&#8221; field, it is logged into the Zigbee ring buffer; if parsing fails, the firmware logs an error event instead.</p>



<p>The bottom ESP32-C6 is dedicated to Zigbee. Its setup initializes debugging serial, the UART link, LED state, and sends early “boot/hello” style events for quick verification from the top board’s dashboard. Zigbee logic runs inside a separate task (esp_zb_task), keeping the coordinator responsibilities isolated from the multi-protocol gateway functions.</p>



<h2 class="wp-block-heading">Setting Up the Lab</h2>



<p>To keep the project realistic but safe, I built a dedicated testing environment on my home network using VLAN segmentation on my UniFi gateway. The lab was designed so our team could run recon and protocol testing against the honeypot without putting my everyday devices or core services at risk. The structure also reflects how an enterprise would isolate IoT systems to reduce lateral movement and limit blast radius if a device becomes compromised.</p>



<p>I created three main network segments. The core VLAN (10.0.0.x) hosts my critical services, including my main Ubuntu server (“wifu-server”) running Docker containers like my web server and Home Assistant, as well as a separate DNS cache server. The IoT VLAN (10.0.11.x) is used exclusively for testing and contains the honeypot plus several real IoT devices such as a Litter-Robot 4, an Ecobee thermostat, and a wired Philips Hue bridge and bulbs. The main VLAN is reserved for personal devices (laptops, phones, TVs, etc.) and is intentionally out of scope to keep experimental traffic away from my daily-use equipment.</p>



<figure class="wp-block-image aligncenter size-large"><img decoding="async" width="1024" height="681" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/NetDiagram-1-1024x681.jpeg" alt="" class="wp-image-320" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/NetDiagram-1-1024x681.jpeg 1024w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/NetDiagram-1-300x200.jpeg 300w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/NetDiagram-1-768x511.jpeg 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/NetDiagram-1-1536x1022.jpeg 1536w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/NetDiagram-1-2048x1362.jpeg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>From there, I added routing and firewall rules to expose only what we needed for testing. A key part of the lab design was enabling controlled team access to an attacker workstation without opening default high-noise ports to the internet. To achieve this, I configured port forwarding from my public IP to a dedicated attacker machine: a Minisforum UN150P running Kali on the IoT VLAN. External requests are mapped to RDP on port 6767 and SSH on port 6768, allowing remote access while avoiding standard ports like 3389 and 22. This approach keeps access practical for teammates while reducing basic opportunistic scanning risk.</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="768" height="1024" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/IMG20251210152539-768x1024.jpg" alt="" class="wp-image-354" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/IMG20251210152539-768x1024.jpg 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/IMG20251210152539-225x300.jpg 225w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/IMG20251210152539-1152x1536.jpg 1152w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/IMG20251210152539-1536x2048.jpg 1536w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/IMG20251210152539-scaled.jpg 1920w" sizes="(max-width: 768px) 100vw, 768px" /></figure>



<p>On the services side, I installed an MQTT broker on my home server and configured it for anonymous access so the honeypot and test devices could publish/subscribe without needing per-device credentials. This setup was intentional for education: it increases realism for “weak default” demonstrations and makes it easier to reproduce attacks and logging outcomes during testing.</p>



<p>To make the Kali box usable for the whole team, I installed a full desktop environment along with xrdp and OpenSSH so teammates could connect either through remote desktop or terminal. I also created separate user accounts for Jesse and Cynthia, which avoided password sharing and made activity more traceable during collaboration.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full is-style-rounded wp-duotone-unset-2"><img loading="lazy" decoding="async" width="401" height="600" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/cynth.jpg" alt="" class="wp-image-316" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/cynth.jpg 401w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/cynth-201x300.jpg 201w" sizes="(max-width: 401px) 100vw, 401px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h2 class="wp-block-heading">Recon and MQTT</h2>



<p>Cynthia led our recon and MQTT testing, validating that the honeypot was discoverable and behaved like a believable IoT target inside the segmented home lab. She used Nmap to identify MQTT-related exposure and confirm the messaging surface.</p>



<p>After discovery, she used curl to pull useful HTTP-visible details, including the connected broker, ClientID, and base topic structure; exactly the kind of information that makes MQTT hijacking and message injection easier.</p>



<p>For MQTT exploitation and validation, Cynthia used Mosquitto tooling to simulate message injection/broker-style interaction and confirm our logger captured the traffic as expected. She also incorporated RALMQTT as part of her MQTT pentesting toolkit, which we referenced alongside our broader MQTT testing sources.</p>



 [<a href="https://erikmakesthings.ddns.net/iot-honeypot-capstone-project/">See image gallery at erikmakesthings.ddns.net</a>] 



<p>To round out the risk story, she performed a SlowITe-style MQTT denial-of-service demonstration, showing how TCP-based IoT messaging can be disrupted through connection exhaustion even with minimal bandwidth.</p>



<figure class="wp-block-video"><video height="540" style="aspect-ratio: 1440 / 540;" width="1440" controls src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/My-Event-on-Wednesday-December-10-2025_edited.mp4"></video></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="683" height="1024" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/erik-1-683x1024.jpg" alt="" class="wp-image-347" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/erik-1-683x1024.jpg 683w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/erik-1-200x300.jpg 200w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/erik-1-768x1152.jpg 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/erik-1-1024x1536.jpg 1024w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/erik-1-1365x2048.jpg 1365w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/erik-1-scaled.jpg 1707w" sizes="(max-width: 683px) 100vw, 683px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h2 class="wp-block-heading">BLE Testing</h2>



<p style="border-top-left-radius:91px;border-top-right-radius:91px;border-bottom-left-radius:91px;border-bottom-right-radius:91px">I led the BLE testing to confirm the honeypot presents a believable Bluetooth target and reliably logs both passive probing and active interaction. I started by scanning for nearby devices using Bettercap’s ble.recon module, which gave me a quick snapshot of the BLE environment and helped me confirm <em>Honey-LightBLE</em> was advertising as expected based on name, RSSI, and vendor details.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="277" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/BettercapScan-1024x277.png" alt="" class="wp-image-366" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/BettercapScan-1024x277.png 1024w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/BettercapScan-300x81.png 300w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/BettercapScan-768x208.png 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/BettercapScan-1536x416.png 1536w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/BettercapScan.png 1721w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>After identifying the device, I connected and queried its GATT profile. The honeypot exposed standard services like Generic Access, Device Information, and Battery, plus a custom Nordic UART-style service. While exploring the GATT table, I confirmed that even simple reads generated visible events in my dashboard, which showed the system could capture low-noise reconnaissance.</p>



 [<a href="https://erikmakesthings.ddns.net/iot-honeypot-capstone-project/">See image gallery at erikmakesthings.ddns.net</a>] 



<p>To test active input, I used bluetoothctl to connect and write a short payload to a writable UART RX-style characteristic. The dashboard logged and decoded the write, validating the full chain from discovery, connection, GATT enumeration, write action, and finally event capture. This confirmed the honeypot can reliably record both read-style recon and write-based injection behavior.</p>



 [<a href="https://erikmakesthings.ddns.net/iot-honeypot-capstone-project/">See image gallery at erikmakesthings.ddns.net</a>] 
</div>
</div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="683" height="1024" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/jesse-1-683x1024.jpeg" alt="" class="wp-image-319" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/jesse-1-683x1024.jpeg 683w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/jesse-1-200x300.jpeg 200w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/jesse-1-768x1152.jpeg 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/jesse-1-1024x1536.jpeg 1024w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/jesse-1.jpeg 1365w" sizes="(max-width: 683px) 100vw, 683px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h2 class="wp-block-heading">Zigbee Testing</h2>



<p>Jesse led our Zigbee testing to validate that the Zigbee side of the honeypot functioned correctly and to establish what normal baseline traffic should look like in a small smart-home style environment. He noted that meaningful “attack-style” testing was harder to demonstrate in a clean way because Zigbee’s behavior is highly local and device-driven, so most of the effort focused on observation and recon rather than flashy exploitation.</p>



<p>During this phase, the Zigbee network was confirmed to be working and able to pair with Zigbee end devices, which helped verify the core functionality of the setup.</p>



<p>Jesse also documented a limitation we ran into: issues with the Zigbee logger prevented us from showing the depth of logs we originally intended. Even so, we were still able to capture and confirm devices attempting to connect to the system, which supported the overall purpose of the Zigbee-facing honeypot design.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="137" data-id="377" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-16-11-37-1024x137.png" alt="" class="wp-image-377" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-16-11-37-1024x137.png 1024w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-16-11-37-300x40.png 300w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-16-11-37-768x103.png 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/Screenshot-from-2025-12-10-16-11-37.png 1519w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</figure>
</div>
</div>



<h2 class="wp-block-heading">Download the code to try for yourself.</h2>



<div class="wp-block-file aligncenter"><a id="wp-block-file--media-ef60b6af-85e3-4042-b796-fa2f9a0a1541" href="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/FinalFirmware.7z">FinalFirmware</a><a href="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/FinalFirmware.7z" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-ef60b6af-85e3-4042-b796-fa2f9a0a1541">Download</a></div>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="498" height="437" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/LTT-SoCool.gif" alt="" class="wp-image-394"/></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://erikmakesthings.ddns.net/iot-honeypot-capstone-project/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		<enclosure url="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/3dPrinters-1.mp4" length="32441782" type="video/mp4" />
<enclosure url="https://erikmakesthings.ddns.net/wp-content/uploads/2025/12/My-Event-on-Wednesday-December-10-2025_edited.mp4" length="4558613" type="video/mp4" />

			</item>
		<item>
		<title>DiY Garden IoT</title>
		<link>https://erikmakesthings.ddns.net/diy-garden-iot/</link>
					<comments>https://erikmakesthings.ddns.net/diy-garden-iot/#respond</comments>
		
		<dc:creator><![CDATA[Erik]]></dc:creator>
		<pubDate>Sun, 01 Jun 2025 02:53:36 +0000</pubDate>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Micro Controller]]></category>
		<category><![CDATA[Server]]></category>
		<guid isPermaLink="false">https://erikmakesthings.ddns.net/?p=213</guid>

					<description><![CDATA[A garden is a grand teacher. It teaches patience and careful watchfulness; it teaches industry and thrift; above all, it teaches entire trust. &#8211;Gertrude Jekyll When I first took up gardening a few years ago, I figured it couldn’t be that hard. Just throw some seeds in the dirt, sprinkle a little water, and boom [&#8230;]]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>A garden is a grand teacher. It teaches patience and careful watchfulness; it teaches industry and thrift; above all, it teaches entire trust.</p>
</blockquote>



<p>&#8211;<em>Gertrude Jekyll</em></p>



<p>When I first took up gardening a few years ago, I figured it couldn’t be <em>that</em> hard. Just throw some seeds in the dirt, sprinkle a little water, and boom salad. Easy, right?</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="480" height="287" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/wrong.gif" alt="" class="wp-image-214" style="width:788px;height:auto"/></figure>



<p>It turns out that growing plants successfully requires more than casual optimism and a watering can. It takes patience, consistency, and  most importantly precision. Too much water? Dead plants. Too little? Also dead plants. As someone who works odd hours as a mainframe operator, I quickly learned that remembering to water my plants at the right time every day wasn’t exactly my strong suit. So I did what any tinkering nerd would do, I spend hours building something so I wouldn&#8217;t need to spend seconds doing something and automated it.</p>



<h2 class="wp-block-heading">Water PI v1</h2>



<p>The first version of my automated watering system was basic but surprisingly effective. I repurposed an old Raspberry Pi 2 B to control a 5V relay via the GPIO pins, which toggled a small fish tank pump at set times of the day. The pump sat at the bottom of a 5-gallon bucket and pushed water through a 3/8&#8243; tube. I had pinched the end of the tube shut and drilled holes along its length to create a DIY sprinkler. All of this was controlled by a Python program I wrote and setup as a service so it always ran. I could also SSH and send a command to get it to run for an extra cycle if it was a rather dry day.</p>



 [<a href="https://erikmakesthings.ddns.net/diy-garden-iot/">See image gallery at erikmakesthings.ddns.net</a>] 



<p>It wasn’t elegant, but it worked. My plants got watered, and I didn’t have to think about it. That is, until a summer storm rolled in and decided to conduct a field test, in destruction. Water Pi v1, with its exposed wires and hot-glued components, was utterly torn apart. The setup had served its purpose, but it was no match for wind, rain, and poor weatherproofing.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="480" height="266" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/sad-sal.gif" alt="" class="wp-image-216" style="width:748px;height:auto"/></figure>



<h2 class="wp-block-heading">Grow Lights</h2>



<p>Over the winter, I expanded the system indoors to start seedlings early. I picked up some budget-friendly grow lights from the local Home Depot and spliced in a Sonoff Zigbee relay to automate them through my Home Assistant setup. Now, the grow lights are part of my daily automation routines, turning on and off precisely when the seedlings need them, no more guessing or timers.</p>



 [<a href="https://erikmakesthings.ddns.net/diy-garden-iot/">See image gallery at erikmakesthings.ddns.net</a>] 



<h2 class="wp-block-heading">Water PI v2</h2>



<p>This year, I’m rebuilding the system from the ground up to be more scalable, energy-efficient, and portable. Enter <strong>Water Pi v2</strong> the next-generation watering node powered by a Raspberry Pi Pico 2W and a Waveshare power board, all mounted inside a 3D-printed (possibly weather-resistant) enclosure that I’m designing in FreeCAD.</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="498" height="373" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/upgrades-robots.gif" alt="" class="wp-image-215"/></figure>



<p>One of the main improvements is the addition of a motorized stirring mechanism. In my previous setup, stagnant water in the tank sometimes led to algae growth, which eventually caused blockage issues. This new version includes a dedicated motor to stir the tank periodically, helping keep the water clean and flowing consistently.</p>



<p>The watering function itself is now handled by a larger pump, again controlled via a relay module. The Pico 2W listens on a dedicated TCP port and receives instructions from a Python-based server program running on my home server. This server sends commands like <code>pump:2000</code> or <code>stir:1500</code> to toggle the corresponding relay for a specified duration (in milliseconds).</p>



<figure class="wp-block-video"><video height="1024" style="aspect-ratio: 576 / 1024;" width="576" controls src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/501697626_29724005740548137_3659334797605577503_n.mp4"></video></figure>



<p>To make the system more user-friendly and easier to diagnose, I’ve added a small I2C LCD to the node. It displays real-time status updates, such as the current system state and any received commands. Eventually, I plan to have the screen cycle through useful device information like IP address, battery level, and more — helpful for debugging and at-a-glance monitoring.</p>



<p>Power-wise, the system is designed to be solar-powered. I’m using a solar charging controller and a LiPo battery to allow the node to run independently. The pump, due to its higher power draw, is still powered by an external wall source. I also plan to design a custom bracket to mount the solar panels directly on top of the node&#8217;s housing for an all-in-one footprint.</p>



<p>The firmware for the Pico is written in C to give me finer hardware control and to sharpen my embedded systems skills. On the other hand, the server is written in Python, which should make it easier to get it integrate in to a nice and neat front end, or so I hope. Currently, the UI is a terminal-based menu, but I plan to expand it into a web interface. Long term, I’d like the server to manage a database to support multiple nodes, allowing for more scalable deployment and organization.</p>



 [<a href="https://erikmakesthings.ddns.net/diy-garden-iot/">See image gallery at erikmakesthings.ddns.net</a>] 
]]></content:encoded>
					
					<wfw:commentRss>https://erikmakesthings.ddns.net/diy-garden-iot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/501697626_29724005740548137_3659334797605577503_n.mp4" length="10693804" type="video/mp4" />

			</item>
		<item>
		<title>3D Printing and Finishing a Helmet</title>
		<link>https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/</link>
					<comments>https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/#respond</comments>
		
		<dc:creator><![CDATA[Erik]]></dc:creator>
		<pubDate>Sun, 25 May 2025 03:27:47 +0000</pubDate>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Micro Controller]]></category>
		<guid isPermaLink="false">https://erikmakesthings.ddns.net/?p=132</guid>

					<description><![CDATA[I&#8217;m just a simple man trying to make my way in the universe &#8211; Jango Fett I am a huge Star Wars nerd, like my father before me, and ever since I bought my Ender 3, I’ve been printing various Star Wars models and costume parts. After many failed and semi-successful projects, I finally set [&#8230;]]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>I&#8217;m just a simple man trying to make my way in the universe</p>
</blockquote>



<p>&#8211; Jango Fett</p>



<p>I am a huge Star Wars nerd, like my father before me, and ever since I bought my Ender 3, I’ve been printing various Star Wars models and costume parts. After many failed and semi-successful projects, I finally set out to make my father the helmet of one of his favorite, and most iconic, characters from a galaxy far, far away: RC-1207 Sev from the <em>Republic Commando</em> series.</p>



<h2 class="wp-block-heading">A Long Time Ago&#8230;</h2>



<p>For some backstory, my father is without a doubt one of the biggest Star Wars fans in the galaxy. Some of my earliest memories with him involve watching <em>The Empire Strikes Back</em> on VHS, playing the &#8217;90s <em>X-Wing vs. TIE Fighter</em> games, and building starfighters out of LEGO. As I grew up, he took us to every new movie, bought pretty much every Expanded Universe book, and played countless Star Wars tabletop and video games with us. For the longest time, he dreamed of building a Sev cosplay. I remember when he got in trouble with Mom for buying a helmet off eBay. He never finished the cosplay, life with five kids will do that, so my goal was to make him the helmet he always deserved.</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="879" height="1024" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Old-vs-New-1-879x1024.jpg" alt="" class="wp-image-151" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Old-vs-New-1-879x1024.jpg 879w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Old-vs-New-1-258x300.jpg 258w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Old-vs-New-1-768x895.jpg 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Old-vs-New-1-1318x1536.jpg 1318w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Old-vs-New-1-1758x2048.jpg 1758w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Old-vs-New-1.jpg 1848w" sizes="(max-width: 879px) 100vw, 879px" /><figcaption class="wp-element-caption">Old vs New</figcaption></figure>



<h2 class="wp-block-heading">The Journey Begins&#8230;</h2>



<p>To get this project started, I relied on my mostly stock Ender 3 printer. After a year of learning slicing programs, post-processing, and printer quirks, I felt ready to take on something bigger. Here are a few of the smaller projects I tackled to prep for this build:</p>



 [<a href="https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/">See image gallery at erikmakesthings.ddns.net</a>] 



<p>And of course a test fit was in order.</p>



<figure class="wp-block-video aligncenter"><video height="1440" style="aspect-ratio: 1440 / 1440;" width="1440" controls src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/test-fit-helm-1.mp4"></video></figure>



<h2 class="wp-block-heading">Finding the Model&#8230;</h2>



<p>First thing to do is to find the right model. If you&#8217;re good with 3D modeling or CAD, you can make your own. Otherwise, you can purchase models from amazing creators like aguilarworkshop.com, or search for free ones on sites like Thingiverse. I found the Republic Commando helmet model on Thingiverse, so huge shoutout to creators who share their hard work freely.</p>



<h2 class="wp-block-heading">Printing and Assembly&#8230;</h2>



<p>Then next step was to slice and print all of the pieces, sand them a little, and then put them all together. Since this print is in PLA I used just some simple Gorilla super glue to put them all together. Depending on the plastic you are using you will have different options to fuse everything, like Acetone when printing in ABS. Typically, what I found works best is to place a few drops in the face of the parts that would touch, and then either hand press or clamp the parts together for about five minutes. Then to further increase the the bond between the PLA parts, I would apply a few drops on both sides of the spot where the parts are connected and then spread it out with a brush. After repeating the exterior application a few times I would usually have a pretty strong bond! </p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
 [<a href="https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/">See image gallery at erikmakesthings.ddns.net</a>] 
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-video aligncenter"><video height="1920" style="aspect-ratio: 1072 / 1920;" width="1072" controls src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Helm-Printed.mp4"></video></figure>
</div>
</div>



<h2 class="wp-block-heading">Filling and Finishing&#8230;</h2>



<p>Then all you have to do is do a bit of sanding with some rough grit to get it ready for the next step. Before we move on though let me just point out that this project involved a lot of sanding. Just assume that in between every step I have sanded the helmet going from a rough to a more fine grit each time. If you are going to do this project at home, I would highly recommend some sort of handheld power sander. I did this by and and it was terrible and very time consuming! Also don&#8217;t forget to work in a well ventilated area with a respirator and safety glasses. Don&#8217;t want to get anymore micro plastics than you already have!</p>



<p></p>



 [<a href="https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/">See image gallery at erikmakesthings.ddns.net</a>] 



<p>Once you get everything sanded it&#8217;s time to start filling in the cracks so the surface will be smooth to the touch! From what I read and watched online most people either used watered down wood filler for it&#8217;s ability to fill gaps and sand easily, or Bondo for it&#8217;s ability to add getter structural support to the prints. So I opted to do both, because why not! I used Bondo I got from Mendards and applied it to the sides of the helmet where I had most of the larger parts of the helmet attached to each other. Then used the  watered down wood glue for for the smaller gaps and seams where things didn&#8217;t line up perfectly. After letting it dry, I did some more sanding. Finally, I coated the entire helmet with one layer of water downed wood filler and sanded until it was smooth.</p>



 [<a href="https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/">See image gallery at erikmakesthings.ddns.net</a>] 



<h2 class="wp-block-heading">Painting and Detail Work&#8230;</h2>



<p>With the bulk of the work behind me all I had left was to put down a few layers of primer while filling any extra seems with wood filler. Then I laid down the white base that the clones are known for. After the two or three base coats I when in with a brush to paint the accents with black acrylic paint. For the visor I used a plastic face visor off of <a href="https://www.amazon.com/Feekoon-Replacement-Compatible-Protective-Grinding/dp/B0CT3RMTD4/ref=sr_1_4?sr=8-4">Amazon</a>, and cut it down to fit. After using a heat gun to shape the visor to the helmet I secured it in place using some hot glue. For the mouth grill I bought some wire mesh from a hobby store and cut it to fit before securing it with super glue.</p>



 [<a href="https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/">See image gallery at erikmakesthings.ddns.net</a>] 



<p>The final part of this model is to add the striking livery to the helmet. Since the character has made few appearances since his debut in the 2005 game <em>Republic Command</em>, I had to take some creative liberties to bring the fear inducing bloodied paint scheme to life. After masking the accent lines and parts I used some watered down crimson acrylic paint and my hand to imprint the signature look across the faceplate. Then I used a sponge applicator to apply additional blood splatter and streaks.</p>



 [<a href="https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/">See image gallery at erikmakesthings.ddns.net</a>] 



<h2 class="wp-block-heading">Finishing Touches&#8230;</h2>



<p>With the helmet complete, I decided to add some flair. Using a Raspberry Pi Pico and MicroPython, I wired up LEDs behind the visor to simulate the in-game glow. I also found original voice lines and sound effects from the game and used small speakers inside the helmet to play them. The entire system is powered by a USB power bank and securely tucked away. Final touches included padding, wire routing, and mini exhaust fans for comfort. Once everything was in place, I drove the helmet to my dad and handed it to him in person.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-video"><video height="656" style="aspect-ratio: 368 / 656;" width="368" controls src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/like-95-done-1.mp4"></video></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
 [<a href="https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/">See image gallery at erikmakesthings.ddns.net</a>] 
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-video"><video height="1920" style="aspect-ratio: 1072 / 1920;" width="1072" controls src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Helm-Boot-1.mp4"></video></figure>
</div>
</div>



<p>Watching my dad don the finished helmet with glowing lights and Sev&#8217;s iconic crimson streaks was worth every failed print, every grain of sandpaper, and every drop of glue. This wasn’t just a cosplay prop. It was a tribute to the man who introduced me to Star Wars, and to the galaxy we still explore together.</p>



<p>This one was for you, Dad. For the Republic!</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="473" height="1024" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/20240630_131035-473x1024.jpg" alt="" class="wp-image-204" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/20240630_131035-473x1024.jpg 473w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/20240630_131035-139x300.jpg 139w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/20240630_131035-768x1662.jpg 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/20240630_131035-710x1536.jpg 710w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/20240630_131035-946x2048.jpg 946w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/20240630_131035-scaled.jpg 1183w" sizes="(max-width: 473px) 100vw, 473px" /></figure>



<h2 class="wp-block-heading">MicroPython for helmet.</h2>



<pre class="wp-block-code"><code>#libs
import time
import board
import random
import digitalio
from audiocore import WaveFile
from audiopwmio import PWMAudioOut as AudioOut

#Speakers
audio = AudioOut(board.GP16)

#dir var
path = "sounds/"

#LEDs
led = digitalio.DigitalInOut(board.GP5)
led.direction = digitalio.Direction.OUTPUT
led1 = digitalio.DigitalInOut(board.GP6)
led1.direction = digitalio.Direction.OUTPUT
led2 = digitalio.DigitalInOut(board.GP7)
led2.direction = digitalio.Direction.OUTPUT
led3 = digitalio.DigitalInOut(board.GP8)
led3.direction = digitalio.Direction.OUTPUT
led4 = digitalio.DigitalInOut(board.GP9)
led4.direction = digitalio.Direction.OUTPUT

#function to open/read .wav file
def play_sound(filename):
    with open(path + filename, "rb") as wave_file:
        wave = WaveFile(wave_file)
        audio.play(wave)
        while audio.playing:
            pass
        
#from input play selected file        
def sfx(n):
    if n == 0:
        play_sound("62_anger.wav")
    elif n == 1:
        play_sound("rad_02.wav")
    elif n == 2:
        play_sound("rad_03.wav")
    elif n == 3:
        play_sound("62_droids.wav")
    elif n == 4:
        play_sound("40_win.wav")
    elif n == 5:
        led4.value = False
        led3.value = False
        time.sleep(1)
        led2.value = False
        led1.value = False
        time.sleep(1)
        led.value = False
        
        time.sleep(2)
        
        led.value = True
        play_sound("chirp.wav")
        play_sound("chirp.wav")
        led1.value = True
        led2.value = True
        play_sound("chirp.wav")
        led3.value = True
        led4.value = True
        play_sound("chirp.wav")
    elif n == 6:
        play_sound("delta.wav")
    elif n == 7:
        play_sound("62_rgr.wav")
        time.sleep(1)
        play_sound("07_lol.wav")
    elif n == 8:
        play_sound("62_bad.wav")
    

#initial boot sequence
play_sound("chirp.wav")
led.value = True
play_sound("chirp.wav")
play_sound("chirp.wav")
led1.value = True
led2.value = True
play_sound("chirp.wav")
led3.value = True
led4.value = True
play_sound("chirp.wav")
play_sound("boot.wav")
play_sound("heal.wav")

time.sleep(30)

#initial sound play
n = random.randint(0,8)
sfx(n)
m = n

#main loop
while True:
    n = random.randint(0,8)
    
    if m == n:
        n = random.randint(0,8)
        sfx(n)
    else:
        sfx(n)
    
    m = n
    
    time.sleep(300)</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://erikmakesthings.ddns.net/3d-printing-and-finishing-a-helmet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Helm-Printed.mp4" length="8804734" type="video/mp4" />
<enclosure url="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Helm-Boot-1.mp4" length="5525130" type="video/mp4" />
<enclosure url="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/test-fit-helm-1.mp4" length="16203264" type="video/mp4" />
<enclosure url="https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/like-95-done-1.mp4" length="257793" type="video/mp4" />

			</item>
	</channel>
</rss>
