May 12, 2013

"Ayrduino" Single-Sided Arduino Clone



I'm teaching "Electronics for Scientists" this semester, and I wanted to allow each student to have their own Arduino to play with for microcontroller lab exercises and possibly use for their final projects. The Arduino is not very expensive at roughly $30 per, but they add up quickly when you have a whole class of students needing one each. I'd been buying enough electronics equipment over the course of the semester that my department chair was showing an involuntary tic any time I knocked on his office door... So I built my own. They are a stripped-down variant of the Duemilanove.

Hoo-ah:
  • Standard Arduino form-factor and mount-points.
  • Accepts standard Arduino shields.
  • Single-sided board, easy to make with toner-transfer method. 
  • 16MHz ATmega328.
  • No SMT parts.
  • On-board 5V regulation.
  • Screw-terminal power-in connector, rather than barrel jack.
  • Pin-13 LED.
Meh:
  • Lacks on-board USB-Serial conversion, so programming requires an FTDI cable.
  • No 3.3V regulator.
  • This is as detailed a board as I ever want to make using toner-transfer.  
  • No TX/RX LEDs.
  • No ISP connector.
  • Three component-side jumpers. Couldn't quite get all traces on the back side!
None of these down-sides are significant for this application. The requirement of FTDI cable is inconvenient, sometimes, but I have 3-4 of them in the lab and students share them without too much squabbling.

My grader, Lena, did most of the drilling and soldering work. She's graduating next week, and I'll miss her, but the graduate program in Nuclear Engineering at University of New Mexico is going to be thrilled.

If you want to make your own single-sided Arduino variant, and this set of pros/cons is acceptable to you, here are the EAGLE files. One of the smart-asses in the electronics class immediately dubbed it the "Ayrduino"...

Parts list:
  • ATmega328P-PU (1)
  • 16MHz crystal (1)
  • 22 pF cap, ceramic (2)
  • Button, momentary tactile switch (1)
  • Angled header, 6-pin male (1) 
  • 0.1µF cap, ceramic (5)
  • Red LED (1)
  • Green LED (1)
  • 1N4001 diode (1)
  • 2-position screw terminal (1)
  • 7805 regulator (1)
  • 10kΩ resistor (1)
  • 510Ω resistor (2)
  • 47µF Al. Elect. cap (2) (short ones to fit under shield boards)
  • Female headers, 8-pin (2) (optional)
  • Female headers, 6-pin (2) (optional)
  • 28-pin IC socket (1) OR 14-pin IC socket (2) (optional)
  • Three short jumper wires
  • Single-sided PC board, 0.032" 1/2oz Cu.
You can cut 11 of these from one 8x10 sheet of PC board if you do it just right.



April 30, 2013

Minecraft Ore-Block night-light


You can buy a minecraft ore-block night-light... but it's more fun to make your own, and this one is not just redstone. It cycles through the colors of redstone, emerald, lapis lazuli, iron, gold, and diamond. It also pulses slowly; just a subtle fading in and out. My son and my nephew both had birthdays this month; although they're past the age of needing nightlights they're both minecraft nuts so I decided to make these for them.

Let's start with the light. For the light source, I used a 10mm RGB LED from Adafruit. This common-anode RGB LED provides a nice bright color-space, and the diffused package mixes the light well. I first wrote a quick Arduino program to read three potentiometers and adjust the red, green, and blue levels according to those pots. The program would then send the actual RGB values back to the computer via the serial line. This allowed me to experiment with different light mixes in an effort to find the best RGB combination for each color. I could tweak each knob, see the results immediately, and when I found a combination I liked I could check the serial line to see what it was.

Here's the program, and here's what the test-rig looked like:


I eventually decided on these tuples for each type of ore:
Redstone (255,0,0)
Emerald (0,255,0)
Lapis Lazuli (0,0,255) --- those three are easy!
Iron (16,4,0) --- closest I could get to "brown" with the RGB!
Gold (255,115,0) --- maybe a bit less green?
Diamond (0,255,100) --- could've gone more blue, but this works.

These colors are hard-coded into the program, which was downloaded onto the microprocessor before soldering the microprocessor into the board. Here's the program.

Next, the electronics: I chose to use an ATtiny84 microprocessor to drive the light. The ATtiny84 has much more memory than necessary for this purpose, but I needed three separate PWM outputs to do the color mixing (so the ATtiny45 was out) and I didn't have any ATtiny44's handy. The board layout was fairly simple: I used EAGLE CAD, and here's the design:


