Arduino NMEA GPS replacement for paddle wheel transducer -not NMEA2000

Arduino NMEA GPS code to replace paddle wheel transducer uses GPS module TTL to RS232 converter, all code and wiring included.

  • While it is all in the code, the kind of pseudocode is:
  • Read GPS output at 9600 baud (that is the GPS default)
  • Get rid of everything except $GNVTG sentence
  • Convert $GNVTG sentences into valid $SDVHW,0.0,T,0.0,M,0.95,N,0.0,K*7E sentence (the SD seems to be something Garmin MAY want)
  • create and add a checksum in after the conversion
  • add the carriage return and line feed (yeah, totally weird eh)
  • send it out of the Arduino as TTL (0 to +5v) at 4800 baud (4800 is what Garmin wants)
  • convert the TTL signal to RS232 (invert and change the voltage level) became NMEA0183 is not TTL, but RS232.
  • read “water speed” on Garmin.

A high percentage of this code probably came from someone else. I do not know how to write code, but I can sometimes paste things together that work. Even if the code shown here did not come from one of the sources below, I most likely learned how to make it work with help from them. My apologies to anyone I missed. Please make use of anything you see here, but do not count on good coding practice as I have just done what was needed to make it work. But it does work, unless otherwise noted. Thanks to everyone who has shared their knowledge and good luck to those who are learning. https://www.jarutex.com/index.php/2021/12/19/8868/ https://www.arduino.cc/ https://www.sparkfun.com/ https://randomnerdtutorials.com/ https://youtu.be/3BWSSpcn95A https://stackoverflow.com/ https://youtu.be/684KSAvYbw4 https://exploreembedded.com/ https://www.youtube.com/watch?v=JmvMvIphMnY&t https://prosperityconsulting.com

Hardware-wise, I am using a buck regulator to take the 12 volt (nominal) boat power down to +5 volts for the cards. I may just use a 7808 if I ever try to produce this for sale, as it will be cheaper, and I am not concerned about the small loss of efficiency in power transformation from 12 to 5 volts. This can be as high as 14.7 while being charged

I currently have it running on a

  • Nano but it was prototyped on a Uno,
  • using a Beitian BN-220 Dual GPS Module TTL Level 9600bps + GPS Passive Antenna and a
  • MAX3232 RS232 to TTL Serial Port Converter Module DB9 Connector.
  • and the buck DC to DC converter.

I got the .MAX3232 RS232 to TTL Serial Port Converter Module DB9 Connector. from a Canadian guy on ebay https://www.ebay.ca/usr/phillipjfry78?_trksid=p2047675.l2559 . I didn[t need the DB9 connector but after getting a bunch of bad Max3232 chips on Amazon, I did not want to wait a month for my order from China.

I got the Nano on Amazon.ca (pack of 5 for $20 ) The UNO came from Alibaba years ago. And misc. Parts came from AliExpress.

softwareserrial.H is needed to get a separate “input” port (from the GPS) and a separate “output” (to the chart plotter). This also allows me to have a different baud rate going in and a different one going out. Kind of miraculous in itself.

our Gemini Let’s look at the code for a Arduino NMEA0183 GPS to Paddle wheel converter.

crappy code by me
*good code, concepts, inspiration and ideas by:
*http://www.holdentechnology.com/2017/09/02/nmea-0183-speedometer/, https://www.sparkfun.com/tutorial/BeginningEmbedded/ATmega8-RS232.pdf
*http://picprojects.org.uk/projects/simpleSIO/SimpleRS232.pdf , https://create.arduino.cc/projecthub/hwhardsoft/how-to-use-nmea-0183-with-arduino-6e3988
*groundFungus, and a few others who deserve credit but I did not capture there names in time.

This worked on an Uno card, I will likely move it to a nano or pro-mini (as I have some). You can copy the code just as it is but omit the [code language=”cpp”] and the [/code] at the end. I will update this as the project progresses.

Overall, the idea is to see if I can replace the through hull paddle wheel with a GPS speed over ground single. And I also hope this gets my “true wind” to work on the RayMarine Axiom and wind gauge (IT DOES !!) Arduino NMEA0183 GPS to Paddle wheel converter

arduino nmea gps


[code language="cpp"]
/*
  parse nmea sentences from GPS and output to MNEA RS232 device. updated 5:48
  What it does. 
  reads nmea signel from a gps then strips out everythng but the VHW sentence then strips everything from that except the speed in knots, then it adds a checksum. 
  as of now I do not have it actually feeding the onboard electronics, but I have checked the sentences here >> http://freenmea.net/decoder  and the checksums all check out.
	 RX is digital pin 9 (connect to TX of other device)
   TX is digital pin 8 (connect to RX of other device)
   reads serial data to com port at 9600 and software serial port is also set at 9600
   *crappy code by me
   *good code, concepts, inspiration and ideas by:
   *http://www.holdentechnology.com/2017/09/02/nmea-0183-speedometer/,  https://www.sparkfun.com/tutorial/BeginningEmbedded/ATmega8-RS232.pdf
   *http://picprojects.org.uk/projects/simpleSIO/SimpleRS232.pdf , https://create.arduino.cc/projecthub/hwhardsoft/how-to-use-nmea-0183-with-arduino-6e3988
   *groundFungus,  and a few others who deserve credit but I did not capture there names in time. 
   *
   */
#include <SoftwareSerial.h>
String ReadString;
SoftwareSerial Serial1(9, 8); // RX, TX
char* nmeaData = "$--VHW,0.0,T,0.0,M,20.36,N,0.0,K";
int nmea0183_checksum(char* nmea_data)
{
	int crc = 0;
	int i;
	for (i = 1; i < strlen(nmea_data); i++)
	{
		crc ^= nmea_data[i];
	}
	return crc;
}                                        // =============== End nmea0183_checksum routine   
  
