All posts by ehammers

DEF CON 29 Mask

DEF CON 29 happened in Las Vegas, NV from August 5 to August 8, 2021. DC28 was entirely virtual. This year, the conference operated in a hybrid model, and in-person attendees were required to demonstrate proof of vaccination and to mask whenever in conference spaces. This strategy was enormously successful, and DC29 did not function as a COVID super-spreader event. I attended, and because I was going to mask the entire time, I decided to lean into it.

Photo by Andrea Peterson. Source: Fear and Covid in Las Vegas: Pen testing Hacker Summer Camp’s mask policies

I started with a 3M 6503QL “Rugged Comfort” respirator, a pair of 3M 6001 filter cartridges, 501 translucent filter retainers, and P95 filters. This respirator is pretty comfortable, supported by a head strap and pulled snug by a neck strap. It has a quick-release mechanism that removes tension on the head strap and lets it hang loosely below my face. Most importantly, those filter cartridges provide plenty of room for components.

How it started

I wanted this mask to do something, and just covering it in der blinkenlights was not enough. I thought about making it wifi reactive (visualizing observed deauths, for example), or offering an open web service that people nearby could use to modify the behavior of the lights. In the end, I decided that it would be really cool if it could visualize its core function by changing the color of the lights as I breathe in and out.

Adafruit BME680 atmospheric sensor breakout. I only use the atmospheric pressure.

To detect breathing, I used the atmospheric pressure sensor from a Bosch BME680 atmospheric sensor (in an Adafruit breakout board). I needed this mask to be an actual safety device suitable for protecting myself and those around me, so I removed all of the valves and plugged the unfiltered output hole (after several attempts, I went with carved pencil eraser). This created enough of a pressure differential inside the masklow pressure when I breathe in, high pressure when I breathe out—that I could detect it with the sensor and use it to inform the behavior of the lights. Here’s an early test of the concept: the lights turn green when the pressure drops below a threshold and red when the pressure rises above a threshold.

To start, I hollowed out the filter cartridges. Each cartridge has a hole on one side where it links up with the mask, a thin filter layer, densely packed charcoal, another filter layer, and then a thick plastic mesh. On top of this would go one more P95 filter and a translucent retainer. I clipped away a big piece of the plastic mesh and emptied the charcoal. I also wound up cutting away some supporting structure inside the cartridge and in the hole that passes through to the mask. This gave me space to fit the components with enough room left for me to breathe.

In the end, I had to cut away much more of the internal plastic.

For maximum bling, I wrapped the perimeter of each cartridge in Neopixel LED strips and put two nested Neopixel rings behind each outer P95 filter. I had originally planned to use a Dotstar strip for the perimeter lights, but when I couldn’t find the rings in Dotstar lights, I decided the whole thing may as well be Neopixels. One fewer library, and I could control it all from one pin. Unfortunately, I forgot that I had ordered RGBW lights for the rings, and I had already glued RGB strips around the cartridges and wired all of the lights in series: Arduino → rings on its side → strip on its side → across my nose → rings on that side → strip on that side. 3-byte-per-pixel and 4-byte-per-pixel strips are not interoperable, and I had to rewire the lights so that the rings were all in series on one pin and the strips were in series on another pin. Still just one library, but two strip objects to manage. Wiring between the cartridges was not a problem, as I had already plumbed the crossover connectivity with one extra wire just in case.

Trying to use RGB and RGBW lights in the same strip gives weird results.

Lots of lights means lots of power, so I decided to power the mask with two 18650 lithium cells (eventually pared down to one). Please note: improper physical or electrical handling of these cells can render them literally explosive. I do not recommend that you wear one on your face, and if I ever modify this project, the first thing I will do will be to change the power system.

Notice the giant lithium cell at the top of the right filter cartridge.

I knew it would be hard for people to hear and understand me while wearing this thing, so I designed in an audio system. I combined a little electret microphone breakout with a tiny 2.5W audio amplifier. I ordered two pairs of little speakers, one pair of flat, tinny speakers and one pair of heavier loudspeakers. I decided I could only really fit the thin ones (this was incorrect), but they sounded terrible, and I scrapped the feature.

Having the Arduino MKR1000 Wifi on this bit of perf board made connecting to it easy, but the whole setup was too bulky. I should have gone with a Pro Mini.

I originally intended for this project to use a pair of 18650s, one in each filter cartridge, with the microcontroller (an Arduino MKR1000 Wifi) on one side and a power distribution board on the other. I didn’t think I had enough space on the Arduino’s side for the cell (I did), so I wound up with a single cell powering the Arduino and all of the lights. This worked well, and I never ran out of battery, even with hours of use.

I ground off the logo, roughed up the plastic, and gave it a little copper rub-n-buff for that beat up metal look.

I had a bunch of these neat little rotary encoders, so I drilled a hole right in the front of the mask and stuck a knob on it. The knob also works as a clicky switch, so I could use code to detect left turns, right turns, clicks, and long presses.

Kit shot with encoder, knob and hardware
I ruined one of these by making the nut too tight. I carved out a bit of plastic inside the mask to seat one of the mechanical side tabs and left the nut just snug.