The EAGLE files are available here. I created the board using toner-transfer and FeCl etching.


Next, it was time to make the physical ore-block. I used 1/4" clear acrylic, cut on my table saw. The sides are each 3" high by 2 7/8" wide, and the top is 2 3/4 x2 3/4. I then used a router table to cut a 1/8x1/8" shoulder-groove around each piece.
The side pieces then fit together, each overlapping the next. The top fit perfectly inside the recessed square formed by the sides. The bottom was left open for the moment, but if you're following along on visualizing how this goes together, you'll realize that there is a 2 3/4x2 3/4" recessed square hole there, too --- just the right size for the circuitboard.

Before gluing the pieces together, I sandblasted them ---both sides--- to make them better diffusers.
I then solvent-welded them together using methylene chloride. Plastic model glue would have worked nearly as well, but I work in a building with chemistry labs and fume hoods and solvent-welding acrylic works REALLY well. When finished, I had a nice translucent 3" cube of frosted acrylic, open on the bottom. I also drilled three holes near the bottom of one side of the block; holes that would later accommodate the buttons and power cord.

The outside pattern is key to making this a Minecraft block, of course! I created a single 3x3" side using a vector graphics program, then put five sides together so I could wrap them around the cube. The largest-format laser printer I have available will only print letter-sized paper, so I had to break the wrap into two pieces, like this:
The top piece wraps around three sides of the block, and the bottom folds over the top and fourth side. The extra on the sides wrap around to prevent light leakage around the edges. Here's a link to a .pdf of that design, should you want to make your own block.

To make the "stone" parts of the lamp light-proof I used 3M spray adhesive ("Super 77") to glue a print of this pattern onto a smooth piece of aluminum foil. Next, I carefully cut the pattern out using a sharp new X-Acto blade and a metal straightedge.
I then carefully creased this aluminum-foil/paper label on all fold lines, using the metal straightedge again. I sprayed the aluminum side with adhesive once more, and wrapped the label around the block.
The final assembly step was to provide a power source (salvaged 5V phone charger) and solder the power cord and buttons. I found two buttons that were nearly identical; one was momentary and the other latched. The latched button is used for power, the momentary button cycles through ore-type. The circuitboard fit (with a small amount of sanding) into the recess on the bottom of the cube: I glued it into place with RTV and added four stick-on rubber feet.


It works great, the boys think they are cool, and it's on to the next project: writing a final exam for my electronics course!

April 8, 2013

ISP Clip for ATtiny44/84 (or others!)

I got my start in microcontrollers with the Arduino, as many of us outside of electrical engineering did. (And still do!) The ease of programming that little board makes it a great gateway... and like any gateway, sometimes you go through.

Most of my projects now don't use Arduinos directly. For simple microcontroller applications, it's much more cost-effective to use a bare microcontroller selected for the memory size and pin-count you need to do the job. For me, that usually means either the 8-pin ATtiny45/85 or the 14-pin ATtiny44/84. Both can now be programmed directly using the Arduino IDE with either a commercial programmer or with an Arduino, as described on the excellent MIT High-Low Tech site.

One frustration with these smaller microprocessors, though, is that I either had to take them out of the circuit and wire up a breadboard as shown at MIT's site, or build a 6-pin ISP connector into my project. I built a 6-pin ISP-to-breadboard adapter assembly, which often helped during the prototyping process, but it was not ideal. What I really wanted was something that would clip directly to the chip and let me reprogram it without removing it from the breadboard or circuit.

It turns out the solution had been sitting in my toolbox for the last 15 years, I just didn't know it! Years ago, someone gave me a set of "DIP clips": they're a spring-loaded clip made by 3M that grabs a DIP chip from the top and provides easy contact points to each pin. They're still sold here and elsewhere. I glued a 6-pin ISP header on the side of one of these with wires from the ISP header to the appropriate pins on the clip, and voila! A ISP clip.

This one is for the ATtiny84 (or 44): I just plug my ISP programmer to the clip and put the clip on the ATtiny84: I can then test and debug the microcontroller while it's in the circuit —even if it's soldered into the circuit— without having to build an ISP header in the circuit. There's another 8-pin clip that does the same for me with the ATtiny85 (or 45).

