GPS distance measurement between two coordinates using Arduino

I knew the dimension of the LCD (Nokia 5110) as 43mm x 43mm but it looked smaller than I thought.  That’s good because I want to put it on top of the GPS (Holux M-1000).

In my previous post, I explained how to get coordinates, date & time, speed, and bearing data from GPS, Holux M-1000.  Now that I have the LCD, it’s time to add two parts to the Arduino sketch: 1) LCD driver/display, 2) distance calculation between two locations.

1. LCD Driver

First of all, I searched for a simple and small library for the LCD, Nokia 5110. There were a few different libraries for this LCD: Adafruit’s, Sparkfun’s, and Henning Karlsen’s.  Among these libraries, I chose Henning Karlsen’s because I needed only simple text display with a couple of different font sizes.  Henning Karlsen has separate library for graphics as well.  I would like to thank Henning for his sharing his nice work on the library.  Henning’s library supports 3 different font sizes: SmallFont (text and number, 6×8), MediumNumber (number only, 12×16), and BigNumber (number only, 14x 24).  Only downside of this library is that the Medium and Big fonts do not support texts but only numbers. However I would need only numbers to display with bigger fonts, this limitation was no problem with me.

2. Distance calculation between two locations

There are number of websites showing how to calculate distance between two locations from latitudes and longitudes. Movable Type Scripts shows various  calculations of distance, bearing and other useful conversions using Haversine formula and BlueMM posted the Excel formula to calculate distance which is basically the same way as Haversine.

The calculation is quite straightforward but I found there was a problem: Arduino (Atmega328p) cannot handle over 6-7th decimal digits which is very important in trigonometric calculation for short distance.

Arduino reference page says “Floats have only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point. Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float.”

Let me give you an example.  Suppose we started from a position A (lat: 40.00, long: 80) to a position B (lat: 40.01, long: 80.00). That is, we moved 0.01 degrees in latitude only. If you calculate the distance using Haversine formula on your PC, you will get about 1,111.9m. However, Arduino calculates it as 3,110.8m. Big error!  More interesting thing is that even if you reduce the latitude difference to 0.001 or 0.0001 degrees, you get the same results, 3,110.8m. So I investigate further what exactly cause this error. Of course I know the culprit is the float precision limitation as said above. But I wanted to know which part of the calculation by Arduino cause this big error. In the Haversine formula, there are COS, SIN and ACOS functions used.  I tested a few different calculations using these functions and found the calculation of COS and SIN functions affect minimal but the problem was the ACOS.  If you calculate the formula on your PC only inside of ACOS bracket, you will get 0.9999999848. See my point? The decimal places below 6th in ACOS function is actually important to calculate the angular difference for small distance, but unfortunately Arduino cannot handle this.  Not only for small distance but for even relatively long distance (say over 1 degree for instance) there is error between the results on the PC and Arduino.

Well, so I started thinking about how to avoid trigonometric function calculation when over 6th decimal places are important. And I found a solution! Instead of calculating angular difference between two positions and THEN calculating the distance by multiplying the mean earth radius, calculating a ratio of angle between two positions (latitude and longitude separately) over 360 degrees and divide the circumference of the earth by this ratio. In other words, keep the numbers big while calculation. Arduino’s float type has a limitation on the small decimal places, but can handle relatively big numbers!

Here is my formula:

The mean circumference of the earth is 2 x 6,371,000m x π = 40,030,170m

Δd (lat) = 40,030,170 x ΔΘ (lat) / 360 (assuming ΔΘ is small)

Δd(long) = 40,030,170 x ΔΘ(long) x cosΘm / 360 (Θm: mean latitude between two positions)

Now, the distance is √[Δd (lat)^2 + Δd (long)^2]

Below is the test Arduino sketch to test my formula.  The result is 11.029m while Haversine formula for the same coordinates gives 11.119m.  This is close enough considering the accuracy of the most GPS is bigger than one meter.