This device uses quadrature encoding to let you determine both speed and direction of the knob using only 2 pins + ground. As you turn it, two switches connected to the two pins fire out of phase with each other. If you see switch A fire, then both of them, then switch B, then none again, that’s one entire 4-phase cycle in one direction. If B fires first, then both, then A, then none, that’s one cycle in the other direction. Of course, because the switches are mechanical and the Arduino is not infallible, you need to account for errors: you might see the same state change more than once, and you might miss some state changes altogether. I put together a few implementations and tested out several libraries, and I ended up with an interrupt-driven model using a library called QDEC.

I didn’t want the lights to simply be green or be red as I was breathing in and out; I wanted them to have their own behaviors that were influenced by the breathing. I threw together a simple system for applying sin, cos and tan to red, green and blue with a flexible set of time and brightness parameters. Then I used the difference between measured pressure and a moving baseline to apply a multiplier to the red or green brightness. The end result was that the lights twinkled blue when air pressure was nominal and tended red or green when the pressure was newly different.

The mask’s first outing at the Chandelier bar in the Paris hotel

After wearing this for the first time at DEF CON, it was clear that no one could hear me at all and that even a poorly functioning audio system would be better than none. I had brought the parts for the audio system with me, and I added them back to the mask. I went with a single larger speaker over the two tiny ones, which I think helped a little with clarity. I hit a new snag, however, when I tried to test the system: the lights wreaked havoc with the audio! The PWM mechanism the Neopixels use to maintain their intensities modulated the supply voltage to the amplifier, which brought that modulation directly into the audio output. It was almost musical. To fix it, I managed to jam the second 18650 into the Arduino side of the mask just to run the audio system. I gated this with a little toggle switch, jammed that into a piece of foam, and used that piece of foam to replace the pencil eraser that was stopping up my breathe-out hole. Now I had a switchable speaking system! While this did sometimes mean the difference between being heard and not being heard, I still wound up lowering the mask when I really needed to be understood.

Mask with voice switch installed.

After wearing this mask for a few hours the next day (linecon, a brief visit to the swag line, roaming around the villages), I figured out the next few changes I needed to make. One, it was DRIPPING wet inside, so I had to double mask for the rest of the conference. This was fine, as I often needed to drop the mask down in order to communicate.

Gross

Second, I wanted to go to an LGBTQA+ social event that afternoon, and I thought a rainbow motif would be appropriate. I stole the rainbow code from another LED project (similar to the light boxes I built for the boys, which was itself adapted from Adafruit’s strandtest example). I added it to my too-complicated control scheme, and it worked great.

The last change was harder: the mask was HEAVY and left a deep red mark on my nose. I needed to cut weight.

Ouch

I popped it open and looked for stuff I could rip out. One obvious way to make it lighter was to reduce my use of plugs and connectors with excess wire and to instead cut the lines to size and solder them together. This cost me my ability to take the mask apart, but it worked. I also pulled the 18650 running the audio system and replaced it with a much smaller 3.7v cell. I so infrequently had the audio switched on, this worked out just fine and saved a bunch of weight. I had no significant comfort issues with the mask for the remainder of the conference.

Before
After

Like always, I built way more flexibility (and therefore complexity) into the UI for this project than I actually needed. I built the control system around the one clicky knob. The knob had a set of modes, and clicking the knob switched it from operating in a mode to selecting a new mode. I stuck a piezo buzzer in there to emit some quick little beeps, letting me know when I was in “pick a new knob behavior” mode and to let me know which mode I was selecting. But it turned out that I couldn’t hear the piezo outside of my quiet room, so changing any setting became a drawn out sequence of click, spin, click, spin, click, spin until the knob was in the right mode and I then got the behavior change I wanted. It was just silly. On the first full day of DEF CON, in the afternoon, I had some downtime, and I didn’t want to hole up in my room. I made my way to one of the “chill out” rooms and sat down to code a new UI for the mask. I think I spent about 10 minutes coding and 90 minutes chatting with the nice people who joined me at the table or stopped to ask about the mask. I simplified the system dramatically: clicking the knob turns the knob on and off (when it’s off, spinning it does nothing), and spinning the knob when it’s on changes between light behaviors (breathing, rainbow, or off).

After the second full day of the conference, I was ready to go to the MC Ohm-I show (awesome DJs to follow), and I thought it would be super cool if I could make my lights react to sound. I was a little short on time, so I quickly wired the mic board output and the amplifier disable pin to the Arduino. I got the system buttoned up and headed down to Drunk Hacker History, where I sat in the back and worked on the audio reactive code. I whipped up the algorithm, flashed the Arduino, and nothing. No sound reaction in the lights. After some debugging, I found that the audio from the mic board wasn’t being read by the Arduino… because I gave them different power systems and they therefore did not share ground. Nuts. I was not about to hike all the way back to my room and miss the show.

Image
https://twitter.com/mcohmi/status/1424252494763466754

