Sunday, November 24, 2024

How to Build a Fort (Again!)

 In 2019 we moved to a new home and had to leave our old fort behind. There was nothing to do but start again! We got more ambitious this time around. 


We picked a location far enough from the main house to feel adventurous, but close enough that we could easily see the fort from the house and house from the fort. 

Fort Location

I did the initial design in SketchUp. With some help from my dad, I decided to use four 6"x6" posts as the main supports (upgrading from the 4"x4"s used in the previous fort). 

Fort Scale

Since we live in Minnesota, we had to dig down 4' for each of the four posts to avoid heaving risk in winter. 

Posts Poured

With help from the neighbors we set up the posts and braced them into position. 

I don't own a construction helmet, so I used a bike helmet

We notched out the posts to mount two 2"x8" ledger boards. 


We lag bolted the ledger boards to the posts, then hung 2"x6" joists between them. We used ledger strips, rather than joist hangers, to save money (the size difference between the ledger board and joists allow this approach). 



We put down plywood decking and decorated it.



We installed a temporary roof to keep rain from spoiling the plywood decking. 

Adding a temporary roof. Also shown, rails to keep people from falling out


 We used the fort as-is for quite a while, since it made a great place to see the yard and the kids enjoyed playing in it. 

The gully flowing, as seen from the fort

Eventually (a couple of years later!) we decided it was finally time to add some walls. My dad and I stick-built the walls from 2"x4"s and the kids helped with sheathing. 

Nailing on sheathing



Fort with sheathing and a hole cut for a window

We used house wrap left over from siding our main home, and some friends gave us a couple of old windows. 



My dad did the trim and siding on the front.


It was time to replace the temporary (now years old) roof with a real roof. We still plan to add a rooftop patio, so the real roof had to be a little shorter than the top of the 6"x6" posts. 



I managed to finish shingling the new roof just before winter in 2022. 



My dad built a beautiful custom front door.

Cedar siding and custom front door

I designed and build a custom electronic lock for the door.

Components of the custom lock

Which required a bit of welding to make a custom mounting bracket for the magnetic lock. 

Magnetic lock mounted with welded steel bracket

