Saturday, January 12, 2013

Embedded Halloween Costume




Summary:
Used Halloween as an excuse to get myself back up to speed on basic electronics and Arduinos. Ended up with something with flashy lights that looked great in the dark.

Motivation:
After finishing my grad school qualifying exams, I took a few days off work to get myself back into electronics. Halloween was coming up, so I could kill two birds with one stone by making some kind of light-up costume.

Build Details:
After searching around the internet for ideas, I found a few sites offering instructions on how to make an Iron Man costume using LEDs and miscellaneous hardware parts. I decided to model my costume after this image and include a microcontroller to control the LED brightness. There were four main components that needed to be built: the chest light, the hand light, the controller circuit, and the arm brace.
Goatee not included.

The chest light was made by punching holes in a circular piece of cardboard and gluing some blue and white LEDs into the holes. The LEDs were connected in series in groups of three or four, so there were a couple wires coming out of the chest unit that would need to be hooked up to power. I didn't care much about the number of wires needed to power everything, more bare circuitry would make it look a little more authentic anyways. To diffuse the light, I added another layer of cardboard and masking tape to the front to get the outline I wanted.
Cardboard and duct tape, because Halloween is only one night.

Poor white balance on my part making the blue LEDs look purple.

Looks much better with the lights off.

The hand light was made similarly with 7 LEDs (mix of blue and white) on a cardboard backing. For some reason I decided it was not interesting enough to take pictures of while building, so you'll have to use your imagination.

With both lights built, it was time to figure out the controller circuit. I wanted the microcontroller to have complete control over the brightness of the hand and chest units independently, so I wired up a simple circuit that would drive the LEDs with transistors and allow pulse-width modulated output from an ATtiny84 to set the brightness.
Testing the circuit.

Final board. Not pretty, but it worked.

After burning the Arduino bootloader on to the ATtiny I uploaded a sketch that would slowly modulate the brightness of the chest light like a heartbeat. When the button is pushed, the chest dims, the hand flashes for a few seconds, then the chest comes back on with a faster heartrate that slows back down over time. The full code can be found here.

I'm a fan of making my Halloween costumes super-cheap, so the entire arm brace was made out of cardboard, duct tape, and an old motorcycle piece or two. While duct tape obviously isn't the best choice for structural stability, the costume only had to last a few hours of one day.
All assembled.

Bright enough to provide dramatic lighting.

Insights:
1) The ATtiny85 is a great alternative to a full-blown Arduino board when you want something cheap and small. I'll probably use them again in future projects.
2) The lights look nice in the dark, but were far too dim in normal lighting. It might have been worth it to significantly increase the number of LEDs and just be prepared to change the battery every now and then.

Thursday, January 3, 2013

Water Level Analysis

The water level sensor has been steadily collecting data for more than 4 years now. Well, not so steadily. There are small gaps in the data due to things like internet connectivity issues, power outages, code bugs, you name it. Then there are larger data gaps, usually due to a physical malfunction of the sensor. Not to say it was poorly set up or is poorly maintained, in fact it has lived through a good number of storms.

As mentioned in the previous post about the build details, two sets of data are held in the online database. One is high temporal resolution data from only the most recent few days, and the other is coarser data for as long as the project has been going. For this post I will be showing this second data set and hopefully pointing out some interesting features. No build details or motivation, just good ol' analysis.

(Click to Embiggen)

Without any processing, this is what it looks like for the first 1000 days. After this, it's mostly gaps in the data due to my own negligence. But even in this 'nicer' part, there are some obvious flaws. The first is the large gap around day 200. I'll get back to that one. Next is the spiderweb of lines going back and forth through time near day 400. At some point around that time there was a bug in determining the timestamp to associate with a data point, so data was being sent around in time. A quick sweep through the data to remove non-sequential data points would probably clear that up. Next is some anomalous data near data 800 and 1000 showing the water level suddenly dropping to a constant -2.7 feet. After conversion, that is the level returned if the ultrasonic sensor consistently reads the maximum value it can. I'll be honest, I don't remember why that happened. Oh well!

Now that we've pointed out all of the flaws, let's look at the clean parts.
The first couple of days of data sure look clean. The most obvious trend is the daily tides which cause about a foot of variation every day.
More normal daily variations, but suddenly we hit the large gap from the first plot. Even before the gap, there is a long trend of rising water level. Right around the day 175 marker on this plot, Hurricane Ike made landfall a few miles away. The damage to pretty much everything on the island was pretty bad, so getting the water level sensor back up and running was not the number one priority. And so, large data gap.

But back to the cleaner parts of the data, we can also look at tide patterns and how storms play into the mix.
This is the longest portion of uninterrupted data I have, so I'll spend some time analyzing it. As before, we see the daily tide variation causing a foot of variation, but there is something else on top of this signal causing low amplitude nodes every 14 days or so. These low amplitude tides are called neap tides, while the large tides that occur in between are spring tides (this wiki article explains it more). Near day 125 is a storm that rolled through and messed up the nice tide pattern from the weeks before. As seen in both this storm and the hurricane from before, it's possible to predict incoming storms by a day or so just by keeping track of the water level.