So I went to the show with no sound reactive lights, and the show was fun. I hadn’t seen MC Ohm-I or Kadesh Flow before and they were great, but I was still bummed that my quick hack had fallen flat. Enter: the DEF CON chill out room centerpieces. While I would never steal anything from them or purposefully destroy an art piece, I didn’t think it would do much harm to borrow a little of this wire. I had my leatherman on me, so I just clipped about 4″ of wire out, stripped the ends, popped my mask open and did something terrible. It worked.

Mask and the centerpiece that donated a ground wire.
The audience cam got a shot of me hacking on my mask during the show.

A lot of connectivity happened inside the part of the mask where my face also was. I didn’t have a main power switch, so I ran the battery connection out of the cartridge and into the facemask, letting me plug and unplug the battery without popping off the filter cover. This was also how I accessed the battery for charging. The audio power could stay connected when not charging because I had a chin mounted power switch for that. Also sharing space with my nose and mouth were a crossover cable (carried power right to left, LED signaling left to right), the speaker cable, the pressure sensor, the cable connecting the knob, the microphone, and the two extra wires I added to let the Arduino hear the microphone and disable the amp. Because I double masked when wearing this, I wasn’t bothered by it at all.

Here’s a look at the distribution board in the right filter cartridge. I had originally built this to hold two 18650s in parallel, but the project didn’t work out that way. It was really useful to have the extra space on this board when I needed to rework the LED wiring (one strip to two) and when I wanted to plumb power to the reinstalled audio hardware (which I later ripped out because of the PWM noise). In retrospect, I should have looked at this side for zip tied dead weight to cut. I could have lost the last half inch or so of the PCB, too.

Behold the chaos of my hotel room workbench. It got even messier than this. I was really proud of how selective and correct I was about what parts and tools to bring and what to leave behind (I did bring two oscilloscopes, but they are both very small). The white cable management hose (which is full of LEDs) and the LED disc beneath it both go on my backpack. The disc has an on-board Raspberry Pi and is controlled by the same software that runs the Hawks sign. The hose has a goofy little Pro Mini-based control box with a lovely 10-way switch for behavior selection.

That cloth mask is me.
LED hose and disc installed on backpack. I have that disc at almost minimum brightness.
The resistors soldered between each position of the rotary switch mean that I can read it with just one analog pin. This project is why I added analog support to the Debouncinator.
The Arduino Pro Mini has a special place in my heart. I brought one with me just in case I decided to ditch the bulk of the MKR1000.

Post conference, I have been cleaning up the code. There were some bits that I put in a framework for and never built, and I removed most of them. One of them, I decided to complete instead: brightness adjustment. In the course of disassembling the mask for photography and also modifying and testing the software, I managed to break the mask completely. No lights, no controls, nothing. I poked at it for a couple of very disappointing days before I buckled down and got systematic. In the end, the hardware problems amounted to 3 broken solder joints. On the software side, the Arduino IDE picked up a test file that I had created in the project’s directory, and this was interfering with the correct operation of the real code. I fixed the joints, flashed the Arduino, and it’s back to full functionality.

Back to full bling capacity.

As long as I had it on the bench, I decided to pull the speaker and the amp, remove the audio power system and just run the mic off the main power. This let me also pull the chin switch and get my nice chunk of carved pencil eraser back in there. So the mask no longer makes noises, but it can still react to them, and it has only one cell to charge. Time to find a nice spot for this to live, clean off the bench, and figure out what’s next.

As usual, the code is on github.

That’ll do, mask. That’ll do.

Dog Food Timer

My newest project, and also one of my oldest, is the dog food timer. My wife and I sometimes wind up with disconnected morning or evening schedules, and this could sometimes result in the dog missing a feeding or being fed twice. There are many ways to solve this problem, but of course I chose to build an electronic one.

I first built this timer in late 2012. The first iteration used wire taped to aluminum foil to sense when the lid of the food container was opened and closed. This was read by an Arduino, which would show how long it had been since the last several times that the container was opened on a multi-line text display. I never got a photo of the text display, but this is what that foil switch setup looked like.

The giant text display had an RGB backlight, which I configured to show green/yellow/red depending on how long it had been since the dog had last been fed, and it quickly became clear that this was all we actually needed. In a knee-jerk reaction to the cost and complexity of my first overengineered solution, I took a swing at doing the whole thing with 3 LEDs and a few discrete chips (and maybe just a couple of 555 timers). Totally doable, but I wanted a little more functionality. In the end, I settled on an Arduino Pro Mini (my favorite for many years), an accelerometer left over from the robot costume project, two pushbuttons, and three LEDs. This has been in production with every dog we’ve had (two) from 2012 until this week.

The build for this project is janky as heck. The bare wires of the LEDs are loosely insulated with electrical tape, one of the buttons sticks out through a crudely dremmeled opening, both buttons are pressed toward the outside of the case by a random piece of foam… it’s just a mess. I’ve been wanting to redo it for a while.

I was thinking about this on Saturday when I realized that the Adafruit Circuit Playground Express has everything I need for this project! Its 48MHz ARM Cortex M0 is more than enough, it has a circle of NeoPixel LEDs, two pushbuttons, an accelerometer, and a piezo speaker. It’s perfect.