New idea? No... Pretty? No... But it works nicely.

March 10, 2013

Random training interval timer

In addition to various things I'm supposed to do, I race triathlons. One of the training tools we use is the interval workout, in which we alternate high- and low-intensity time intervals during the course of a run or bike workout. There's been a bit of discussion during the Monday-Night run recently about whether it might be advantageous to train with randomized intervals instead of with set intervals.

A typical running interval workout might be a 20min warmup, 5 sets of 1min hard 3min recovery, then 20min cooldown. The idea is to replace the main set with 20 minutes of random intervals, during which the hard and recovery intervals vary randomly in length (within reasonable parameters, of course.)

Typical sports-watches have an interval feature that helps time regular intervals, but they don't do random intervals. Here's my solution: use an ATtiny45 to generate the random intervals, and indicate the intervals via a flashing LED.


And here's the code.

Programming of the ATtiny45 was done via the Arduino IDE: the fuses on the ATtiny45 are set to use the 1MHz internal oscillator. The circuit itself is simply power and ground to the chip (using a 1225 lithium battery) and an LED with current-limiting resistor on PB0 of the microcontroller.

June 18, 2012

Quantitative Two-Dimensional Temperature Measurements

Lab Experiments involving the Heat Equation are usually one-dimensional exercises involving a copper pipe and a half-dozen thermocouples. But with DS18B20 "One-Wire" thermometer chips and an Arduino, it's possible to measure hundreds of temperature values simultaneously. Here's what my students Daniel Lund and Lawrence Lechuga and I came up with for 2-D temperature measurements.

We began by laying out a 10x10 grid of sensor locations on a 30cm-square plate of 5mm-thick aluminum. We laid Kapton tape in strips under where the sensor leads would be located, to prevent the leads from shorting against the aluminum plate; then we glued each sensor to the plate using thermal epoxy.

Next, we temporarily attached each sensor to an Arduino microcontroller running FindAddress.ino. This program first determines how many devices are on One-Wire bus; then for each device, it sends the address of that device to the Arduino serial port. A terminal emulator on the attached computer displays those addresses. By running this program with the sensors attached individually, we could then determine the hard-coded addresses of each sensor. One hundred tests later, we had a complete list of sensor addresses, ordered by their physical position on the grid.

Once we knew the individual addresses and corresponding locations of the sensors, we permanently wired all the sensors to the Arduino. Power and ground are provided by the USB connection to the computer, and the data pins for each sensor are all connected via a single wire to one input pin of the Arduino. The data bus is also connected to power via a 1k pull-up resistor. (Note: the datasheet for the DS18B20 calls for a 4.7k pull-up resistor, but we found that with 100 sensors on a single bus a 1k pull-up resistor provided more reliable operation.) The Arduino itself is connected to the computer via a “FTDI Friend” USB-serial converter board.

The completed hardware (bottom side) can be seen below. The plastic stand-offs allow it to be placed flat on a table with the bare top side up.


The final step in construction is to program the Arduino to measure the temperatures and send those temperatures (in order of grid position) to the computer. With this many sensors we found that we were straining the capacity of the microcontroller: although the ATmega328 chip on the Arduino board has 32k of program space, it has only 2k of RAM. This RAM is used by the serial and One-Wire communications libraries as well as by our program, and when the RAM is full the Arduino behaves erratically. Our solution was to store the array of sensor addresses in the 1k array of EEPROM on the microcontroller. This required a second Arduino program (address_storage.ino) which was run once to store the sensor address array in EEPROM. Once that program did its job, we uploaded our final program, ThermoPlate.ino.

The ThermoPlate.ino program operates in two steps after the initialization procedures: first, it sends out a “broadcast” message on the One-Wire bus telling all sensors to record the current temperature. Next, it goes through all the sensor addresses stored in EEPROM. For each address it sends a temperature inquiry to that address, converts the sensor response to °C, and sends the temperature as text down the serial line to the computer. When the Arduino has gotten the temperature from each sensor it sends an EOL character to the serial port, then repeats the process. That’s the final output of the device: line after line of serial data, each line containing 100 temperatures in left-to-right, top-to-bottom order. With our 16-MHz Arduino, it takes just under 2 seconds to measure all points, with the limiting factor being the speed of the One-Wire bus itself.

