December 5, 2011

Christmas-tree water-level alert

Update 12/11/11: A fix to the program--- changed to capSenseRaw() instead of capSense(). The problem with capSense() is that it auto-adjusts the output for touch sensing, rather than absolute capacitive measurement. capSense() reports whatever capacitance it observed the first time as zero from then on. This means that if the water level is high when the Arduino is turned on, high will be interpreted as dry... And it's not very convenient to make sure the sensor is outside the tree-stand whenever you first turn the lights on! Kinda misses the point of this whole exercise if you have to take the sensor out, dry it off, turn the lights on, put it back... But using capSenseRaw() takes care of the problem.

One other note: the sensor has to be very waterproof! The 4 coats of polyurathane were marginal: I've since added a thin coat of silicon RTV and it works much better. If water touches the electrode strips, it shorts out the capacitor and the sensing function returns -2, which leads to erroneous reports of low water level.

-- --- ----- ------- ----------- -------------

About a year ago I made a Christmas-tree water-level sensor that didn't hold up well. Here's a link, but don't make that one. It had a flashing LED, then an audible alarm, to let you know that the water was either low or gone. But why use an LED? As "Joe" suggested in his comment last year, the tree has a lot of lights on it already and why not flash them instead?

Good idea, Joe. Thanks!

The functional problem with last year's model is that the copper traces used for the water-level sensor corroded quickly, and the device was useless in less than a week. The fix I came up with this year is to use a capacitive measurement of water level instead of a conductive measurement. This method (and the necessary CapSense library) is described on the Arduino Playground wiki as an idea for a proximity sensor. Since water has a very high dielectric constant, the presence or absence of water significantly changes the capacitance of a pair of copper traces. Measuring the capacitance of those traces then gives you a measurement of water level while keeping the traces isolated from the water.

Here's my sensor. It's just a strip of strip-type protoboard. (It's 4 traces wide, but I'm only using 2 traces.) It's been covered with 4 coats of spray-on clear polyurethane, so it is (one hopes) completely waterproof. There are two neodymium magnets glued to the back so I can mount it to the inside of the Christmas-tree stand. I forgot to put something in the picture for scale, sorry: it's 9cm long.
With this improved sensor, I can now use the CapSense library to measure water level without worrying about corrosion of the copper traces. And I probably should have stopped there, but Joe's suggestion just seemed to good to pass up. So here's the schematic for the rest of it:
Everything inside the dashed lines is built into a small box. The box has a plug receptacle on the top, into which are plugged the tree's lights. Power to that receptacle is switched by a relay, controlled by an Arduino Pro Mini. (The Pro Mini and relay are powered by a 9V wall-wart transformer, also mounted inside the box.)

If the Arduino detects a "good" water level, it leaves the relay alone and the lights plugged into the receptacle stay on continuously. When the water level drops to "fair", the Arduino cuts the lights briefly once every 5 seconds. When the water level drops below that, the Arduino flashes the lights once a second. Here's the box: I wrapped it in shiny paper to help it "blend in" under the tree.
Here's the code. The values of "fair" and "good" will depend on the exact geometry of your sensor and sensor cable. Uncomment the serial lines in that code and see what values are coming back from the Arduino to determine what levels are appropriate for your setup.