With all those bright LEDs, I could implement the color display in a much cooler way. This is what the new timer looks like when it’s time to feed the dog.

The clear plastic case that Adafruit sells for the Circuit Playground Express has a nice 1/4-20 (camera tripod standard) metal nut that made it trivial to attach the board to the underside of the container’s lid. So much cooler to light up the whole thing! Bonus: it shows us how much food is left in there, too.

I ported the timer code from C++ (for the Arduino) to CircuitPython. This was my first real project using CircuitPython on the Circuit Playground Express, and I found the whole system very easy to work with. Download the CircuitPython firmware, plug the board into your computer, double-click the reset button, and then drop the firmware image onto the drive that shows up. Once the file is there, the board will reboot, and then a new drive will appear. On this drive is a file named “code.py”, and every time you write to this file, the board runs it. It also offers console over serial, including an interactive environment for experimenting with the behavior of these particular libraries running on this particular version of Python. This is an amazing way to quickly build an embedded device.

Adafruit provides a Python module for their boards that makes interfacing with the hardware simple and convenient. Create an instance of the module, then just read the property “button_a” to know if the button is being pushed or “acceleration” to get a tuple of x, y, and z acceleration. I couldn’t find an obvious abstraction for button clicks, but I found a pattern that I like. One feature of their module that I did not find in any of the examples is cp.were_pressed. This is a property that returns the set of buttons that are being pressed. Combined with a little bit of set arithmetic, this gave me rock solid debounced button clicks.

As always, the full code for this project is on github: https://github.com/erickhammersmark/dogfoodtimer. Here’s the new timer in action.

12 Sign redux

A few years ago, I posted about the Seahawks “12” sign that I keep in my window during football season. It was a piece of foam-core board with a strip of Neopixels punched through in the rough shape of a 12.

It is not without its charm, but I needed an upgrade. I have had great luck making fun things out of “RGB LED matrix” panels. These are not built from addressable LEDs like the Neopixel lights in my old 12 sign, but are bare RGB LEDs with just enough circuitry to power and address them. In order to get a persistent image, you have to write to them constantly. Nick Poole did a great write-up on these for Sparkfun.

These panels are usually available from Adafruit or Sparkfun, and they come in a small range of sizes and pitches (pitch is the spacing between the lights). The apple is drawn on a 32×32 6mm pitch panel, about 8″ on a side.

This is the back of a 32×32 4mm pitch panel (5″ x 5″). These panels all have two 16-pin connectors, one input and one output. The primary use case for them is as elements of much larger displays, and they are daisy chainable. You must power each panel individually via the hefty 4-pin connector in the middle. They usually come with a ribbon cable and a power cable (but not a power supply).

I’m driving that Apple logo display with an Arduino Pro Mini. I’m using an Arduino and not a Raspberry Pi because getting a stable image out of these requires consistent timing, and a Pi is just not good at that. I have successfully driven a panel like this from a Pi, but the image was always shaky and flickering. Enter the Adafruit RGB Matrix HAT! This handy little board comes as a kit, which just means that you get to solder the headers on yourself.

The long connector along the back plugs right into the pins on the Pi, the 16-pin connector in the middle is for connecting to the panel, and the screw terminals output 5v. There’s a 2.1mm a barrel connector on the left for 5v in (I recommend a high-amperage supply, at least 2A, preferably more), and there’s a battery slot on the right in case you care about having a persistent real-time clock. In my applications, I don’t need this. The hat will power the Pi, which is nice, and you can use the screw terminals to send power to the panel.

Using these tools, I can build a really neat 12 sign. Driving it with a Raspberry Pi means that I get the full capabilities of a Linux environment to help me decide what to draw. Being able to daisy chain panels lets me build a bigger display. For this project, I chose two 64×32 5mm pitch panels from Adafruit. I have mated them along their long edges, forming an approximately 1′ x 1′ square. I connected them using a 30cm ribbon cable I bought from Amazon.

To join the panels together, I first made a template by laying the panels out how I wanted them and using paper and pencil to make a rubbing of the holes. I used this template to drill out holes in some strips of scrap plastic and then screwed these to the panels (the panels have tapped holes for screw-in feet around their edges). I have a Raspberry Pi + Adafruit’s RGB Matrix HAT connected to the bottom panel and the bottom panel chained up to the top panel. Both panels are powered from the HAT, and the whole thing is powered by an Adafruit 5v 10A supply. I can get this system to pull up to about 40W (8A at 5v) if I turn all the pixels on brightest white. Typical draw is more like 16W.

The software is all python. It takes a rich set of CLI options to define what goes on the panel, and it also exposes an API endpoint and a simple web interface. These are plaintext, unauthenticated endpoints, please do not expose them to the Internet. It defaults to rendering text, but it can also display an image file (I have tested JPG and PNG). Display device options include a single 32×32 panel, a daisy-chained square of 64×32 panels, or an Adafruit Dotstar disc.