My dad and I have nearly finished the siding (different on every side, because we're reusing old material) 

Different siding on each side

I added some interior and exterior lights


Now we're working on the interior. Stay tuned!




Sunday, January 14, 2024

Thermostat Monitor System

 Summary

I was having trouble keeping track of which of my house's three heating zones was activating the boiler and pump at any given time. So I built a device to monitor which zone was calling for heat. 

Zone activation sensor system, with indicator lights

I used Prometheus to keep track of zone activation over time. 


Two days of zone activation lots via Prometheus. The temperature dropped over the last 8 hours, so you can see the upper floor is constantly active.

Build Process

My house has a hot-water heating system with three zones, each controlled by a valve like this one


Zone controller, photo via Amazon.com

There are three zones, each managed with one of these zone valves. Each zone valve is controlled by a thermostat.

Boiler and control valves 

These control values take a 24 Volt Alternating Current (VAC) input. When a thermostat calls for heat, it does so by sending 24 VAC to its control valve. The control valve opens the physical valve and sends 24 VAC to the boiler.


Diagram of power flow through the boiler system. The thermostat is effectively a switch that, when activated, closes the connection between the 24VAC transformer and the zone control valve.

The boiler system uses a transformer to convert the standard 120 VAC wall power to the 24 VAC used for the heating system. 

Each thermostat has its own settings for when to call for heat. The basic function of a thermostat is to track a set point (e.g., 68 degrees) and a current temperature (e..g, 70 degrees). If the current temperature is below the set point (in the case of a heating thermostat, e.g., 65 degrees) the thermostat will close the circuit from the transformer to the control valve. The control valve will open the pipe for hot water to the associated region of the house and will also close a circuit to provide 24 VAC to the boiler. This, in turn, causes the boiler to heat up and the water pump to turn on. 

Side note: newer thermostats like a Google Nest Thermostat require a "C-Wire." The C-Wire or "Common-Wire" is a neutral wire that allows the thermostat to use the 24 VAC supplied by the transformer. Without a C-Wire, the thermostat is just like a switch. 

Approach

I wanted to monitor which thermostat was calling for heat at what time and for how long. I also did not want to modify the heating system (I definitely don't want to break out boiler in the dead of winter!) To do this, I took advantage of a handy property of alternating current: you can indirectly measure it. Alternating current creates a magnetic field, which you can measure without directly touching the wires carrying that current. 

I purchased some of these clamp sensors (you can find them on eBay), which can measure alternating current on a wire when clamped around it. 

Clamp current sensor photo via eBay

I connected these to an Adafruit Metro ESP-32 S2, and used its analog ports to measure the voltage reported by each clamp sensor. 


Adafruit Metro ESP32-S2 via Adafruit


I found a prometheus exporter for CircuitPython on github. I had to make one modification to make it work with my board (my fork on GitHub).

I wrote a CircuitPython program to read the analog signals from the clamp sensors, then make that reading available to my prometheus server via a simple HTTP endpoint. Setting up CircuitPython took a bit of work, let me know in a comment if you would like a blog post about that process. 

The endpoint looks like this when viewed with a web browser:

Statistics reported by the thermostat monitor system

I configured my Prometheus server to scrape the thermostat statistics every 15 seconds. To generate a graph of when thermostats are active, I can use a query like:

environment_thermostat_upper_heat{job="thermostat"}

A query and associated results viewed in the Prometheus graph viewer

In this case we can see that the upper floor heat was active almost continuously over the past ten hours. This is not surprising, since an arctic vortex just arrived. 

Conclusion

CircuitPython is really handy for making Internet of Things (IoT) devices that work with an aggregator like Prometheus. 




Sunday, November 19, 2023

Analog to Digital Adapter for Alesis Turbo Mesh Kick Drum


Earlier this year we bought an Alesis Turbo Mesh electric drum kit. The kit works well, but my drum teacher advised me to switch from the spring/trigger kick pedal to a proper kick drum pedal. I ordered a kick pedal and sensor from eBay, but was bummed to discover that the Turbo Mesh kit only works with a "switch" style kick pedal

Fig 1: The Goal (Images via Alesis.com)

The Alesis Turbo Mesh kick pedal connects using a standard 1/4" mono jack. When the pedal is depressed, the two conductors in the mono jack are connected and the control module recognizes it as a "kick." You can easily demonstrate this by touching both parts of the kick drum 1/4" connector with a wire. 

The higher quality kick sensors are analog, meaning instead of a binary on/off (like a switch) they change the voltage on a signal wire, which is interpreted by a microcontroller. This is how electric drum kits get different volume levels for different intensity strikes. In this case, I needed to convert the analog signal from the kick pedal to a binary on/off before the signal reached the Alesis drum controller. 

Fig 2: Connections (Images via Alesis.com and Sparkfun.com)

I bought an Arduino Redboard from Sparkfun for about $20. The Redboard has analog and digital I/O pins, making it an easy choice for this project. I also had some relays left over from the Fort Lock project. I bought a couple of 1/4" jacks. 

Part List

Digital Resources

Process

Redboard Setup

The Arduino IDE didn’t work out of the box with the Redboard, which requires an additional support package. 

I had to add this line to the Arduino IDE preferences to add additional boards to support. 

https://raw.githubusercontent.com/sparkfun/Arduino_Apollo3/main/package_sparkfun_apollo3_index.json

After updating the preferences, I was able to select the Redboard and connect!

Reading Analog Values

I connected the kick drum sensor to an analog pin on the Redboard and used the example serial reader code to read the voltage levels from the kick sensor.

Fig 3: Serial reader sample code from Sparkfun

Using the built-in LED I was able to reliably detect "kicks" using the analog sensor and looking for sudden increases in voltage. The Arduino software does not provide time guarantees, but the main loop ran fast enough that any latencies were not noticeable. 

Writing Digital Values

To trigger the "kick" I needed to "connect" the two conductors from the Alesis control unit's kick cable. There were a couple of options available to accomplish this. Using a multimeter, I found that the Voltage difference between the two kick sensor conductors was 3 Volts. 

To make the signal consistent, I had to create a common ground connection between the drum control unit and my Redboard. I connected a solid wire from the Redboard to part of the breakout connector on the bottom of the drum control unit. 

Fig 4: Connection point to establish common ground


I tried sending 3V directly using the Redboard's digital output pins, but the latency was too high (it sounded like about 300-500 milliseconds). My suspicion is that the Redboard could not supply the voltage quickly enough the internal resistance in the drum control unit. 

To overcome this issue, I used a relay that acted like a switch to close the connection between the two signal lines in the kick drum cable. I can't find the exact product I used (it was from eBay) but it was similar to this (Amazon). I understand from talking with friends that an OpAmp could have achieved the same thing, but I have not learned how to use those yet. 

I designed a simple case in FreeCAD and printed it. 

Fig 5: 3D Model of Enclosure



Fig 6: Wiring Diagram



Saturday, July 8, 2023

Build Log: Keycode Access Control for the Fort

 My sons requested a keycode-based access control system for their backyard fort. I'm pretty happy with what we created. In this blog post I'll talk through the details of what we built and why. 

The keypad and custom mounting bracket

Parts List

Microcontroller

  • Adafruit Metro ESP32-S2
  • The Adafruit Metro ESP32-S2 is a fairly inexpensive ($20) controller that includes wifi and Adafruit's Qwiic I2C connector system. 

Keypad

Electronic Lock



Relay



  • Fuses (PTC Fuse Resettable Fuses 72V 0.5A 500mA RXEF030 Series)
  • Diodes
  • Qwiic Button

Architecture

Requirements

I worked with my friend Peter to develop requirements for the lock. The requirements are written up on github here. In summary, the lock: 
  1. shall not allow a child to get stuck
  2. shall be resistant to critters/teenagers
  3. shall not require physical keys
The current solution meets all three of these requirements. 

Cyberphysical System Models

This project gave me a good excuse to spend time learning the Assume Guarantee REasoning Environment (AGREE). AGREE is a model-based tool that helps you build and verify an argument for correctness in your architecture. 


This specification, written in the Architecture Analysis and Design Language (AADL) describes a magnetic lock actuator that physically actuates (locks) only when power is applied to the system and the lock gets an actuation signal. The first section, "lock_actuator" describes the desired behavior in terms of assumptions and guarantees. The section section, "lock_actuator.magnetic_actuator" describes the state transitions of a particular lock design. 

This type of reasoning is helpful when thinking through design choices. For example, I considered using a solenoid lock like this version from SparkFun: 


But this kind of lock does not meet the conditions described in my assumptions and guarantees. Namely, (as I verified through bench testing) the SparkFun solenoid lock physically actuates (locks) when power is not applied. Such behavior would violate the requirement, "shall not allow a child to get stuck," because a power loss could cause a child to become stuck in the fort.   

Electrical Architecture

Architecture Figure 1: Electrical System

Electrical Summary

A MOSFET relay with a dedicated 12VDC source controls power to the electronic lock. At Peter's recommendation, both sides of the 12VDC supply are protected with resettable fuses to avoid shorting the system (if, for example, something is wired backward). 

The ESP32 board uses one of its General Purpose Input/Output (GPIO) pins to trigger the relay. Input to the ESP32 comes from two sensors (a button and a keypad) both of which are connected via the I2C protocol using Sparkfun's Qwiic cable system (which I absolutely love). 

Flyback Diode

When the magnetic field of the electromagnetic lock collapses, it can induce a current in the reverse of the normal direction. To avoid damaging the microcontroller, I used a Flyback Diode as described on this page. Normally current flows in the B to A direction (illustrated on the figure), but when the lock's power is disengaged, the collapsing magnetic field induces a current in the A to B direction, making a circuit back through the electronic lock to dissipate the remaining power. 

Physical Assembly

The lock I purchased was intended to by mounted on the interior of a door frame. The fort door is an exterior door, so this mounting approach would not work (the lock would be exposed to weather). To mount the lock entirely inside the fort, I welded a "Z" bracket from two pieces of "L" steel. 

Architecture Figure 2: Installation. After taking this photo I had to shim the steel plate (attached to the black painted steel) so that it made good contact with the magnet.


I installed the microcontroller, relay, and exit button in a standard 2 gang electrical box. 

Architecture Figure 3: Exit button and installation box


My son and I designed the keypad mounting bracket in TinkerCAD (this was great practice for him using a micrometer). You can find the .stl file here

Architecture Figure 4: Mounting Bracket for SparkFun QwiicKeypad


Software Architecture

Architecture Figure 5: Software

The software design is pretty simple. As shown in Architecture Figure 5, the microcontroller simply waits for input from either the keypad or the exit button, storing up keypresses to compare to a saved code, resetting if input times out. 

Development Environment

This was my first time using CircuitPython and the Mu Python editor. Overall I'm still on the fence about CircuitPython. It is certainly convenient once it is working, but the set up process is not as straightforward as I'm accustomed to with Arduino. 

1. Install CircuitPython to Board Flash Memory

  • Download esptool (I used version 4.4)
  • Find ESP32 in my device manager (on Windows this was COM8)
  • Write circuitpython bootloader to flash
    • .\esptool-v4.4-win64\esptool-v4.4-win64\esptool.exe --port COM8 --after=no_reset write_flash 0x0 .\tinyuf2-adafruit_metro_esp32s2-0.12.0\combined.bin
Once CircuitPython is loaded on your board's flash memory, the board will appear as a storage device.

2. Install Mu Editor

You can download Mu here. Overall I'm content with Mu, but the CircuitPython model seems to require I only use a single file, "code.py" which makes version control cumbersome.

3. Install Required Libraries

CircuitPython libraries are not the same as regular Python libraries. You can find many CircuitPython libraries here. Copy the files for the devices you are using from the lib directory of the CIrcuitPython library to the lib directory on your board. For example, I copied sparkfun_qwiickeypad.mpy to the lib directory of my board so that I could do:

import board
import sparkfun_qwiickeypad
...
i2c = board.I2C()
keypad = sparkfun_qwiickeypad.Sparkfun_QwiicKeypad(i2c)

Testing

Access Testing

My kids helped me test the lock - both the entry PIN and the exit button work as desired. We also talked through the emergency protocol if they need to leave the fort and the exit button is not working (just unplug it). 

Power Consumption

I used a KASA wifi power outlet adapter to measure power consumption. It holds steady at about 9 Watts for the lock alone (not including the controller). 

Final Thoughts

I learned a ton doing this project. The practice doing circuit design was particularly valuable, as I made (and corrected) lots of mistakes.