float gpsLat0 = 40.0;
float gpsLat = 40.0001;
float gpsLong0 = 80.0;
float gpsLong = 80.0;

void setup()
float delLat = abs(gpsLat0-gpsLat)*111194.9;
float delLong = 111194.9*abs(gpsLong0-gpsLong)*cos(radians((gpsLat0+gpsLat)/2));
float distance = sqrt(pow(delLat,2)+pow(delLong,2));

void loop()

To be continued….


Wii Nunchuck hack: making an electronic level with Arduino compatible JeonLab mini v1.3

I have posted a project on using the accelerometer chip in the broken Wii Nunchuck. It was broken: the joystick did’t work. However, the accelerometer chip in the Nunchuck was intact and it also has the I2C interface which can be easily communicate with Arduino (or compatible board) with the Wire.h library.

I have seen those applications on iPod touch or Android tablets that can be used as a level using their built-in accelerometer sensor chip with a nice graphic showing bubble level.  I thought I could make one like that with the Wii Nunchuck and started building one.  I had bought a Wii Nunchuck from ebay to replace my kids’ broken Nunchuck for less than $10 (I don’t remember exactly) and I thought it was much cheaper to buy them than to buy the accelerometer with I2C interface or breakout boards so I bought a couple more at that time.

The joystick and the PCB look like this.
Wii Nunchuck PCB-Joystick

I don’t need the (broken) joystick part, so I cut off that part.
Accelerometer part of the Wii Nunchuck PCB top
The accelerometer chip (A7260) is shown.

The I2C converter is at the bottom of the PCB.
Accelerometer part of the Wii Nunchuck PCB bottom

Now I need a case for this project and found perfect size clear acrylic case from my junk box. I don’t even remember where I got it.
Clear case
Clear case width
Clear case height

The width inside of the case was almost perfect for the JeonLab mini v1.3. I had to file off about half mm of the PCB. I also thought to use a 3.0V CR123A battery for this project.
JeonLab mini v1.3 in clear case with CR123A

But later I changed the power supply to a 3.3V regulated with a 12V A23 battery for better stability.

The cut PCB from the Nunchuck was glued on top of the ATmega328P chip on the JeonLab mini v1.3.
Wii Nunchuck PCB on JeonLab mini v1.3 in case

The I2C wires, clock and data, are connected to the analog pin 5 and 4 on the JeonLab mini v1.3, respectively.
I2C wiring between Wii Nunchuck PCB and JeonLab mini v1.3

I also connected the power for the Nunchuck board to the JeonLab mini v1.3 board as shown below, but this was my mistake.
Power sharing between Wii and JeonLab mini

The power supply I thought was 3.0V battery, so I thought sharing the power should be fine. BUT I forgot the program upload through the FTDI. The accelerometer chip and the I2C interface need 3.3V (3.0-3.6V) and the ATmega328 on the JeonLab mini v1.3 (and other Arduino compatible boards as well) can work 3-5V. The Nunchuck data reading header, nunchuck_funcs.h (from WiiChuckDemo by Tod E. Kurt) provides the settings for utilizing the analog pins 3 and 2 as power source for the Nunchuck board but this provides 5V, not 3.3V. The problem is that 5V supply to the Nunchuck board could damage the chip(s) either the accelerometer or the I2C chip or both. Actually, the first one I used had been unstable and noisy, so it had to be replaced with a new one. That’s when I decided to change the power source from the 3V battery to 12V battery with a 3.3V regulator and added a Schottky diode (1N5819) to protect the Nunchuck board from FTDI 5V supply.

Now, let me explain the design. Using the accelerometer sensor on the Nunchuck board, it detects which side is tilted and send the 3 axis data to the Arduino program loaded JeonLab mini board through the I2C protocol. The program compares the current data to the stored (in EEPROM of the ATmega328P) calibration data. There are three stages of displaying: 1) If the value is within certain range, it will turn on the central red LED connected to the digital pin 7; 2) If the value is greater than the range (sens in the program) and less than 2 times of the range (sens), it will turn on the red LED and one green LED at the opposite (in order to simulate the bubble direction) side of the tilt; 3) If the value is greater than 2 times of the range (sens), then only the green LED is turned on.