One interesting issue I ran into was that I could only convince the Adafruit rgbmatrix library to address the two panels as though they were arranged end-to-end, 128×32 instead of 64×64. I compensate for this by transforming my 64×64 square image to 128×32 at the last minute.

The main executable is “run_sign”, and to run a 64×64 display composed of two 64×32 panels, the call looks like this:

python3 run_sign --decompose --rows 64 --cols 64

The command line arguments represent a subset of the functionality represented by the API.

$ curl localhost:1212/help

Hawks API usage:
  /api/get                Return current settings
  /api/get/presets        Return a list of presets
  /api/set/key/value      Modify a current setting
  /api/do/image           Returns a PNG of the current image

Settings:
  bgcolor                 Background color when rendering 
                           text
  outercolor              Outer color of rendered text
  innercolor              Inner color of rendered text
  font                    Font to use when rendering text
  rows                    Image height
  cols                    Image width
  decompose               Display is a chain of two 64x32 
                           RGB LED matrices arranged to form
                           a big square
  text                    Text to render (if file is "none")
  thickness               Thickness of outercolor border
                           around text
  animation               Options are "waving" or "none"
  amplitude               Amplitude of waving animation
  fps                     FPS of waving animation
  period                  Period of waving animation
  file                    Image file to display (or "none")
  file_path               Directory in which to find files
  margin                  Margin of background color around
                           text
  brightness              Image brighness, full bright = 255
  disc                    Display is a 255-element DotStar
                           disc
  transpose               PIL transpose operations are
                           supported
  rotate                  Rotation in degrees
  mock                    Display is mock rgbmatrix

Calling run_sign with --mock will use mocked implementations of the RGBMatrix and RGBMatrixOptions modules. The mock RGBMatrix will draw the image to your terminal, using two spaces to represent each pixel. This is handy for developing code for an rgbmatrix while not physically near an rgbmatrix. And even when you ARE near your rgbmatrix, you do not have to disturb your sign to test new settings or develop new features.

Calling run_sign with --disc will set the display to an Adafruit Dotstar disc, assumed to be accessible via SPI. These are relatively low-res, but super beautiful.

You can find the code on Github: https://github.com/erickhammersmark/hawks

Automatic closet lighting

When I redid my closet, I went all out and installed over-closet lighting. It has this lovely soft glow that really classes up the IKEA. These lights have two drawbacks. First, their tiny switches are all the way up on the bases of the lamps, and there are six of them. Super inconvenient. Second, both sets of three lights burned out their power supply within the first year.

After having one of the supplies sitting in my workshop for years, I finally gave up on it and ordered some replacement supplies. 12v @ 60W x 2, just like the lights came with from IKEA. They even came with screw terminal 2.1mm jacks, which are very handy.

I gutted one of the IKEA supplies and retrofitted it with a 2.1mm jack. When I tested this with my closet lighting, I found that time and/or PSU death had cost me more than half of the bulbs. The new supplies were fine, but when I looked closely at the bulbs, I saw that they are 20W each. No wonder the original supplies burned out, they were running at their maximum rated capacity 24/7! Who can reach those six tiny switches? So I replaced them all with LEDs. I can run all 6 lamps off of one of the new supplies, they look great, and I can leave them on all the time without guilt. But that wouldn’t be any fun at all.

I picked up a 5-pack of PIR motion sensors (data sheet). This was my first experience with pyroelectric IR sensors, and I was surprised at how easy they were to work with. The modules I bought had a very simple 3-pin connector (+5, ground, and signal) with two on-board POTs for adjusting sensitivity and re-fire delay. I cranked sensitivity all the way up and re-fire delay all the way down and I was good to go. Once these things see a person, the signal pin goes high for the length of the delay. Since I’m not doing anything fancy with how I read them, this adds the length of the delay to my “lights off” time (which is 10 seconds).

schematic

The design is pretty simple. I built this project around an Arduino Pro Mini 5v/16MHz, my go-to one-off “production” build board. I have one of these running the sensors in my garage (post on that project is pending) and one running each of the NeoPixel control panel boxes in my kids rooms. Given how often I use these boards, I made a really boneheaded mistake when I moved this project from breadboard to protoboard: I wired Vin (which is 12V) directly to VCC (instead of RAW) on the pro mini. This kills the pro mini. Twice. SMH.

As you can see in the schematic, 12v in is wired directly to 12v out. I use an N-channel MOSFET to switch the output’s ground connection. This is a great transistor for this kind of project, because you can switch it all the way on with 5v directly from a digital I/O pin on the Arduino. In addition to the PIR sensor, there’s a physical switch that can also control the behavior of the lights. I’m using a big fat 3-position DPDT switch with one direction for ON, one for OFF, and the center position to allow the sensor to control the lights.

switch

system

Check out this amazing demo video, wherein I walk into my closet and then walk right back out again.

Behold the Debouncinator!

When you throw a switch or press a button, you expect that device to transition definitively and atomically from one state to the other. The switch is either open or it is closed, the button either is pressed or it is not. But in the course of those transitions, the metal contacts of the underlying switch can gain and lose connectivity many times. This is referred to as “bouncing”.