The computer has to be able to listen to the apparatus and make sense of the incoming data. Since the incoming data is simply text, there is a wide range of possible tools to use for this purpose, ranging from LabVIEW to IDL to C++. For simplicity, we chose to write our program, TempMovie.py, in Python. This program captures each line of data coming in the serial port, splits the line into individual temperatures, rearranges those temperatures into a grid, and then draws a filled contour plot based on that grid data. One can set the temperature scale in the program to cover the expected range of values, and if desired the program will save the raw data for later analysis. The figure below shows a single frame of output of TempMovie.py when a small bag of ice was placed at the upper right and a hot soldering iron was placed near the center.


The image changes as the plate moves towards its new equilibrium state, and one can observe the heat flow in real time. For the sequence of images shown below, the plate was hit with a flame from a propane torch, which was removed after a few seconds. (Time in the video below is sped up by a factor of 4.) Time-dependent thermal data such as this can be compared to numeric solutions of the Heat Equation.

video 

Note: These temperature sensors can detect changes as small as 0.1°C. If you look closely at all of these images, you can see that an area near the lower left corner of the plate is about 0.3°C warmer than the rest of the plate, due to the power dissipation of the microcontroller.

This technique of using multiple DS18B20 sensors controlled by a single Arduino can be used for one-dimensional experiments as well. Twenty-five sensors, evenly spaced along a meter of copper pipe, would make a wonderful replacement for the typical half-dozen thermocouples we’ve all used and hated as undergrads!

The sensors can be ordered from Newark.com or Jameco.com. For our thermal epoxy we used "Arctic Silver Alumina" from Newegg.com.

May 16, 2012

Off-topic, but... AT&T sucks.

For the past several years we've gotten our internet through AT&T DSL. Unless you want to support Comcast with your money (and nobody with an interest in net neutrality does) AT&T DSL has been the only option in this town.

I got tired of slow network. Calling AT&T did no good, they claimed things were fine. So I measured the actual speed. Repeatedly!

It just happens that I have access to a pair of very nice servers at my work; I wrote a script on my home machine that downloaded a small file from one of them and recorded the download speed every 15 minutes. An identical script on the second server served as control: should the problem be the server rather than the DSL line, the second server would show it.

After sitting through more than a year of dreadful AT&T service, here are the results.

Notes:
  • Up through the end of April of this year, my actual download speed was at most HALF the advertized "up to" speed. For most of last year, I got a quarter of the advertised speed on average.
  • The jump in speed at the end corresponds to the date at which many of my neighbors gave up and got Comcast. Speeds after that point are still less than 2/3 the advertised "up to" speed.
  • The "control" server (graph not shown here) showed a flat constant speed of nearly 100 Mbps. In other words, the limiting factor was the transfer, not the source.
Conclusions: AT&T sucks, and we need for them to have some serious competition in this area.

They just switched me to "U-Verse" (still the same "up to 1.5 Mbps" speed) so we'll see if that's any improvement. I'm not holding my breath, and the script is still running.

Oh, and here's the code, which was executed every 15 minutes by cron.

#!/bin/bash

DATESTRING=`date "+%Y-%m-%dT%H:%M:%S%t"`
DOWNLOADSPEED=`curl -s -o /tmp/whatever -w '%{speed_download}' http://REDACTED/randomblock`
echo "$DATESTRING    $DOWNLOADSPEED" >> /REDACTED/speedresults.txt

rm /tmp/whatever




March 21, 2012

Driving multiple Sparkfun 7-segment displays with an Arduino

I'm currently helping a couple of engineering students finish a senior project that didn't get finished last year. Long story... Anyway, it's a bicycle brake tester being built for Paul Components. The mechanical design is great, but they had trouble with the electronics.

Part of those electronics involved writing numbers to a pair of Sparkfun 7-segment displays. There's a lot of discussion on the Sparkfun board about these: apparently they're difficult. I had some issues making them work ---baud rate, for example, which should be set to 9600 in setup() not 2400 as stated in some references--- but it's relatively straightforward once those issues are straightened out. Here's my code, in hopes that it'll be helpful to anyone else trying to write to several 7-segment displays simultaneously.

The serial TX line (second pin given in the SoftwareSerial declaration) should be connected to the RX pin on the corresponding Sparkfun breakout board; the RX line in the SoftwareSerial declaration should be left unconnected. I've only tested it with two boards at a time, but it should work with as many as you have room for on the Arduino. It works fine for just one display, also!