The calibration values are the neutral value of each axis reading when it is leveled on that axis. For example, the Nunchuck data reading is between 60-70 (these values are different from sensor to sensor) at -g (upside down) on that axis and is over 170 at g (up right). So the neutral (leveled) value of each axis is about 120-130. The calibration begins when the pin 10 goes HIGH by connected to V+ with a small push button switch pressed. One the calibration process begins, in order to give the user some time to put the device down on a flat surface, it waits until the central red LED blinks a few times. The actual calibration is done really quickly and followed by a few quicker blinks.

Here is the whole program.

 * Wii_Nunchuck_Level
 * Feb-Mar 2012, Jinseok Jeon
 * Wii Nunchuck data read:
 *  nunchuck_funcs.h from WiiChuckDemo by Tod E. Kurt, 

#include "nunchuck_funcs.h"

byte accl[3]; //accelerometer readings for x, y, z axis
int calPin = 10; //calibration pin
int sens = 1; //sensitivity
int orient;

void setup()
  for (int i=5;i<10;i++) { 
    pinMode(i, OUTPUT);
  } //9 left, 8 up, 7 center, 6 down, 5 right
  pinMode(calPin, INPUT);

void loop()
  //if the calibration pin is pressed, jump to funcion calibrate()
  if (digitalRead(calPin) == HIGH) calibrate();

  if (orient == 1 || orient == 2) {
    if (abs(accl[0] + orient*10))  sens) digitalWrite(5, HIGH);
    if ( + orient*10)-accl[0] > sens) digitalWrite(9, HIGH);
  if (orient == 3 || orient == 4) {
    if (abs(accl[1] + orient*10))  sens) digitalWrite(8, HIGH);
    if ( + orient*10)-accl[1] > sens) digitalWrite(6, HIGH);
  if (orient == 5 || orient == 6) {
    if (abs(accl[0] + orient*10)) <= 2*sens && abs(accl[1] + orient*10))  sens) digitalWrite(5, HIGH);
    if ( + orient*10)-accl[0] > sens) digitalWrite(9, HIGH);
    if (accl[1] + orient*10) > sens) digitalWrite(8, HIGH);
    if ( + orient*10)-accl[1] > sens) digitalWrite(6, HIGH);

  for (int i=5;i<10;i++) { //turn off all LEDs
    digitalWrite(i, LOW);

void getData()
  accl[0] = nunchuck_accelx();
  accl[1] = nunchuck_accely();
  accl[2] = nunchuck_accelz();

  orient = orientation(); //get orientation

void calibrate()
  for (int i=0;i<3;i++) {
    digitalWrite(7, HIGH);
    digitalWrite(7, LOW); 


  for (int i=0;i<3;i++) {
    EEPROM.write(i + orient*10, accl[i]);

  for (int i=0;i 125 && accl[0]  110 && accl[2]  170) orient = 1; //bottom on floor
    else if (accl[1]  110 && accl[1]  110 && accl[2]  180) orient = 3; //left on floor
    else if (accl[0]  110 && accl[1]  125 && accl[0]  170) orient = 5; //back on floor
    else if (accl[2] < 80) orient = 6; //front on floor
  return orient;

Some pictures below show the assembling procedure of the LEDs and the tiny switch from a broken camera. Here I want to give all of you a note: don’t throw away any broken electronics. Because they don’t work doesn’t mean they are garbage. There are a lot of good parts you can use for other projects.

Bubble LEDs
assembled bubble LEDs and resistors
assembled JeonLabmini v1.3 - Wii Nunchuck - bubble LEDs

The tiny switch found from a broken camera.
micro switch for calibration

A 10k resistor is used to pull down the pin 10 and this tiny switch is connected to the pin 10 and V+ to trigger the calibration.
Calibration switch connection

Now these are the parts for the power supply. There are a piece of prototype board, a Schottky diode (from a broken power adapter), 0.1uF ceramic capacitor, a 10uF electrolyte capacitor, 12V A23 battery, 3.3V regulator LD33V, and battery contacts also found from the broken camera.
Power supply parts
Battery contacts from broken camera

The battery contacts were modified a little bit and soldered on the board. The regulator doesn’t need the big heat sink so the metal part was cut on top and soldered on the board and it also form a perfect battery holder.
battery holder with 3.3V regulator

This is assembled power supply in the case.
power supply with rearragned caps

Fully assembled Wii Nunchuck Level:
Completed Wii Nunchuck Level top

When it is leveled:
Wii Nunchuck Level leveled

When it is tiled to left:
Wii Nunchuck Level tilted left

When it is tilted to right:
Wii Nunchuck Level tilted right

And here is the Youtube video showing how it works.

TV-B-Gone_JeonLab power source

As same as Adafruit’s original TV-B-Gone kit, my modified TV-B-Gone_JeonLab accepts any DC power source within 3-5V. The micro-controller, ATtiny85V, runs within 1.8-5.5V, but the IR LEDs consumes more power than the micro-controller, you need to keep the source voltage at least 3V.

Adafruit includes 2 AA battery holder in their kit, but I will not include any battery holder or connector in my kit in order to give more flexibility of choice of power source.  As long as the voltage of the source is within 3-5.5V, any battery or supercap can be used.  For example, 2-3 AA or AAA alkaline batteries, 3-4 rechargeable batteries like NiCd or NiMH, Li-ion (or Li-PO) rechargeable batteries or 2 of 2.5V (0r 2.7V) supercap (at least 10F).

As I mentioned a few times before, I like supercaps. Even though they can not hold much charge compared to batteries, they can be charged quickly (less than a minute) through USB or 5V wall adapter and small and light.  So I decided to attach two supercaps to my TV-B-Gone_JeonLab, but I wanted to compare the sizes of 4 and 2 AA battery holder and AAA batteries.

TV-B-Gone_JeonLab size_4AA

TV-B-Gone_JeonLab size_2AA

TV-B-Gone_JeonLab size 3AAA & 1A

The actual size of my modified PCB is slightly smaller than Adafruit’s which fits nicely at the back of 2 AA battery holder. Anyway, I figured someone would be interested in having supercaps as a power source and here is how I did.

First thing I did was to attach a male header a guide (plastic piece on one side) for assuring correct polarity of connection.

connector male header

But this one was too tall compared to the other components.
connector male header before cut

So I cut the plastic guide and pins a little bit.
connector male header after cut

Using a small piece of double sided tap with foam two supercaps (2.5V, 10F) were attached to the bottom of the PCB and soldered in series together.
TV-B-Gone_JeonLab supercap soldered

TV-B-Gone_JeonLab sideview with supercap

In order for ensuring the supercaps in place securely, a thin cable tie was used.
TV-B-Gone_JeonLab top view cable tied

TV-B-Gone_JeonLab cable tied bottom

Now it’s time to make the USB cable connector. I cut one of those USB cable found from my junk box.
USB cable wires

And attached female connector to the red (+) and black (-) wires of the USB cable.
USB cable power wires red and black

female connector before finishing

When you insert those spring pins in the connector housing, make sure the stopper to be inserted all the way in until it makes click sound (blue arrows in the picture below).
female connector assembled_click

Finished with a heat shrink tube.
female connector shrink tubed

Charging from my laptop computer.
TV-B-Gone_JeonLab with supercap USB charging

Look how small it is in my hand.
TV-B-Gone_JeonLab size in hand

And it works!!
TV-B-Gone_JeonLab_supercap in hand

With one full charge (about one minute), I could turn one of my TVs on and off more than 40 times from about 6.5m (21 feet) away. Of course I used STOP button right after it turned on (or off) the TV. It does save power!

If you want to buy the kit (without supercap or battery holder), PCB, or firmware loaded ATtiny85V or any combination, email me for a quote.

Finally “TV-B-Gone JeonLab mod” is assembled!

Finally, the PCBs (revised) I ordered for the TV-B-Gone JeonLab mod have arrived. It’s always exciting to see actually fabricated PCBs I designed. It was not an exception this time. As I mentioned before, I made a couple of mistakes and had to order the revised one. Which means that the new PCB itself doesn’t look different from the faulty one, but it did look different. Funny.

For those who don’t have a clue what I’m talking about, please take look at my previous post.

Anyway, I quickly started making one and wanted to share the procedure and brief test results.

Here is the look of the PCB.
TV-B-Gone_JeonLab_PCB top-bottom

As you may have noticed from above picture of the PCB, it is “universal” version meaning it has a region (NA-North American models, EU-European models) selection switch.

First thing I did was to solder a 8-DIP socket for the ATtiny85V chip.
8DIP socket on TV-B-Gone Jeonlab PCB

The ATtiny85V chip is flashed with my modification from the Adafruit’s firmware v1.2 as below.

// exit do loop if REGIONSWITCH is pressed
 if ((region == US && !(PINB & _BV(REGIONSWITCH)))
|| (region == EU && (PINB & _BV(REGIONSWITCH)))) break;// delay 100 milliseconds before transmitting next POWER code (it was 250ms, but found 100ms works fine and faster)

Before assembling it fully, in order to check whether or not the ATtiny85V chip was flashed correctly, the indicator LED (green or red, I chose green), an 8MHz ceramic resonator, and a 1k ohm resistor for the LED were soldered first.  With my favorite power source (two 10F super-caps, 5V, USB charged), I checked the LED was blinking as below and it worked fine.
assembling TV-B-Gone_JeonLab: ATtiny85V and indicator LED check

Some photos after fully assembled:
assembled TV-B-Gone_JeonLab 1

assembled TV-B-Gone_JeonLab

components of TV-B-Gone_JeonLab

Further test results and assembly instruction will be posted soon.

If you want to buy the PCB, the ATtiny85V with JeonLab mod firmware, or a full kit, email me.


TV-B-Gone mod for battery saving and region/range selection

TV-B-Gone is a small gadget that can turn on and off virtually any TV in the world developed and sold as a kit by Adafruit. They also provide the source code and compiled firmware under Creative Common Share Alike license.
I would like to thank original developers at Adafruit for this great work and sharing ideas.

At first, I downloaded the firmware v1.1 and flashed an ATtiny85-20 and made it with only one transistor and two wide angle IR LEDs with two supercaps as shown below. The switch is connected to the supercap + so it will beam only when you press the button.
simple TV-B-Gone with supercaps

It worked fine, but the problem was it drained the supercaps too quickly.  The first reason is, of course, low capacity (compared to batteries) of the supercaps, but there are other reasons, too. I didn’t have a resonator at 8MHz, so I burned the oscillator selection  fuse bit of the ATtiny85-20 as internal 8MHz.  The internal oscillator has benefits of omitting an external component and programmable, but there are serious down side; its frequency can be unstable and varies depending on the temperature and power supply, AND it consumes more power at high frequency settings.

I also tried v1.2 on a tiny bread board as shown below.

TV-B-Gone on breadboard

I haven’t taken a picture, but on the breadboard shown above, I added a 8MHz ceramic resonator and uploaded v1.2 firmware on an ATtiny85V-10 and found it can last double the time. One full cycle of pulsing all the codes takes a little less than a minute and with this latest testing configuration, more than 30 times of full cycle worked with 2 supercaps before the voltage dropped below 1.7V (two in series).

I have thought about to turn off the device before the full cycle finished. I thought about to add a power switch but that wasn’t very attractive to me.

A couple days ago, I suddenly got a good idea to utilize the Region Detection pin6. Once the program detects the region from the level of pin 6 (float (internal pull-up): US, pull-down: EU), it is not used until all the code pulsing is finished. So, in US mode for example, after it started pulsing and when you want to stop it, forcing the pin6 to ground will exit the do loop  in software and the device will go sleep. I tested both US and EU mode with modified code and worked fine. This way, you can save battery.

Here is the schematic for the US version. I also added a slide switch to select IR LEDs between 2 wide but short ones and 1 narrow but long beam LED.

TV-B-Gone JeonLab Mod-US

And EU version:

TV-B-Gone JeonLab Mod-EU

If you want to have both in hand like me, you can use following design with a DPDT slide switch to change region.

TV-B-Gone JeonLab Mod-Uni

More updates will be followed.

If you want to buy an ATtiny85v-10 chip with this modified firmware loaded, send me an email with your location.  It will be $5.00 + shipping.

The full kit will be ready soon, too.


Toy Laser Gun

I found a pistol shape broken RC car remote from my son’s toy box one day and got an idea to modify it into a toy laser gun. I also had a cheap laser pointer. I regret for forgetting to take pictures of all intermediate procedure.

Here is the picture of the modified toy laser gun.
Toy Laser Gun all

As you can see, the antenna was removed and an aluminum tube (about a half inch OD) as a barrel was added. The laser diode assembly and the triggering circuit and two supercaps for power supply are all integrated inside the handle as shown in the picture below.
Toy Laser Gun inside circuit

The laser diode for a laser pointer needs about 3-5VDC, so my idea was to provide 5V to the laser from two supercap (10F, 2.7V) in series and charge the supercaps through USB female connector.  You can fully charge them from a computer USB port in 20-30 seconds (not minutes or hours!).  Of course the supercap’s capacity is much smaller than other rechargeable batteries, but it can hold sufficient amount for playing with your kids for long enough with one charge. I made a circuit to supply only a short pulse of power to the laser when it is triggered by a tactile switch attached behind the yellow trigger.

Here is the circuit diagram I made.
Laser gun circuit

As explained, there is a USB connector and two supercaps are connected directly to the +5V and GND pins of the USB connector so that they can be charged whenever you plug it in to any USB port of a PC or a wall wart USB charger. In the diagram, I added a power switch, but I didn’t actually use it because it could charge so fast that you don’t have to try to save power when it is not used.  And in fact, even if you cut the power line to avoid discharging by the circuit, you cannot completely prevent discharging 100%. You may have experienced with old flash lights.

Let me talk about how it works.

  • First of all, if the supercaps are charged (and power switch is closed), the capacitor C3 (electrolyte capacitor, 470uF, 6.3V) is instantly charged because it is connected to the supercaps through the normal close pin of a small relay, K1 (5V).
  • When the trigger switch is closed, the relay, K1, is activated and the charge from the capacitor, C3, discharges to the laser.  You can change the length of the laser pulse by changing the capacitor, C3, e.g. 200uF for shorter pulse or bigger ones for longer pulse.
  • Once you release the trigger, the relay will be deactivated and the capacitor, C3, is charged again.

It’s simple but solid way to generate a laser pulse, isn’t it?

For more detail pictures, visit my Flickr Photoset .

The target is relatively simple. I googled an image for a shooting target and used a cardboard box as shown below.
Toy Laser Gun target

Inside the target box, there are a power switch at the top left corner; a piezo buzzer at the top center; a CdS to receive laser beam (a red plastic (taken from a push switch 🙂 at the center of the target (see above picture) is used to filter only (mostly) the red laser beam); a circuit board for switching the buzzer triggered by the CdS; and 5) two D battery holder in the picture below.
Toy Laser Gun target inside

And the circuit diagram of the target is here.
Laser gun target circuit

The circuit is very simple. A general purpose NPN transistor, 2N3904, works as a switch. Two batteries (3V) power the whole circuit. If the laser hit the center of the target, the CdS cell will decrease its resistance and the base current of the transistor will be increased. As a result, the transistor will be ON and the buzzer will set off.  That’s it.

You can find more detail pictures from my Flickr Photoset