Rasberry Pi NMEA

KAM

Well-Known Member
Joined
6 Jun 2005
Messages
1,356
Visit site
Storm bound at the moment so fiddling about with the new raspberry pi. Got the compass working but I now need to get an NMEA output. Just looking for a rough HDG so I can get wind direction. It's possible but I got lost in geek land trying to find the best approach. Has anyone done it or can anyone point me in the right direction.
 
Storm bound at the moment so fiddling about with the new raspberry pi. Got the compass working but I now need to get an NMEA output. Just looking for a rough HDG so I can get wind direction. It's possible but I got lost in geek land trying to find the best approach. Has anyone done it or can anyone point me in the right direction.

Can you get hdg into it? If so how?

Otherwise once you have the hdg data you simply configure a com port and send it in the form $--HDG,x.x,y.y,a,z.z,b*hh<CR><LF>

where x.x is the heading in decimal degrees, y.y is deviation and z.z is variation,

a and b are both E or W

you can often ignore the checksum hh but not a good idea and some gear may not display the heading if there isn't one; you need the CR LF to terminate the sentence.

HCHDG needs to be in uppercase and you need ALL the comma separators and the decimal points.

How you string the sentence (as ASCII characters / codes) together will depend on what programming language you are using.
 
Last edited:
The heading is coming from an hmc5883 compass module. So far I have a Python program giving me a bearing from that.
 
The heading is coming from an hmc5883 compass module. So far I have a Python program giving me a bearing from that.

I've never used Python so can't off much more help but presumably you can use the print command to send data to a serial port, once you have configured the baud, stop, start & parity.

Read the number representing the heading into a array so you can access the individual digits which you then can send as the ASCII representation.

EG print "$HCHDG,";X1;X2;X3;".";X4;",,,,,E","CR LF" [ the semicolons are used to separate the literal parts from the data obtained from the array]

X1 to 4 are the hundreds, tens, units and tenths which are stored in the array at the locations 1 to 4 (often the order is reversed and the first position is reserved for the number of elements so you may need to use 5 4 3 .2 )

My programming skills are minimal so hopefully someone will come along with a better example.
 
Storm bound at the moment so fiddling about with the new raspberry pi. Got the compass working but I now need to get an NMEA output. Just looking for a rough HDG so I can get wind direction. It's possible but I got lost in geek land trying to find the best approach. Has anyone done it or can anyone point me in the right direction.

You will need a line driver - a chip that converts the Pi's data line voltage to the voltage of the NMEA-0183 signal. NMEA-0183 has specified RS422 line voltages for a while now, but it used to be RS232 levels. All NMEA-0183 receiving equipment must be able to accept either, so it doesn't matter which you use.
 
You will need a line driver - a chip that converts the Pi's data line voltage to the voltage of the NMEA-0183 signal. NMEA-0183 has specified RS422 line voltages for a while now, but it used to be RS232 levels. All NMEA-0183 receiving equipment must be able to accept either, so it doesn't matter which you use.


He won't need this if he's driving the embedded serial to wifi module directly.

If the Pi runs on 3.3v then an ADM3202 or equivalent from Rs or Farnell will do the job if he needs nmea signal compatibility. (which he will do if he uses one of your multiplexers or the cased wifi module)
 
I thought it might be possible with a USB to RS485 adapter (99p off ebay) using the pyserial package in Python.
 