The daily and monthly tidal variations are pretty obvious by looking at these time-series plots, but periodic features such as these should also be visible when looking as a function of frequency. The neap/spring tide pattern mimics a beat, so we might expect to see two peaks of power separated by a frequency splitting corresponding to 14 days. To look for this, I apodized the data from the previous plot using a reasonable-looking Gaussian, took a Fourier Transform, and plotted the logarithm of the magnitude.
The whole spectrum, log power. Clearly I record too many data points per day.

Looking at the low frequency power, there are two significant peaks located at 11 uHz and 22 uHz. These frequencies correspond to 25.3 hours and 12.6 hours, respectively. Not quite the frequency splitting I was looking for, but nice to see the daily tides showing up strong. Now at this point in my analysis, I nearly gave up thinking the frequency splitting was hidden under the noise. Maybe it takes more than just a few weeks of clean data to measure this subtle sun-moon interaction.

On a whim, I decided to check out the two small peaks on top of the left larger peak. Considering the scale of noise in the rest of the spectrum, I wouldn't really want to assign much meaning to these. But maybe.. By eye, the two peaks have frequencies 10.76 uHz and 11.57 uHz, so a difference of 0.81 uHz, which is a period of... 14.3 days! Exactly what was expected. Unfortunately, the scientist in me is saying this is just a cute coincidence due to noise and we shouldn't take this seriously. Still, kind of cool to see.

Wednesday, January 2, 2013

Water Level Sensor


Summary:
Used an ultrasonic sensor, 555 timer, netbook, and PHP skills to create a live online database of the water level in Galveston Bay.


This is a project started by my father and me in Spring 2008, with modifications and additions being made intermittently through the years. It is by far the longest running project I've ever done. The setup has been recording water level data in Galveston, TX almost continuously since the beginning (minus a hurricane or two), and the most recent few days of data can be viewed live on the internet:

Most recent 6 days of data. Sometimes looks weird if I've recalibrated something, or if a hurricane has wiped out our house. The dashed blue line is roughly the height of the bulkhead.

Motivation:
Measure the water level in Galveston Bay and display the results on the internet. Simple enough..

Build Details:
1) Sensor
The first issue was how to actually measure the water level. We have a house with a boat slip, so direct access to the water isn't a problem. One method would have been to have some sort of sensor float on top of the water or run down the height of the bulkhead. Exposure to salt water would cause problems for any kind of sensor we could think of, so we opted for remote sensing. We mounted an ultrasonic sensor a few feet above the water pointed down to measure the distance between the sensor and the top of the water. The first sensor we used had a range of 6 to 255 inches with one inch resolution. The connections needed to control the sensor (Vin, GND, TX, RX) were made through an ethernet cable running from the mounted sensor all the way back into our house (~50' of cable) where the rest of the electronics were. We did this to limit the amount of circuitry exposed to the elements.


2) Controller
The second part was figuring out how to trigger the sensor to take a measurement and how to read the result. All that is needed to trigger a measurement on the sensor we chose is a single pulse at least 20us long on the RX line. I wired up a simple astable 555 timer circuit that would send such a pulse 4 times per second, enough to capture the change in water level due to individual waves moving by. Once the sensor has made a measurement, the result is sent back on the TX line as regular serial data in the format R###, with the number corresponding to the distance between sensor and water. The TX line runs straight into an adjacent netbook for processing.

3) Processing
Running on the netbook is a short C# code that reads the incoming serial data and parses it. After converting the R### message from the sensor into a water height using a known calibration, the code stores the result into a buffer. After collecting about 100 measurements (25 seconds of data), the mean and standard deviation of the buffered data is computed. Since the measurements are being taken a few times per second, the standard deviation is taken as an approximate wave height and stored along with the mean water level. Once a few of these water level / wave height pairs are collected, the code sends them off to the internet for logging.

4) Logging
One measurement every 25 seconds is still a lot of data to store if you are interested in keeping track of years of data. The data set sent from the netbook gets stored in two different databases. The first stores every measurement received, but clears out any data that is over 7 days old. This way, recent data can be viewed at high resolution and only requires about 25k data points. The second database stores 15 minute averages of the incoming data, so even years of data only needs 100k data points. In all, both databases combined only take up a few megabytes of memory.

5) Plotting
To generate live plots of the most recent few days of data, I wrote a somewhat lengthy PHP script that would read data from the database and output a png file plotting the data. Instead of using a library for plotting things, I for some reason hand-wrote how to set up the axes, autoscale them, draw grids, print labels, and plot the water level line by line. While this allowed for a significant amount of customization, in hindsight I think we could have survived with a pre-built library like Google Chart Tools. Still, the plot works well and allows the user to set both the image dimensions and the time extent to display.

To this day, the water level plots have been useful for figuring out water conditions, tide patterns, and incoming storms. At some point I'll write a post showing some of the long-term recorded data and how it can be analyzed. All kinds of interesting features can be seen, like the interplay between solar and lunar tides and the effects of incoming storms.



Insights:
1) Weather-proofing an outdoor sensor is difficult, but not impossible. Over 4.5 years the sensor had only been compromised once, and that was from a hurricane that was able to take someone else's boat and place it on our lawn.
2) The 555 timer is too simple and static, while the netbook is too complicated and overpowered. A simpler solution would be to use a single Arduino board to trigger the sensor, process the measurements, and send data to the internet.