A note for the Arduino-haters: Yes, this could be done with an ATtiny85. Here's why I decided to use a whole Arduino this time:
  1. You need fairly precise timing to measure capacitance repeatably with the CapSense library. That means you need an external crystal rather than the microcontroller's internal oscillator.
  2. The 12A relay I used needed 9V to activate. (My local Radio Shack didn't have a 5V relay that could switch more than 1A.) An ATtiny needs 5V at most, so I would need a voltage regulation circuit.
  3. I needed to know the values coming out of the CapSense routines so as to be able to set the cutoffs for "good" and "fair" in the final program. That meant I needed a serial link back to the computer for the setup process.
  4. Put all this together and hey, it's an Arduino. The Arduino is built already, and I have to write an exam this week also.
But yeah, it'd be cheaper and more elegant if I just used an ATtiny85. :-)

Update: Since I have the memory available, I tweaked the program a bit. Instead of a fast blink when the tree gets dry, it now blinks "water... water... water..." in Morse code.

September 14, 2011

Hovercraft

Stefan and I cleaned out the garage last weekend. We found some useful scraps of plywood, and plastic sheeting, and a roll of duct tape, and a leafblower that nobody was using for blowing leaves. Rather than just throw them away, we decided to stick them together first and THEN throw them away. So we built a hovercraft.

This is not the usual electronics-related hack; it has nothing to do with microcontrollers or teaching physics. But it was fun... and it's definitely a hack! Here's how to build your own.

Start with a piece of plywood with an area of 7-9 square feet or so. Circular would probably work best, but anything roughly symmetric should be fine. Cut an off-center hole in it. Cut a piece of plastic sheeting about 6" larger than the plywood.

Put the plastic under the plywood and fold the plastic loosely up over the edges. Tape the plastic down with duct tape. Staple through the tape every 1-2 inches, then put a second strip of tape over the staples to seal it. It should be evenly loose, not tight!
 We put the staples too far from the edge in these pictures, and had to put in a second row of staples closer to the edge. More duct tape! Make sure the plastic is completely sealed to the plywood, because when it comes off your hovercraft will stop hovering.

Now turn it over and cut four (roughly) symmetric holes around an 8-inch circle in the center. We just cut slits a little more than 2 inches wide. We then fed duct tape through the holes so that the center of the plastic was attached to the plywood. Anchor it firmly with more staples, and reinforce the plastic around the holes with —you guessed it— more duct tape.
Air can now blow in the hole in the plywood from the top, inflate the plastic into a flattened donut shape, and exit through the holes in the center. The filled plastic "bubble" makes a skirt for the hovercraft.

Next, turn it right-side up again and attach the leafblower. We used more plastic and duct tape and staples... Lots of staples... More duct tape... and eventually got something that would direct the air through the hole without too much leakage.


Sit on top and turn the blower on — you're good to go!
Obviously a gas-powered leafblower would be an improvement — this one is limited in range by the 50-foot extension cord. It's still fun for sliding around the driveway, though!

August 25, 2011

How long until Christmas?

I have kids. They have questions. One of their big questions, all year long it seems, is "How long until Christmas?" Here's one way to answer that question.


The circuit consists of three main elements: Arduino Pro Mini, DS3231 real-time clock (RTC) breakout board, and a standard 2x16 LCD. 

The Arduino Pro Mini takes power (raw) from the 9V battery through the toggle switch. The Vcc output  of the Arduino's regulator (5V) is used to drive the LCD and the clock. Here's the program on that Arduino. The program reads the time from the RTC, calculates the number of seconds between 'now' and a hard-coded 'targetDate', then from that time differential calculates and displays the number of days/hours/minutes/seconds remaining. It does this roughly 4x/second, which makes a nice ticking-second countdown. When the countdown reaches zero, it displays "Merry Christmas!" and goes to sleep.

The Arduino uses I2C to communicate with the RTC. I used a homemade DS3231 breakout board with a battery backup for my RTC, but one could use the more standard Sparkfun DS1307 breakout as well. In either case, my DS3231 library works fine. The code provided above does not set the clock: it assumes the clock has been set previously. I used the setClock.pde sketch from my DS3231 library to set the clock using the serial port, and no hardware changes are required to make that program set the clock on this circuit.

The LCD is a standard 2x16 LCD with the HD44780 driver, as shown here.

Nothing particularly fancy, but I just happened to have all the necessary parts sitting on my workbench anyway so I threw it together one evening. You can of course change the target date and message in the software so it works for any other event you might want. At this point in the semester, I'm leaning towards counting the seconds until the Physics 202B final...

August 3, 2011

Simple Arduino data-collection

At this year's "Arduinos in the Physics Lab" workshop at the AAPT meeting, one of the participants asked for a simple way of using the Arduino as a tethered A/D converter for data collection direct to a computer. This is my quick & dirty demonstration solution.

Here's the code for the Arduino. It waits for a single byte 'N' to arrive on the serial port, then once that byte arrives it sends out N data pairs formatted as tab-separated millis() and analogRead() values. The readings are separated by roughly 10 milliseconds. This version of the code only reports the values of analog pin 0 (A0), but it can be easily modified to return other (or more) ports.

For the computer end, I used Python: here's the code. This was done on a Macintosh, with Pylab installed so I can use matplotlib to handle the plotting nicely. On Linux or Windows the port will be described differently, and if the program fails for you on the line 'import pylab as pl' then ... well, install pylab on your system. It's a great wrapper package for scipy, numpy, and matplotlib. The program expects two arguments: the number of points to collect and the filename where points should be saved.

Here's a sample output plot, showing relatively meaningless data from a light sensor.
One glitch I found was that there needs to be a short delay between starting the serial communications to the Arduino and sending the request for N data points. I do not know whether this is a problem with the Arduino in general, or with the Arduino Uno I was using as a testbed, or with the pyserial library, or with the Macintosh implementation of pyserial... It was a mess trying to figure out what was going on, though, because when in interactive mode everything would work perfectly but the exact same commands in a Python script would not work. The difference of course is that I would take several seconds to type commands in interactive mode, and it took me a long time to figure out what was causing the problem! The solution I used is in line 37 of the code:
    time.sleep(1.5)
The sleep value (1.5 seconds) was determined by trial and error. ser.flush() should work also, but I did not find this to be the case.

June 25, 2011

Stereo Camera rig


This is something I've been wanting to try for awhile: I'd like to take pictures I can use with an old-school stereoscope. It seems like a simple enough idea: you just need two pictures of the same thing, taken from a few inches apart. I've seen it done with just two cameras —no external synchronization, just push both buttons at the same time — but it seemed like I could probably synchronize things a bit better than that.

Ideally, it would be perfect to set things up so that one camera was a master and the other a slave: exposure and zoom parameters would be set on the one, which would then be duplicated on the other. The Canon Hack Development Kit (CHDK) gave me some hope that this might be doable, but I haven't found any straightforward way of setting up a master/slave relationship, so instead I used cruder methods. The cameras use a CHDK script to time how long power is applied to the USB connectors, and depending on the pulse width the cameras either zoom in, zoom out, or shoot.

The pill-bottle on the left contains a 4-AA battery pack, 5V regulator, some buttons, and an ATtiny85 to convert button presses to appropriate-length pulses for the cameras. It's not ideal, but it does give me synchronized zoom and shoot capacity using the one set of controls on the pill-bottle.

Here's the code for the cameras, and here's the code for the ATtiny85. One thing I found out by extensive trial and error is that the signal at the USB connector must be 5V. Less than 4.5V does not work, at least on these eBay-special A590is cameras.

I still think there should be some way of having one of the two cameras tell the microcontroller its settings, and have the microcontroller set things to the same values on the second camera. That would allow much easier use of the excellent controls available on the A590is camera. But someone else will have to figure that one out. Send me a link if you know of someone who's successfully managed this!

June 21, 2011

Morse-code trainer

My kids are learning Morse code this summer, so I threw together this little circuit to help them learn. And to make it more fun...
It uses an ATtiny85 ($2.26 at digikey.com) to drive a piezo beeper (≈ $3.50 at Radio Shack.) The ATtiny85 takes 5.5V max, so I built the circuit on a piece of strip-board so as to fit onto the back of a 3-AA-cell ($3 or so at Radio Shack) battery pack.
To program it, I used MIT's "High-Low Tech" ATtiny85 core using an Arduino as an ISP programmer. I actually built a 6-pin ISP header into the board, so I don't have to pull the chip out to reprogram it as you would with MIT's instructions, but that's neither here nor there. Using an Arduino core allows me to  use all the Arduino tools I'm familiar with, but I don't have to spend $20 or more on a full Arduino when all I really need is one output pin and a couple kb of program space. The ATtiny85 is perfect for this: plenty of memory and dirt cheap. (Actually, an ATtiny25 would work with the amount of memory this program takes, but ATtiny85s are so cheap you don't save much buying the ATtiny25.)

Here's the code. When the device is powered up, it waits 3 seconds then puts out the message at the desired speed. The message repeats until power is removed. Currently the message is "SOS the moon rover has broken down and I am stuck in the trash can in the garden shed." Once the kids decode it, they'll find a small Lego moon rover there as a prize.

Changing the speed of the Morse output is easy: just increase or decrease the definition of DOTLENGTH and everything adjusts proportionally. Changing the message is equally simple: just change the value of message[] in the source code. As written, it can handle up to 255 characters in the message. The program can handle upper/lower case, numbers, and some punctuation.

The program will also work with an Arduino, of course. You can even change the value of OUTLINE to 13 and the Arduino will use the built-in LED. (No circuit required, just a bare Arduino!)

I know Morse code is pretty much obsolete now. You don't even need it for a ham license any more... but all the more reason to learn it! 

.... .- ...- .  ..-. ..- -.  .-- .. - ....  .. -  .- -. -..  . -- .- .. .-..  -- .  .. ..-.  -.-- --- ..-  ..- ... .  .. - .-.-.-

May 9, 2011

Arduino-based event counter

I teach Modern Physics here at CSUC, and we occasionally use isotopes with half-lives of a year or less (such as Zinc-65 and Cadmium-109) for energy-calibration sources for a gamma-spectroscopy lab. I thought it might be fun to try measuring the activity of one of these sources over time and thus get a looooong-scale half-life data-set for students to play around with. Or maybe watch background nuclear count rates as a function of time for a couple months and see if we can locate the sun and/or galactic center from the cosmic ray count rate as a function of time and/or season.

I didn't want to dedicate an entire computer and LabVIEW seat to the project, and besides I haven't yet seen a six-month period here during which our power didn't go off at least once. I figured it'd be nice to have a cheap self-contained module that did nothing else but count and log the counts. Here's what I came up with:

The control unit is an Arduino Pro Mini, 328/3.3V/8MHz. It talks to a DS3231 real-time clock to get time-stamp information, and counts nuclear events (or any other digital signals) using an interrupt. Every hour (or so) it saves the event count to the SD card, with time-stamp information at the beginning and end of the interval, and starts another interval. The board has a large capacitor and a zener diode so that if the power fails the Arduino immediately saves the current count (with time-stamp) and writes a warning in the file to let the user know what happened. When power resumes, so does the counting — on the next line in the file with a new time-stamp, of course. When you're ready to stop collecting data, flip the switch and pull the SD card: everything is saved in ASCII format on the file "DATA.TXT"

It can comfortably count events at up to 10ks/s. Possibly more, but I've not tested it past that rate as that's two orders of magnitude faster than what I need. There is also a count/don't-count switch, a battery backup on the RTC chip, an ALD1701 op-amp follower making sure that the input pulses are 3.3V-safe by the time they reach the Arduino, and of course an LCD that provides helpful information such as the time/date, count, and occasionally an error message.

A complete parts-list, EagleCAD schematic and board layout, and Arduino programs are available here, should you want to make your own. I use the DS3231 library I wrote earlier, so you'll need to either grab that or modify my code to use your own clock routines if you'd prefer. The board layout I put together has larger-than-necessary pads —particularly on the vias— to facilitate 2-sided board production if you're using the toner-transfer method.

In order to set the clock, you'll need to run the SetClock.pde program on the Arduino once. (It's provided in the above link.) This program uses the serial port connection to the Arduino to set the DS3231 clock: send the string "yymmddDhhmmssx" just once, and after that the clock will be fine until the CR1220 battery runs out in 10 years or so. (i.e. "1105092190115x" for 2011 May 9 Monday 7:01:15pm.) After the clock is set the first time, load and run the scaler.pde program for actual data collection.


Good luck with it, and feel free to contact me with any questions if you try making your own.

April 4, 2011

DS3231 Real-Time Clock

I've used the DS1307 Real-Time Clock (RTC) for a few projects in the past, but I'm currently working on several datalogger projects that use both RTC and SD-card. The problem is that the SD card won't survive 5V, and the DS1307 won't work at 3.3V. That particular clock chip needs a minimum of 4.5V according to both the datasheet and some inadvertent "experimental verification".

Rex Belli (One of my students and an all-around bright guy, contact me if you're hiring a summer intern) pointed me towards the DS3231 as a possible replacement. It has several advantages over the DS1307:
  • It runs fine on either 3.3V or 5V.
  • It has a built-in oscillator: no external crystal required.
  • It has two built-in alarms that can drive an interrupt pin, so if you just need a periodic interrupt signal this chip can in many cases do the job without a microcontroller.
  • It' rated to 2 minutes per year (max) drift. (My best DS1307 clock drifts about 2 minutes per month!)
One disadvantage is that the DS3231 doesn't have the eprom storage that the DS1307 has, but you can cheat and store seven bytes in the alarm registers if you had to.

I wrote an Arduino library for it, so if you want to use this clock chip with that microcontroller it makes things a bit easier.

Here's the library: DS3231.zip
The header file (DS3231.h) is extensively commented, and there are several example sketches included as well. Enjoy! If you use the library for anything interesting, send me an email. I'd be happy to hear what's been done with it.