void setup()
{
	
	// Open HARDWARE (usb and pins 1 and 2) serial communications and wait for port to open:
	//set speed of hardware port below
	Serial.begin(4800);  // speed of HARDWARE port
	while (!Serial)
	{
		; // wait for serial port to connect. Needed for native USB port only
	}
		Serial.println("Goodnight moon!");
			// set the data rate for the SoftwareSerial port
	Serial1.begin(9600);  //dw THIS IS SOFTWARE SERIAL, pins 8tx and 9Rx 

}
void loop()
{
	
	ReadString = Serial1.readStringUntil(13);   //NMEA data ends with 'return' character, which is ascii(13)
	ReadString.trim();        // they say NMEA data starts with "$", but the Arduino doesn't think so.
	
	if (ReadString.startsWith("$GNVTG"))
	{ 
     //This section gets repeated for each delimeted bit of data by looking for the commas
	 //DW   begin routine to find next comma and remove all charactors before it. 
		int Pos = ReadString.indexOf(',');   //look for comma delimetrer
		ReadString.remove(0, Pos + 1); // Remove Pos+1 characters starting at index=0, 
	 	Pos = ReadString.indexOf(','); //looks for next comma delimetrer, which is now the first comma 
		 //DW   begin routine to find next comma and remove all charactors before it. 
		int Pos2 = ReadString.indexOf(',');   //look for comma delimetrer
		ReadString.remove(0, Pos2 + 1); // Remove Pos+1 characters starting at index=0, 
		Pos2 = ReadString.indexOf(','); //looks for next comma delimetrer, 
     	 //DW   begin routine to find next comma and remove all charactors before it. 
		int Pos3 = ReadString.indexOf(',');   //look for comma delimetrer
		ReadString.remove(0, Pos3 + 1); // Remove Pos+1 characters starting at index=0, 
		Pos3 = ReadString.indexOf(','); //looks for next comma delimetrer, which is now the first comma 
	 	 //DW   begin routine to find next comma and remove all charactors before it. 
		int Pos4 = ReadString.indexOf(',');   //look for comma delimetrer
		ReadString.remove(0, Pos4 + 1); // Remove Pos+1 characters starting at index=0, 
		Pos4 = ReadString.indexOf(','); //looks for next comma delimetrer, which is now the first comma 
	 	 //DW   begin routine to find next comma and remove all charactors before it. 
		int Pos5 = ReadString.indexOf(',');   //look for comma delimetrer
		ReadString.remove(0, Pos5 + 1); // Remove Pos+1 characters starting at index=0, 
	 	Pos5 = ReadString.indexOf(','); //looks for next comma delimetrer, which is now the first comma 

		 //DW   END routine to find next comma and remove all charactors before it.
		 // 
		// DW remove charctors after the ground speed or isolate the ground speed as a variable.
		String grdSpd;
		grdSpd = ReadString;
			int DecPos = grdSpd.indexOf('.');   //  look for the decimal point
		grdSpd.remove(4);
		
		// DW insert the GPS speed into a VHW sentence
		String VHW;
		String Stringone = "";
			//String VHW1 = "$--VHW,0.0,T,0.0,M,";
     // String VHW1 = "$VWVHW,0.0,T,0.0,M,";
     String VHW1 = "$SDVHW,0.0,T,0.0,M,";
			String VHW2 = ",N,0.0,K";
			String VHW3 = "0D 0A";  // Add carrage return and line feed in HEX)
			VHW = String(VHW1 + grdSpd + VHW2);
	// dw it is good till here,  I now have to add the checksum to the end of this
		//	Serial.print(" the String variable VHW           >");
		//	Serial.println(VHW);
		//	 Serial.println("dw it is good till here,  I now have to add the checksum to the end of this");
	// dw add the checksum in HEX  to the end of the string. first add "*" then HEX	
			  // change data type so it will work in the function.
		char vhwArray[50];  // make a char array so create array name 
		VHW.toCharArray(vhwArray, 50);
		/*
		Serial.print(" print VHW  after the array was made   >");
			Serial.println(VHW);
		// finished creating array 

	
			Serial.print("print the array  vhwArray          >");
		Serial.println(vhwArray);
		Serial.print(" print VHW  after the array was made   >");
		Serial.println(VHW);
		Serial.print("print the checksum from the fuction    >");
		Serial.println(nmea0183_checksum(vhwArray), HEX);
		*/
								
		String hexVar = String(nmea0183_checksum(vhwArray), HEX); 
		hexVar.toUpperCase();
	//	Serial.print("Create a variable for the HEX checksum and print it here     >");
	//	Serial.println(hexVar);


		//  Now combeine the string and the hex number with a "*" between them.
		String withHex = "";
	//	VHW.concat(hexVar);
	//	withHex = VHW + '*' + hexVar + " " + VHW3;  // ALSO added the carrage retrun and line feed 
	//	withHex = VHW + '*' + hexVar + '\r'+'\n';  // ALSO added the carrage retrun and line feed  '\r' '\n'
		withHex = VHW + '*' + hexVar + "<CR><LF>";  //  <CR><LF>
	//	Serial.print(" the variable one more    >");
		Serial.println(withHex);

		

		
		//---------------DW see if we can add a CRC checksum
		
							
	}  // exists before checksum routine 
}  // exists before checksum routine 

[/code]

Loading

Please share it. Thanks!