NMEA 0183 Speedometer

I had an email request to find this project from 2010… I updated the code too!

Arduino in Test Mode
Arduino in Test Mode

This project  takes the pulse from a paddlewheel boat speed sensor and makes an NMEA output on the serial port.  It should work with most through-hull speed transducers, and also with windspeed transducers too.  The NMEA stream comes from the arduino serial port, so if you have a USB arduino you can hook it up to a laptop easily.  If you want to hook it up to another NMEA instrument you’ll need something like a MAX232 chip to take the TTL logic from the serial port pins and convert them to RS-232 (or convert to RS-422 to meet the NMEA specification).

I used Valis’s NMEA monitor program (NavMonPC) to check out my output string.

The top picture is of the basic sensor in self-test mode.   The arduino makes a pulse for testing that should show 5.5 kts.  The yellow wire connects the pulse output to the pulse input to be measured.

Here is a screenshot of the output of the NMEA string received by hyperterminal.

Here is a screenshot of NavMonPC showing the display.

On power-up the microcontroller waits for a +++ sequence for a few seconds, if it receives it, it enters a calibration mode so you can change things like the filter pole and the number of pulses per mile.  You can also change these in the code itself.

To test the unit, I have it creating a pulse using the Tone() function.  If you wire the output pin to the input pin you should get around 6.3 knots.  The input would normally be connected to a signal that is either a TTL pulse signal (0-5 Volts square wave) or a switch connected to ground alternating between an open-circuit and shorted to ground.  Here’s a picture of the wiring:

Here’s the code  (updated Sept 2017 for modern arduino, tested on an Uno)

I tested it with a speed transducer my dad gave to me from his box of parts.  It’s from a raymarine st-50 system, the tag says Airmar Z092.

picture of transducer
Airmar Transducer

I put 13V to the red wire, ground from the arduino and my power supply to the bare wire, and connected the green wire to pin 3 THROUGH a 10K OHM RESISTOR.  The resistor is important– the atmel microcontroller has diode clamps to protect against over/under voltages but you need to limit the current so the diodes don’t blow up.  If your input is in the 0-5V range you don’t need the resistor.


2 thoughts on “NMEA 0183 Speedometer

  1. Simply amazing! Great instruction
    I pasted the code into a 5 dollar Arduino uno. Connected the output to my wifi multiplexer and the speed readings 6,3 knots show up in any ios/android app that supports the nmea sentence. Incredible
    My paddlewheel I believe is creating 1pulse per rotation. So I guess a bit of calibration is all it takes to transform my analog paddlewheel sensor to an nmea 183.
    I´ve been trying to figure out what code string to do some trial/error (See if the 6.3kts goes up/down when using the test signal). But I´m no code reader!! If you could point out for me would be great.
    First of all thanks for sharing this nice piece of work. We are tons of sailors out there with a blend of old and newer instruments that we would love to connect and combine the data, without getting ruined. Thanks
    Br Ebbe

    1. Thanks for your comment! There is a calibration routine, if you type +++ at the terminal window in the first 5 seconds after boot, it will walk you through changing the parameters. It’s a little awkward with the arduino terminal with its send button. If you don’t use this you can directly change the code.

      There are 2 constants in the code for the speed per pulse. If you double either you should get 12.6 kt with the test pulse. The first is how much distance the boat moves per pulse and the second is a fudge factor used in calculating speed.

      If you want to change the constants in the code look for the lines:

      #define DEFAULT_KMI_PER_PULSE (1./20000.) // nautical miles per pulse (Airmar says 1/20e3)
      #define DEFAULT_SPEED_SCALE 1.00 // scale factor for calibration. (multiplies kmi_per_pulse)

Leave a Reply

Your email address will not be published. Required fields are marked *