I grabbed some quick measurements with a USB scope (an MSO-19). This is a toggle switch:
switch

This is a tiny little clicky button:
button

If you are polling one of these switches with a microcontroller, you may wind up with short bursts of fluctuating measurements at each open and close. The fix for this is to “debounce” the switch by waiting for it to settle down before you decide that it has actually changed state.

#define DEBOUNCE_TIME 50 //milliseconds
unsigned long switchClosedTime = 0;
int state = HIGH;

void loop() {
  if (digitalRead(PIN) == LOW) {
    if (state == HIGH) {
      if (switchClosedTime == 0) {
        switchClosedTime = millis();
      } else if (millis() - switchClosedTime > DEBOUNCE_TIME) {
        state = LOW;
      }
    }
  } else {
    state = HIGH;
    switchClosedTime = 0;
  }
  if (state == LOW) {
    // The switch is flipped!  Do a thing!
  }
}

This is a basic debounce pattern. If the switch has been in the trigger state for a long time, then decide that it is done changing state. If you see it in the opposite state, then forget it, and start the measurement over when you next see it in the transition state.

I found myself implementing this same pattern in project after project, and eventually I wrote a little Arduino library for it (I used it in the NeoPixel Control Panel project). The Debouncinator makes it simple and convenient to debounce all of your inputs.

#include <Debouncinator.h>

Debouncinator db;

void setup() {
  // pin, initial state, trigger state
  db.init(5, HIGH, LOW);

  // same as 5, HIGH and LOW are the defaults
  db.init(6);

  // this pin triggers when it goes HIGH
  db.init(7, LOW, HIGH);
}

void loop() {
  if (db.read(5)) {
    // pin 5 has been debounced and is LOW
  }
  if (db.read(7)) {
    // pin 7 has been debounced and is HIGH
  }
  db.read(6);
  if (db.fired(6)) {
    // this will be true once for every time the pin
    // debounces to the trigger state
  }
}

You can find the Debouncinator on github: https://github.com/erickhammersmark/Debouncinator

What’s this?

This was a fun one.

I like to repair stuff. Fixing a thing is good for the planet. Not only do you continue to take advantage of all of the energy that went into obtaining the materials and crafting the thing, but you also save it from being buried in a hole in the ground. It can save you a bit of money, too.

Yesterday, I decided to repair my son’s headphones. He had been propping them up so that they pressed into the headphone jack of his computer at angle, because if they sat at the wrong angle, they didn’t work. I figured the connector was bad, I surely had an 1/8″ stereo headphone jack laying around, and it should be an easy repair. In order to hear the problem for myself, I plugged his headphones into a device and started to watch Nightmare Before Christmas. Sure enough, I couldn’t hear Jack Skellington singing “What’s This?” at all.

But wait. I could hear the orchestra, and I could hear them in both ears. I turned it up. I listened carefully. There was no trace of Skeleton Jack, but the instrumentals were clear, if muted. Pressing on the connector at the proper angle brought Jack’s vocals in perfectly. If the headphones didn’t work, I would expect there to be no sound at all, either in one ear or both ears. But what defect would cause just the vocals to disappear?

The answer turns out to be that the stereo audio of the movie I was testing with was encoded for Dolby Pro Logic surround. Before there were 7.1 channels of pure digital audio piped along our HDMI cables, there was Dolby Pro Logic. A stereo audio signal encoded for DPL has some material out of phase between the two channels. When you add the two signals together, the out of phase signal cancels out, and you get just what should be in the surround channel. When you subtract the signals, you get just what should be in the center channel. 4 channels of surround sound out of 2 channels of audio. Pretty neat.

What was happening in the headphones is that the two audio channels were shorting together, cancelling out what should be in the center channel and leaving me with just what should be in the surround channel. I clipped off the end of the cable, spent a few minutes learning which color meant which conductor of the headphone plug, and soldered on a new connector. All better!

2015-12-26-21.09.01

NeoPixel control panel

The holiday season is over, Christmas has been torn down, and a new year has begun. It’s time to figure out what to do with that reel of Neopixels that I bought last year. They made a fun little window decoration, but I don’t want to leave them there year round. I have it in my head to use some of them to make custom lighting for my sons’ bunk beds, and the boys are keen on this idea, too. After a trip to Radio Shack, we have all the parts we need.

2015-01-05-00.39.03

For each of two control boxes, one each of:

  • Enclosure
  • 50k linear pot
  • 1/4″ shaft knob
  • Red momentary switch
  • Black momentary switch
  • 2.1mm DC jack
  • 4-pin mic jack (panel mount)
  • 4-pin mic plug (in-line)

And I already had some other bits and pieces laying about:

  • DPDT center-off toggle switch
  • 5v power supply
  • mini breadboard
  • microcontroller

NB: A Trinket is pictured, but I decided that I want more inputs, I built these using Pro Minis.

2015-01-05-22.22.22

2015-01-05-21.35.49

