 |
07-06-2012, 07:09
|
#1
|
Registered User
Join Date: Aug 2010
Posts: 298
|
NMEA Electronic Compass
Just to share a compass project I started.
Based on the article about the $25 gyro compass I started looking for something similar for nmea based systems. After some research I popped onto this site Build Your Own Solid State Compass for $60 | MatrixMariner This compass is actually only demonstrated in a flat situation.
As a start I ordered the Arduino Uno and the HMC6352. Since this whole system was new to me, I searched for software to re-use to created nmea-strings as output. The first result can been seen here: Arduino Uno met Kompas - YouTube While investigating the Arduino system, I discovered that next to a 'regular' 2 axes compass, you actually need a three axes compass for tilt compensation, and the HMC6352 is some what unstable. I therefor changed to LSM303
Changed to code to make use of this module. As per example the output from the module is:
Quote:
$HCHDG,309.00,,,,*78
$HCHDG,311.00,,,,*71
$HCHDG,310.00,,,,*70
$HCHDG,311.00,,,,*71
$HCHDG,311.00,,,,*71
$HCHDG,310.00,,,,*70
$HCHDG,310.00,,,,*70
$HCHDG,311.00,,,,*71
$HCHDG,310.00,,,,*70
$HCHDG,309.00,,,,*78
$HCHDG,311.00,,,,*71
$HCHDG,312.00,,,,*72
$HCHDG,311.00,,,,*71
$HCHDG,311.00,,,,*71
$HCHDG,310.00,,,,*70
$HCHDG,311.00,,,,*71
|
Since the output is kind of fluctuating, I first started to use a moving average filter, however this didn't work out (358, 358, 359, 0, 0, 359, 358, 0) --> 224gr. Not very accurate. If you, like me, search the various fora, you'll find the Kalman as suggested solution to reduce the noise from the compass. Since I'm not a programmer, I have a hard time to get this filter into de lSM303-library. Coding is done in C++
If you have any question or suggestion, please feel free. I'll do my utmost to answer questions.
Tags: Arduino Uno, Digital compass, LSM303, NMEA
|
|
|
07-06-2012, 08:05
|
#2
|
Moderator Emeritus

Join Date: Sep 2007
Location: Eastern Tennessee
Boat: Research vessel for a university, retired now.
Posts: 10,406
|
Re: NMEA electronic compass
How much do fluxgates engineered for use on boats with a NMEA output typically cost? I am wondering how much of a cost savings there might be with a DIY fluxgate. It might be a great thing!
It seems the headings cannot be filtered too much because the lag would frustrate the helmsman and prevent the autopilot from functioning very well. The closer to real time, the better a helmsman functions.  This would be especially true if the NMEA refresh rate is set on the slow side.
__________________
David
Life begins where land ends.
|
|
|
07-06-2012, 08:15
|
#3
|
Registered User
Join Date: Aug 2010
Posts: 298
|
Re: NMEA electronic compass
David,
A simrad compass would cost about 600€. A diy about 70€, ex time investment.
Agree that it should not be too low in responsiveness.
|
|
|
13-06-2012, 07:46
|
#4
|
Registered User
Join Date: Jan 2012
Posts: 23
|
Re: NMEA electronic compass
this project may have solved the issue already - Google "B-CALMXP"
|
|
|
13-06-2012, 08:02
|
#5
|
Moderator Emeritus

Join Date: Sep 2006
Posts: 4,666
|
Re: NMEA electronic compass
While I agree that the compass response should be as quick as practical, you can still do accurate filtering. To compensate for the 360 <--> 0 transitions, use the difference between the current filtered value and the new sample point and optionally add or subtract 360 from the new sample before sending it to the filter. I can write out the pseudo-code algorithm if you like , but it's really quite simple.
__________________
Paul Elliott, S/V VALIS - Pacific Seacraft 44 #16 - Friday Harbor, WA
www.sailvalis.com
|
|
|
13-06-2012, 08:35
|
#6
|
Registered User
Join Date: Aug 2010
Posts: 298
|
Re: NMEA electronic compass
Quote:
Originally Posted by stara
this project may have solved the issue already - Google "B-CALMXP"
|
Could you lease explain what it does? I see a bunch of video's showing very steady AP's. I assume it is a combination of hard- and software?
|
|
|
13-06-2012, 08:39
|
#7
|
Registered User
Join Date: Aug 2010
Posts: 298
|
Re: NMEA electronic compass
Quote:
Originally Posted by Paul Elliott
While I agree that the compass response should be as quick as practical, you can still do accurate filtering. To compensate for the 360 <--> 0 transitions, use the difference between the current filtered value and the new sample point and optionally add or subtract 360 from the new sample before sending it to the filter. I can write out the pseudo-code algorithm if you like , but it's really quite simple.
|
Paul,
Even with pseudo code I'm not able to make C++ code, I'm not a programmer 
The code to create the nmea-string looks as follows:
Code:
#include <Wire.h>
#include <LSM303.h>
LSM303 compass;
void setup() {
//pinMode(txPin, OUTPUT);
Serial.begin(4800);
Wire.begin();
compass.init();
compass.enableDefault();
// Calibration values. Use the Calibrate example program to get the values for
// your compass.
compass.m_min.x = -519; compass.m_min.y = -376; compass.m_min.z = -462;
compass.m_max.x = 223; compass.m_max.y = 383; compass.m_max.z = 317;
}
/*----------------------------------------------------------------------------
1 2 3 4 5 6
| | | | | |
$--HDG,x.x,x.x,a,x.x,a*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Magnetic Sensor heading in degrees
2. Magnetic Deviation, degrees
3. Magnetic Deviation direction, E = Easterly, W = Westerly
4. Magnetic Variation degrees
5. Magnetic Variation direction, E = Easterly, W = Westerly
6. Checksum */
char nmeastr[17]; // HCHDG,000.00,,,,*
int checksum;
char hs[6]; // 000.00
void loop() {
strcpy(nmeastr,"HCHDG,");
//dtostrf(FLOAT,WIDTH,PRECSISION,BUFFER);
compass.read();
int heading = compass.heading((LSM303::vector){0,-1,0 }); //1,0,0 will allign North with SFE silkscreen
dtostrf(heading, 5, 2, hs);
strcat(nmeastr,hs);
strcat(nmeastr,",,,,");
//add a checksum
checksum=0;
for (int n=0; n < strlen(nmeastr); n++) {
checksum ^= nmeastr[n];
}
Serial.print("$");
Serial.print(nmeastr);
Serial.print("*");
Serial.print(checksum, HEX);
Serial.println();
//Serial.print("\t");
//Serial.println();
/* 5hz == 200 */
delay(200);
}
Thanks for your help!
|
|
|
 |
Thread Tools |
Search this Thread |
|
|
Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
Advertise Here
Recent Discussions |
|
|
|
|
|
|
|
|
|
|
|
|
Vendor Spotlight |
|
|
|
|
|