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.


12 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)

  2. Like your take on repurposing a depth sounder transducer. I bought a yacht in which the head unit was broke to this will give be an opportunity to get a display in the cockpit. Nice.

    Have you considered running the code on an ESP-32? Its faster and has embedded bluetooth and wifi.

    1. This code should work on an ESP board. The EEPROM read/write and pin change interrupt code would be slightly different however. And if you wanted to use bluetooth or wifi you would need to add that code. I have used ESP8266 boards for several projects and think it is a fine idea if you wanted to extend the basic functions in this project.

  3. Thanks so much for your great article. This is my first arduino project and I was able to get the sketch compiled and uploaded but I’ve got too issues.

    1) I keep getting a bad data from EEPROM message on init

    2) I’m able to see the data on the serial montior and hyperterminal but unable to get the data on NavMon

    Any advice is greatly appreciated. I’m currently using the jumper from 10 to 3 until the paddlewheel arrives.


    1. #2 Issue resolve by going to File -> connections -> serial port and setting to correct com port and hitting the connect at the bottom of the screen. Somehow I missed the connect option earlier. Thanks!

      1. Glad you figured out the NavMon settings. The eeprom message will be there until you run through the calibration steps, it uses default settings when there are none saved in eeprom. To go into the calibration routine, type “+++” within the first 5 seconds of startup. Then follow the prompts. Using a real terminal program rather than the arduino serial monitor will make this easier but it can be done either way. Some options are here: https://learn.sparkfun.com/tutorials/terminal-basics/all

        1. Thanks for quick response. I’ve gotten through the calibration and no more bad eeprom. I’m trying to test with a Airmar ST650 speed sensor that has three wires, Blue, Black and Shield. I’m powering the uno r3 through usb and have tried connecting the wires in all the ways I can think but still getting no response. I should mention I’m a complete novice in arduino and only understand the basics of electronics. Any thoughts?

    1. A reseller (https://maxmarineelectronics.com/product/datamarine-astx-20bth-31-279-1-51-speed-insert-only-3-wire-st650/) says maybe blue=12V (usually red); shield=ground (both power supply ground and arduino ground); black=signal to arduino. Don’t forget the 10k resistor on the arduino pin when running more than 5V into it. If you accidentally put 12V into the arduino anywhere you may have burned it out (sometimes just that pin dies, sometimes the whole chip) so be careful. I don’t know if this is correct.

      1. Thanks so much for your comment. I’ve verified that pin 3 is still operational with the jumper wire to pin 10. Great feature you added there! I’ve also verified that the paddlewheel oscillates voltage on 90 degree turn 5 another 90 degree 0 but still get 0 for speed in hyperterminal and serial monitor. Not sure where to go from here. Thanks again for all of your help, code and inspiration!

  4. I’ve discovered using a multimeter that the output of the sensor, the link you showed is the exact one, alternates between 0.3 and 0 which is not enough to trigger a signal on the arduino. I’m thinking it is either a bad sensor or you would have to amplify somehow to trigger a high signal. Thanks again for your code and thoughts!

Leave a Reply

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