I turned out to have drilled the hole for the pot’s little stabilizing pin on the wrong side, which meant that I had also wired it backwards, but it all worked out in the end. It’s not the kind of precision-routed beauty that my father taught me to love, but it’s not a complete rat’s nest, either.

2015-01-05-21.41.41

Assembly is straightforward. The plastic enclosure took 1d4 of damage at the hands of the drill press, but a little superglue fixed it right up. The behaviors will be pretty simple: use the toggle switch to select between two modes (solid color and disco mode), use the knob and buttons in each mode to adjust the settings for that mode. In solid color mode, pushing the red button will let you use the knob to adjust the color, and pushing the black button will let you adjust the brightness. In disco mode, pressing the red button will cycle through display modes (ripped straight from Adafruit’s strandtest sketch) and the knob will adjust the color where appropriate. The schematic couldn’t be simpler.

neopixel_control_box_schematic

The only tricky thing is the software: I want to use the various strandtest behaviors (color wipe, theater chase, rainbow cycle, etc.), but I don’t want to strand the user interface for the entire length of a behavior cycle. For example, theaterChase() looks like this:

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  //do 10 cycles of chasing
  for (int j=0; j<10; j++) {
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        //turn every third pixel on
        strip.setPixelColor(i+q, c);    
      }
      strip.show();
     
      delay(wait);
     
      for (int i=0; i < strip.numPixels(); i=i+3) {
        //turn every third pixel off
        strip.setPixelColor(i+q, 0);        
      }
    }
  }
}

https://github.com/adafruit/Adafruit_NeoPixel/blob/master/examples/strandtest/strandtest.ino

The value of “wait” is 50, which means that this function will take approximately 50 * 3 * 10 = 1500ms = 1.5 seconds to run. Unless I make my UI interrupt-driven (which is not my usual way of building UIs in Arduino), this will cause up to a 1.5 second delay between pressing a button and seeing any result. For some of the other modes, it’s worse. theaterChaseRainbow() would take more like 38 seconds. Clearly, this will not do.

Enter the global state rewrite! Now, theaterChase() looks like this:

//Theatre-style crawling lights.
void theaterChase() {
  if (i == 0) {
    for (i=0; i < strip.numPixels(); i=i+3) {
      //turn every third pixel on
      strip.setPixelColor(i+q, getColor());
    }
    strip.show();
    delay(wait);
  } else {
    for (h=0; h = 3) {
      q = 0;
      j += 1;
      if (j >= 10) {
        j = 0;
      }
    }
  }
}

It only calls delay(wait) once peer loop(). All of the local state has become global state, so not only do I get to do other work while I’m in the middle of a theater chase cycle, I can also modify its behavior mid-run, changing the color of the color wipe or theater chase behaviors.

After rewriting all of the modes this way, I’m ready to test.

A handful of zip ties later and I have some delighted children!

2015-01-08-20.10.27
2015-02-01-20.27.48

#12s

The Seahawks play the Packers tomorrow for the NFC championship, so here’s a quick “12th man” project. I took a square of foam core board, cut some slots at the ends and vertices of the digits 1 and 2, and threaded these slots with a 100-light NeoPixel strip.

2015-01-17-23.34.33 2015-01-17-23.34.51

Add a little support hardware and you have one fancy window decoration.

2015-01-17-23.40.11

This connects power from the strip to +5v and ground on the Uno and the data pin on the strip to digital pin 6. The 1000uF cap across the power and 470ohm resistor on the data line are per Adafruit’s recommendations. If I decide to keep it for next season, I’ll probably mount a Pro Mini or a Trinket to the back of the foam board so that all I’ll need to do is connect it to power.

The code is very simple, adapted from the “theaterChase” function in the NeoPixel example sketch.

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define NUM_PIXELS 100
#define DELAY 50

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);

uint32_t green = strip.Color(0, 255, 0);
uint32_t blue = strip.Color(0, 0, 255);
uint32_t color = green;

void setup() {
  strip.begin();
}

void loop() {
  for (int q=0; q < 3; q++) {
    for (int i=0; i < NUM_PIXELS; i=i+3) {
      if (color == green) {
        color = blue;
      } else {
        color = green;
      }
      strip.setPixelColor(i+q, color);    
    }
    strip.show();
     
    delay(DELAY);
     
    for (int i=0; i < NUM_PIXELS; i=i+3) {
      strip.setPixelColor(i+q, 0);        
    }
  }
}

And here it is in action. Go Hawks!

Does the Christmas tree need water?

It seems that more and more people are putting up fake Christmas trees, these days. Well, not so at the Hammersmark home. We used to go cut down our own, but, this year, we bought it from the Boy Scout lot nearby. We got a beautiful 7′ Nordmann, managed to squeeze a couple of hours of tree-trimming into our ridiculously busy holiday schedule, and now I get the job of keeping it from burning our house to the ground.

I have a simple system that I’ve used for several years to keep me from having to get down on my hands and knees with a pint glass full of water. It’s a length of 3/4″ plastic tube duck taped to a funnel. The funnel is connected to a heavy duty twist tie, which I use to hang it from the tree like the biggest, ugliest ornament ever. I route the tube to the tree stand, then I pour water (slowly) into the funnel and trust that it’s both making its way into the tree stand and not overflowing the basin. I have, in the past, been mistaken.