I assume (correct me if I'm wrong, but this seems from a bit of googling how it tends to be done) that you're reading the compass over i2C.

There are two possible questions here. One is how to format data for output, the other is how to physically output said data. You may already have a fair idea of either of these, so forgive me if I address things you already know the answer to.

The canonical reference for nmea-0183 if you don't want to pay for the nmea spec or pirate it, is Eric Raymond's "NMEA Revealed" document:
http://www.catb.org/gpsd/NMEA.html
This gives you the details behind what ianj99 posts. I definitely would bother with adding in the checksum. It's simple to do:
http://en.wikipedia.org/wiki/NMEA_0183#C_implementation_of_checksum_generation
I don't do python but I believe string literals are the same in python as C, so lines should be terminated "\r\n" (as you probably already know).
You can output HDM sentences with just magnetic heading, but for HDG you'd need deviation and variation. At the simplest level you could get your program to state zero deviation for all headings and use a fixed value for variation, ideally passed in as a parameter to the program at startup or hardcoded if you must. In v.2.0 you can plan to read changes in variation from proprietary sentences you send it, calculate from a world magnetic map or whatever, but start simple :-). The talker id of "HC" which ianj99 suggests is for a magnetic compass, so seems a fair choice.

If you want to output data onto a serial line, whilst my unix/linux serial programming experience is C, not python, I believe the python class libraries make this straight forward:
http://pyserial.sourceforge.net
8 bits, 1 stop bit no parity, 4800 baud is probably what you want.

If you want to skip mucking about with serial lines directly in your program you might try wrapping the invocation of your program in a subshell which first calls stty to set the baud rate (and 8n1 if you don't want to trust that the device is set to default) then write to stdout but redirect output to the required serial device.

For serial output you have a couple of obvious choices. If you've happily wired up the input you should be happy to use the onboard uart for output as AngusMcDoon is suggesting. First stop the kernel using the serial port for output and stop linux spawning a getty:
http://elinux.org/RPi_Serial_Connection#Preventing_Linux_using_the_serial_port. Plenty of folks have written up using the serial port on the pi: google is your friend. In implementing what AngusMcDoon mentions I've copied others in using a max3232 and 5 capacitors. According to this you can buy something to make this trivial:
http://www.davidhunt.ie/add-a-9-pin-serial-port-to-your-raspberry-pi-in-10-minutes/
You can obviously also use usb to serial converters. Hacking udev rules is useful to pin a name to a device or port if you switch your usb devices about regularly. As well as usb to rs232 devices you can also get usb to rs422. I believe cardo uses one. I've got one which I played with but haven't been using on a regular basis.

If you want to start multiplexing data to the network or sharing it with other programs I'm obviously going to direct you to kplex, but you don't need that if you just want to output a single stream to a serial device.
 
Last edited:
Will you be using an accelerometer package to get pitch and roll so you can correct the compass for inclination? If intending to use on a boat, will you be adding gyro sensors to help give more stable measurements in a dynamic situation?
 
Thanks for the info so far. Yes using I2C. Its going to take a few hours to read up on what Laika has posted. I assumed RS422 and 485 are interchangeable. I have not bothered with the accels or gyros as its a simple learning project but thought it may be a way to get a heading when at anchor so that Seawi can SMS me with the wind speed and direction when I am away from the boat.
 
Thanks for the info so far. Yes using I2C. Its going to take a few hours to read up on what Laika has posted. I assumed RS422 and 485 are interchangeable. I have not bothered with the accels or gyros as its a simple learning project but thought it may be a way to get a heading when at anchor so that Seawi can SMS me with the wind speed and direction when I am away from the boat.

RS-485 is different. Multiple devices connect to the same data lines, rather like Seatalk or the CAN of NMEA-2000, and software is needed to manage when collisions occur. I'm not aware of RS-485 being used in marine electronics.
 
Thanks for the info so far. I have not bothered with the accels or gyros as its a simple learning project but thought it may be a way to get a heading when at anchor so that Seawi can SMS me with the wind speed and direction when I am away from the boat.

What a shame! I have a set of bits on the shelf waiting for me to figure out how to do that - I was hoping I would be able to copy! If you search around on some of the sensor suppliers sites, there is some information on the theory of hard and soft iron corrections, in 2D and 3D, and some of the integrated magnetometer/accelerometer/gyro packages are beginning to acquire software libraries that can be used with Arduino & RPi
 
The heading is coming from an hmc5883 compass module.

Hmm....So I'm probably a bit slow but I've only just realised what the possibilities are here. The specs on that module say a max rate of 116Hz. I'm no i2C expert but a quick look at the specs suggests that wouldn't be a bottleneck. Which means that that module could act as a fast heading sensor, especially combined with processing which rgarside is talking about.

When I was doing a bit of investigation for a friend who has radar but no fast heading sensor and no plans to upgrade his autopilot, appropriate sensors were many hundreds of pounds.

Am I missing something or is this a great marpa project for those with older autopilots?
 
As an example the Invensense MP U 9150 chip puts the sensors together, and there are some libraries out there that claim to do some of the sums. I'm not sure how the libraries handle calibration and delivery of live heading information, but there is obviously some code around to build on. I would think that there must be some of the UAV autopilot people who have sorted this out already.
 
RS-485 is different. Multiple devices connect to the same data lines, rather like Seatalk or the CAN of NMEA-2000, and software is needed to manage when collisions occur. I'm not aware of RS-485 being used in marine electronics.

I think any NMEA gear with + and - outputs is based on RS485 but not fully implemented - just electrically. Certainly my Airmar heading/gps sensor has differential outputs and these work perfectly connected to the RS485 inputs on the serial to wifi interface, and will work on any nmea device with + - inputs.

Actisense interfaces also have differential outputs and inputs and many devices have + - inputs which can also be used with single ended signals by grounding the -ve input.

So Kam will be okay to use a USB (PI) to 485 adaptor - it will connect straight to the serial - wifi's 485 input.

Also, does NMEA 0183 v4 not specify differential connections? (although not RS485).
 
Last edited:
I think any NMEA gear with + and - outputs is based on RS485 but not fully implemented - just electrically. Certainly my Airmar heading/gps sensor has differential outputs and these work perfectly connected to the RS485 inputs on the serial to wifi interface, and will work on any nmea device with + - inputs.

Actisense interfaces also have differential outputs and inputs and many devices have + - inputs which can also be used with single ended signals by grounding the -ve input.

So Kam will be okay to use a USB (PI) to 485 adaptor - it will connect straight to the serial - wifi's 485 input.

Also, does NMEA 0183 v4 not specify differential connections? (although not RS485).

NMEA-0183 is never multidrop which is what RS-485 specifies. It is also not RS-anything, but says that it uses the differential voltage levels of RS-422 in later standards. This is what the + and - data lines are.
 
If I ever got it to work I was planning to connect to the NMEA input of my Raymarine seatalk converter box. But this also has an RS232 input so maybe it would be better to use a USB to rs232 converter.

Thinking to the future how about an autopilot. It ought to be possible to use some cheap drone electronics combined with a low cost 12v linear actuator. There are some quite powerful and fast (claimed IP65) units available for solar trackers which would do the job.
 
If I ever got it to work I was planning to connect to the NMEA input of my Raymarine seatalk converter box. But this also has an RS232 input so maybe it would be better to use a USB to rs232 converter.

There are loads of max3232-based ttl to rs232 converters on ebay well under a fiver (although I bought the components separately and probably more expensively so can't comment on any one in particular). I'd be tempted to use one of those attached to the onboard uart and leave usb out of the picture: keeps your usb ports free and in any case I've found the pi's usb to be not hugely dependable.
 
Top