I know what I want the position display to look like and how it should behave (see ‘Steampunk Features Part 1’). Now I need to figure out the components I need to drive the mechanical counters.
- 1 controller – read position from GPS, control mechanical display
- 1 GPS receiver – get position from satellites, send data to controller
- 4 stepper motors and controllers – control position of display
- Voltage Regulator – convert 12V from trailer supply to 5V for electronic
- Power off storage for position data – write position to non-volatile memory
My first choice is something in the Arduino family, something like the ProMini/ATMega 328. Arduinos are small, stable, cheap, easy to use, and I have a few ProMinis laying around the workbench. The constraint will probably be the number of I/O pins available to get data from the GPS and drive the stepper motors. Most Arduinos have 14 digital I/O and 8 analog input pins – some have more I/O available but the price goes up.
A little background on input/output (I/O) Feel free to skip down to ‘GPS Receiver’ if you’re not interested or are familiar with the subject…
‘I/O pins’ are connection points on the controller chip.
Digital I/O pins either provide 0V or 5V (output) or detect 0V or 5V (input). You can turn an LED on or off from the program running in the Arduino (output), or detect if a switch is open or closed (input). You write a program to turn an LED connected to pin 2 on when a button connected to pin 3 is pressed.
Some Arduino digital I/O pins can be configured to output a PWM (pulse width modulation) signal – a fast on/off signal. You can control the on/off ratio from your Arduino program. PWM signals can be used to do things like drive a servo motor to a position or light an LED so it appears to be dimmed.
An analog input pin reads the voltage provided to the pin (usually 0V to +5V) and converts the analog voltage to a number the Arduino program can use. You could hook up a potentiometer to analog input 1, and read the value in the Arduino program. Combined with an LED connected to a PWM output, you can use the potentiometer to control the brightness of the LED.
Arduino programs are written in ‘C’, using either the Arduino programming environment or a programming environment provided by AVR, the maker of the ATMega processors most Arduinos use. The Arduino environment is a easier to use; the AVR environment gives you more control over the chip and usually makes code that takes less space.
I’ll show examples of the code for driving the display in the next installment of this project when I start writing the code to drive the hardware.
Because Arduinos are open source, there are a lot of Arduino and Arduino compatible devices available; I should be able to find something suitable.
Arduinos aren’t super fast and don’t have a lot of memory available, but for slow updates from the GPS receiver and driving some stepper motors. I don’t need a lot of processing power.
This is the part I know the least about from an interface standpoint. The Ardiuno Playground has examples of interfacing Arduinos to GPS modules. Turns out all GPS modules output position information in NMEA (National Marine Electronics Association) format over a serial connection. It’s text, so it will have to be parsed to get at the info I’m interested in; fortunately for me there are a variety of libraries available to parse the format. An advantage here is I can get NMEA format data samples and feed them to the controller over serial I/O from a computer, so I can test my hardware and software without committing to a specific GPS module.
Serial I/O over requires use of the TX/RX pins (digital pins 0 and 1 on the Arduino), so these will have to be disconnected when I flash the chip and I lose 2 of my precious I/O pins.
Stepper motors are handy – unlike standard DC motors, they move a precise distance either clockwise or counterclockwise depending on the input signals you send them. Perfect for this project where I need to drive the lowest displayed digit in the counter a specific amount based on input from the GPS. Stepper motors are used in a lot of devices, so they’re readily available and pretty cheap.
A servo motor works similar to a stepper – for less than a full rotation anyway. Servos (at least the low cost hobby servos I’d use) only provide 180 or 270 degrees of travel. To control the counter, I need the drive motor to have unlimited rotation in either direction. So steppers it is.
I picked up some small stepper motors and control boards for another project that got superseded (like all my other projects since last summer) by the teardrop build. I think they were used by a project I saw in Make. No surprise, there are libraries available to drive these from an Arduino. Each of the driver boards has 4 digital inputs. For 4 motors (1 each for latitude, longitude, elevation, and distance) I’ll need 16 outputs. With 12 pins left after the serial I/O pins are taken out, I’m 4 short.
These motors have 4096 steps per revolution. 1 step will be considerably less than the accuracy of the GPS (1.5 inches per step for the odometer, 0.01 seconds of latitude or longitude).
The teardrop has 12VDC available; all the hardware for this project takes 5VDC or 3.3VDC. Arduinos usually have a RAW voltage input to an on-board regulator that supplies 5V or 3.3V to the rest of the circuit, but with motors I’d like to have a regulator off-board for noise isolation and current capacity. Regulators are easy, but I need to remember this for the final build.
Power off position storage
The controller either needs to zero the displays every time it powers up, or it needs to keep the values in non-volatile memory that isn’t erased when the controller powers down. Zeroing the display adds complexity to the mechanical side – I’d need to add a reset mechanism to the counters, plus a motor (or motors) to drive the resets. Not impossible, but doing it in software is easier. I’ve never worried about this before – either the data I needed was stored elsewhere (in a standalone real time clock chip for the LED clock, for example) or I didn’t care about keeping values around after the chip powers off (devices that can start for an unknown state). Once again, Arduino site to the rescue. I can store the values to EEPROM using the EEPROM library. There’s not a lot of EEPROM memory available (1K for the 328 on the ProMini) but I don’t need much – 4 x 4 byte floating point values only takes 16 bytes. Microcontroller programming is definitely a different world than my usual Windows applications environment where I’ve got essentially unlimited memory available….
Somewhere this device will mess up somehow and the display will get out of sync with reality – missed steps, rounding errors are two problems I can think of and I’m sure there are others. Since we aren’t using it for anything critical like navigating to the campsite, it’s not a big deal and I’m certainly not going to try to debug hardware while we’re camping! But it would be handy to have a reset button to zero the stored position information without reflashing the controller, even if I have to manually reset the counters. 1 more I/O pin.
It would also be handy to have the TX/RX for the GPS unit on different pins than the USB programming interface so I can reflash if I need to without disconnecting anything.
Other others? I can’t think of any at the moment, but I’d like to have a couple more I/O pins ready in case feature creep sets in somewhere. But no worries, that never happens!
The I/O problem
Arduino (most, anyway) have 14 digital outputs.
The steampunk position display needs at least 19 for
- serial I/O to GPS (2)
- 4 stepper motors (16)
- reset button (1)
- Moved TX/RX (2)
- Reserve? (1 or 2)
So I need 21 (or more) of the 14 available digital pins… There are a few ways to solve this problem
- Pick a different controller. There are some Arduinos with more digital I/O pins – from 20 up to somewhere in the 50 range. Boards are bigger and cost more.
- Use a port expander shield like the Mux Shield from Sparkfun. This would work – it allows up to 48 I/O pins. But since Arduino shields are designed for the form factor of the original Arduino package I couldn’t mount it directly to a ProMini. Also, I don’t need that many ports and I only really need a few input pins (stepper motor controls are output only), so I’m spending money for a lot of features I don’t want or need on a board that is awkward to connect to my ProMini.
- Since most of what I need is output only, I can use a couple of 74HC595 shift registers (same as on the Mux Shield) to control the stepper motors while using only 3 of the pins on the Arduino. These chips are under $1 each, and I have a few around from prior projects.
Option 3 is the winner. Shift registers are pretty easy – three digital pins on the Arduino can control several shift registers, each of which has 8 (or more) digital outputs. And there are plenty of examples of interfacing Arduinos to shift registers.
A little background on shift registers. Feel free to skip to ‘Conclusion’ if you’re not interested or are familiar with the subject…
Shift registers take 3 inputs – serial in, clock, and latch. The serial in and clock define the pattern of bits being sent to the shift register – each time the clock changes state (0V to 5V; 5V to 0V), the state of the serial line defines a bit (0V for off, 5V for on).
As you define the bit pattern with serial in and clock, the shift register stores the values in an output register, 1 bit per output pin. Changing the state of the latch (high to low or low to high, I don’t remember offhand) moves the values from the register to the output pins – bits set to 1 have 5V on the pin, bits set to 0 supply 0V.
Multiple shift registers can be chained together, so 3 output pins on the Arduino can control dozens of outputs.
Now I know what the hardware will look like, and the libraries I need to use to get data from the GPS, store values to EEPROM, and send data to the shift registers. Time to start prototyping!