I'm astounded that some cars don't have a digital compass always visible. You either have to launch the navigation app each time which may even disappear when you adjust the radio. In this project, you'll create a digital compass that can be powered by by the cigarette lighter or another source (batteries make it handheld). You could buy one, but where's the fun in that?
You'll use an awesome OLED screen (with amazing viewing angles), a magnetomter, and Arduino (with a zombie apocalypse mode Easter Egg) to create this cool gadget. If you just want to see the code, I have it in a Gist: Compass.ino. I put it in a Gist so that other people can make edits and improvements to it.
Step 1: Gather the Parts and Tools
Arduino Pro Mini 328 - 3.3V/8MHz I got the 3.3v version for simplicity of connecting it to the other 3.3v parts (Sparkfun).
SparkFun Triple Axis Magnetometer Breakout - HMC5883L This compass breakout can be mounted in any orientation (Sparkfun).
SparkFun Micro OLED Breakout This is the screen form the MicroView, but the Arduino + Screen is cheaper than the MicroView and its programmer (Sparkfun).
Protoboard It doesn't matter what you use, but this is what I got (Sparkfun).
Power Source I just cut the end off a 30-pin 5v car charger that I had. It was useless and lying around. The Arduino can handle an input from 3.3v to 12v DC.
Thin wire You'll need this to make jumper connections on the perfboard. My was about 24 AUG. I used both stranded and solid wire for different parts.
- Headers This will make it easy to attach the components to the protoboard.
- Why no accelerometer? An accelerometer would allow for automatic adjustment of orientation and declination angle, but this is mostly intended to be a more permanent thing, and you can learn about how the declination angle works.
- Wire cutters They must be capable of cutting the size wire that you have
- Metal file These are for making notches in the perfboard
- Sandpaper I used both 110 and 200 grit to clean the hole in the case.
- Another Arduino with USB You'll use this to program the non-USB arduino. I used my Arduino Mega 2560.
- Logic Level Converters If your other Arduino with serial over USB is 5v, then you'll need this to bring its serial voltage down to 3.3v for the Pro Mini (Sparkfun, Adafruit).
Breadboard This for prototyping everything originally and testing it out.
Soldering Iron and solder
Solder wick and/or solder sucker I prefer the wick, but you'll probably need one or the other.
Step 2: Solder the Headers!
The first thing that needs to be done is solder the headers to the components. I would suggest putting the headers and the module in a breadboard while soldering to keep them perfectly aligned. However, be sure not to apply too much heat for too long or you could melt your breadboard.
A good solder joint will create a cone around the pin and a circle around to hole, has no gold from the board showing, and prevents the pin from moving. Press the iron and the fluxed solder near the bottom of the pin. If you're getting clear/yellowish flux everywhere, then your soldering iron isn't hot enough. In the case of non-adjustable ones, you probably just need to wait a little longer for it to heat up. Keep your area well ventilated.
You'll need 12 on either side of the Arduino Pro Mini. Solder from underneath with the long end down (long end and black strip are not on the size with the button). Now you need to solder the I2C lines. They are inconveniently placed in the middle of the board. Solder about two inches of wire to all four pins. We'll only need A4 and A5, but the other will help if you decide to do something else later (in my pictures I didn't realize this and had to balance the wires in the holes while testing on the breadboard).
Next solder all the headers to your Logic Level Converters.
Don't solder headers to the compass module! I wanted my screen to sit in the top center of the board, and the only way to do this without putting anything on the other side was to stick it on somewhere else where the pins don't lines up. Instead, solder a very small amount of jumper wire to the top of it. About an inch will do. Cover the bottom of the breakout board with electrical tape to make a small space in between the two boards when they site on top of one another. You could also use double sided tape. My picture has headers on it while testing because I didn't see the problem yet. I desoldered them later.
Now, on the screen board, solder headers, with the long part and black strip facing down, to the row with the square GND on it. I would also recommend soldering one header at one edge of the other row for stability and to help secure it to the protoboard (I didn't realize this until mounting it permanently, so it's not in the picture). On the other side we'll need clearance for the screw hole. I would not recommend soldering right under the screen's fragile connector for risk of damaging it.
You're now ready to put it on a breadboard and test it!
Step 3: Test It!
Place your components into the breadboard. as shown in the pictures. Next, place a jumper wire between the reset and ground pins on your other Arduino. This will prevent it from getting programmed as well as the Pro Mini.
Let's get the Logic Level Convert set up. On the HV side, plug in ground from the bigger Arduino to GND, 5V to HV, RX to B1 (RX0 or the Mega), and TX to B2 (TX0 on the Mega). On the other LV side, connect GND to your ground rail. Now connect a GND pin to the ground rail. I don't have a rail to use as VCC, so I just connected LV to the VCC pin row on the breadboard on the Pro Mini. Now connect A1 to RXI and A2 to TXO. In the next step, you'll test the Blink sketch. You can jump to that now and come back to the rest of this afterwards if you would like.
We're going to connect the "RAW" pin of the Pro mini directly to 5V on the other Arduino. This will give it power. We already have ground hooked up through the Logic Level Converter, so don't worry about that.
Now for the screen. We'll be connecting it with SPI because it's faster than I2C, and then we only have to deal with the sensor using I2C. Connect GND to the ground rail. Connect VDD to VCC on the Pro Mini (or your rail if you have one). Jumper D1 and D2 together. Connect D1 or D2 to pin 11 (it doesn't matter since they're connected). Connect D0 (SCK) to pin 13. Connect D/C to pin 8. Connect RST to pin 9. Finally, connect CS to pin 10. After you test the blink sketch, you can also test the Sparkfun OLED library example demo if you've installed it all.
Lastly, let's hook up the magentometer. Remember, mine has headers instead of wire since I didn't realize what I needed to do. Connect GND to your ground rail and VCC to VCC (or your rail). Now connect SDA to A4 (one of the ones in the middle) and SCL to A5. You can now test the magnetometer.
Step 4: Program It!
Made sure that you've installed the latest version of the Arduino IDE for your platform.
Next, you'll need to install two libraries. Go to Sketch > Include Library > Manage Libraries. To install a library, select it in the list and an install button will appear.
First, search for "Cardinal" by DaAwesomeP. This is my library that allows you to convert the degrees of rotation to directions of different precisions. More information here.
Next, install the Sparkfun Micro OLED Breakout Library. You can't install this from the Library Manager! You need the latest version (which doesn't have a release yet) that include the extra large font. You can get the ZIP from here. Now open src/SFE_MicroOLED.cpp and uncomment line 46. This will enable the large font. This library is what will drive the screen. You can test out the examples later (they're pretty cool).
Be sure that you've ground the reset pin on your other Arduino! Now go to Tools > Board and select "Arduino Pro or Pro Mini." Then, go to Tools > Processor and select "ATmega328 (3.3V, 8 MHz)." Lastly, plug in the other Arduino (with everything hooked up) go to Tools > Port and select where your other Arduino is plugged in to.
First, start with the Blink sketch. Go to File > Examples > 01.Basics > Blink. Click Upload. As soon as it is done compiling and says "Uploading..." press the reset button on the Pro Mini. You will have about a 1 second window of time to do this. If you miss it and the TX/RX lights on your other Arduino blink every second and aren't always on, then just press the upload button again and try again. If it still gives you an error, then unplug and plug back in the Arduino and try once more.
Now that you know how to program it, you can also test the OLED examples. They're pretty cool.
Finally, let's upload the compass code. I've made a Gist of it here that you can copy and paste from. Create a new sketch and paste it in.
Don't click upload yet! Read through the file! You'll see several options that you need to set and instructions on how to do that. You'll need to set your precision type and declination angle to test it initially. After you have it soldered to the protoboard and you know how you will mount it, then you can adjust the floating X, floating Y, the screen flip, and rotation offset. You shouldn't need to touch the precision of Pi. Now you can upload.
Congratulations! You have a compass!
I invite you to read through the rest of the code and see how it works.
Step 5: Find a Power Supply!
This was an old 30-pin charger. I tested it to make sure that it still worked, and my multimeter read 5V DC. Perfect!. I clipped the end off to reveal a red wire (the positive wire) surrounded by bare shielding (ground). I separated them and later tinned them before soldering.
If you can't find a 5 volt power supply, then anything from 3.3v to 12v DC will do (the Arduino can handle anything in that range). However, if you use batteries (3 AA or AAA would work), then you don't get the bonus of it turning on and off with the car and an unlimited power supply.
Worried that you'll run down your car battery? Well, that's not really how it works. A car battery is designed much differently than a standard rechargeable battery. It has a big burst of power to start the car and then slowly builds it back up as you drive. Also, this is a miniscule amount of power.
Step 6: Solder the Protoboard
Do a dry placement test simply placing everything on the board. Now flip it over and figure out how you're going to solder everything. It's OK if the screen is upside down. There's a setting to fix that in the sketch.
I originally wanted to make "traces" with the solder, but I couldn't get the solder to stick very well in between the squares. So, I just had to use wire for all of it. My sketch on graph paper below had the traces incorporated, but just ignore them. All of it is wire now. After you solder each thing, test with a multimeter's continuity test to make sure that you bridged nothing.
Remember how we didn't put headers on the magnetometer board? Well, now you have some options. You could place it next to the Arduino where it will stick out a tad and could require more cuts for your case, or you could just stick it somewhere else in your case. That's what I did. If this will be in a hot card in the sun, then be weary of melting the adhesive on double sided tape. Screws and nuts probably won't melt unless your car can get that close to the sun, but you'd have other problems to worry about than your DIY compass at that point.
I used the top layer as a ground plain by putting a piece of bare wire through and soldering it on both sides. I had to bend it over on the ground plain side.
Wait until the next step to solder the power source.
Still need to program it? No worries! Slot some wire in the TX, RX, VCC, and GND holes over the side of the perfboard. I then used an alligator clip (you could also use some wire wrapped around it) to get at the RAW pin. Never program it while plugged into both power sources (the other Arduino and your other car power source). It's best just to use the Arduino for power completely when programming it to ensure that you don't mess up accidentally.
Step 7: Enclose It!
After you've tested all your connections and powered it up, it's time to enclose it.
I found this little thing at Fry's. I had to cut little notches in the side of my perfboard with a file to get it to fit, but it was great. It was the perfect size and shape to be a pager or car radar sensor as well, so if you find a screen that will fit, you could make a pager too (if you find that stylish at all). BEEP. It came with some little contacts for an AA battery, but you won't need those.
You'll also need to bend out the large and tall spacer for the battery. Bend it back and forth with a pliers until it starts to snap off. You'll also need to bend out the little support
Before you solder your power source to the board, drill a hole for the wire and route it through.
Now, what about the screen? Does a square object fit through a round hole? Yes, if the object is smaller than the hole. I made a hole with a paddle bit in the middle of the case (with a piece of wood under it for support). You can make the hole bigger or smaller than the screen. If it's bigger, then cover the edges with electrical tape. I stuck another piece to the sticky side of the electrical tape to make the exposed part not sticky.
Step 8: Mount It in the Car!
You're done! Have fun with your little compass.
If you saw the Zombie Mode in the code, then you should probably know that this has no capability of detecting zombies. It's just a cool Easter Egg to make other people in the car laugh.