moisture_sensor

Enter: as-yet-unused garden automation supplies. Last year, I bought a six-pack of cheap moisture sensors from eBay. I also picked up (from Sparkfun) a couple of 12v 3/4″ electric valves, a handful of Arduino Pro Minis, some N-power MOSFETs and some relays. I never did get around to automating the garden, so I still have all of this stuff sitting around the workshop. I decided to put some of it to use (and learn how it works) by building a water level sensor for my Christmas tree stand.

sensor

The sensor is brilliantly simple. It comes in two parts: the sensor strip and a small driver board. The driver board offers 4 pins back to the microcontroller: Vcc, ground, digital signal, and analog signal. The digital signal just runs a comparison on the analog value, controllable by a variable resistor mounted on the board. The analog signal just gives you a voltage somewhere between 1/3 Vcc and Vcc. Though it is intended to go into moist soil, it is perfectly happy reading a half full glass of water.

board

I had a few empty plastic Christmas ornaments that I picked up thinking I might stick some Neopixels in them. One of them was big enough to hold a Pro Mini, so I soldered 5 LEDs to 5 digital pins, soldered 1k resistors to the negative leads of the LEDs, soldered these all together and then connected this to ground. I wired in the sensor board and a power supply, ran all the wires out the top of the ornament, and my water level sensor was ready to go!

3bars

I looped the sensor strip’s cable over part of the tree stand and just let it dangle in the water. When I first installed it, the tree hadn’t had any new water since the previous day, but the level wasn’t anywhere near the base of the trunk. I adjusted the height of the sensor until this lit up 3 of my 5 LEDs. After pouring in a pint of water, the sensor lit up all 5 of my LEDs. Success!

5bars

Next step: Use this to trigger a system that automatically waters the tree from a reservoir. Now I just need another one to monitor the level in THAT…

UPDATE: I am sad to report that immersion in my tree-water (or, perhaps, in any water) causes the moisture sensor to quickly deteriorate. This project worked perfectly when I first installed it. By the following morning, it would only ever read 2 or 3 LEDs full. I pulled the sensor out this evening to discover this mess right here:

2014-12-10-21.58.16

After cleaning up the corroded probe, I found I could get more-or-less 3 reliable signals: dry, some water, and fully immersed. I reworked the code a little bit to cope with only 3 signal levels and am, for the time being, back in business.

intree

Tiny robots are the best robots

I have long admired Actobotics, a “robotics building system based around extruded aluminum channels, gears, precision shafts, and ball bearings”. It’s like a beautiful, heavy-duty, precision-crafted Erector set. For some reason, I never bought any. It’s kind of expensive, and there are so many parts (470, at least when SparkFun started carrying them last year) that I didn’t really know what to buy.

So, I bought a kit! I bought the ActoBitty 2, ROB-13047. It’s a little two-motor tricycle robot, with clips for mounting an Arduino Uno and just enough room left over for some sensors. It comes with motors, wheels, a little fixed caster, and a battery case, all of it mounting on about 4″ of that lovely aluminum channel. Thirty bucks at SparkFun.

2014-10-27-20.25.40

Assembly was totally straightforward, though it didn’t come with any printed instructions, just a link to a video of someone putting one together (as it turns out, they have written instructions on their website). After a lot of pausing (the video was sped up in many places), I had a tiny robot. The kit doesn’t come with a microcontroller or any other way to control the motors, but it does come with a place to snap in an Arduino Uno, so I did. I didn’t have any motor shields on hand, so I just threw a couple of MOSFET transistors into a tiny breadboard and patched that into the Arduino, and then I could drive the motors.

2014-10-27-22.51.19

This worked well for driving either or both motors forward, but could not drive them backward. To do that, you need something like an H-bridge, which can apply power to the motor in either direction. If you can’t be bothered to put together an H-bridge (I couldn’t), you can buy a nice Arduino shield that wraps an H-bridge IC. I am very fond of the Adafruit Motorshield but, because they were backordered at the time when I was doing this project, I wound up using a cheap clone instead.

2014-11-15-15.47.38

OK, so I can write a program to make the wheels turn in the directions and at the speeds that I desire. Awesome. What else?

By this point, Halloween was done, and my Parallax Ping was free. I threw that into a tiny breadboard and, for the first time (I think), peeled the sticky backing off of the back of one of those tiny breadboards and stuck it right onto my beautiful, precisely machined aluminum channel.

2014-11-02-21.59.02

If I want to take it off, I’m sure I can scrape that adhesive off of the aluminum. It’s aluminum: it will always be beautiful.

Now my tiny robot can see the world!

The algorithm is super simple:

void loop() {
  int distance = measureDistance();
  if (distance < DISTANCE_THRESHOLD) {
    rotate_left();
  } else {
    forward();
  }
}

This works fine for getting around, unless one of the wheels gets stuck on something. It seems to have trouble seeing the oven; maybe it’s the angle.