ArduIMU Firmware for NMEA with I2C compass heading

For those NMEA GPS users out there who don't want to be left out of the wonderful product that is ArduIMU, I've modified/combined the NMEA parsing routine in ArudPilot 2.3.1 with the latest ArduIMU firmware from Doug Weibel - ArduIMUV2 DCM V10. Additionally, I'm using the $50 I2C compass from Sparkfun (HMC6352) and have added a routine to pull this data from the compass and include it in the text output as "HDG." I've also added "SAT" for satellites and "HOP" for HDOP in the text output.Download Here: http://www.happykillmore.com/software/RemzibiOSD/HK_ArduIMU_NMEA.zipTo disable the compass code, simply change PRINT_COMPASS 1 to PRINT_COMPASS 0Please also note that 3 Hz is about the fastest you should set your GPS when going throught the ArduIMU. Any faster and the serial port won't be able to keep up (this statement assumes 38,400 baud and only getting GPGGA and GPRMC from the GPS).You'll need to copy the TwoWire.h and TwoWire.cpp files included in the zip to the arduino-0017\hardware\libraries\Wire folder if you're planning on using the Compass routine.
E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones

Comments

  • Developer
    The HMC6343 is very expensive and it's not more than a magnetometer with accelerometers and a PIC core doing the compensation calcs. Does somebody knows how to fuse ArduIMU V1 data with an simple HMC6352 data for achieve tilt compensation? It's interesting for correcting YAW drift error. The Diydrone's 3 axis mag isn't compatible with ArduIMU V1, but I think we can read it "outside the board" and mix data to get a nice heading lock. For example... I'm using ArduIMU V1 sending serial data to a mainboard of my UAV. So I think the mainboard could read the mag separately and do the calcs. Is it possible?
  • No "EDIT" button here?

    I forgot to mention two other things:

    @1 The GPS RX's output burst sequence is asynchronous to our program. So we have to "fear" its data burst at every point (time) of the program.

    @2 Textual output (->LabView) appears only every 100 milliseconds (each 5th call of the IMU loop) - so this is not THAT "problem" compared to binary output ocurring every 20 milliseconds.

    Heading to bed. Good Night, Good Morning from Germany!

    Tom
  • Hi everybody!

    My 1st post here, just signed up.

    @HappyKillmore
    "Please also note that 3 Hz is about the fastest you should set your GPS when going throught the ArduIMU. Any faster and the serial port won't be able to keep up (this statement assumes 38,400 baud and only getting GPGGA and GPRMC from the GPS)."

    Not really.. I'm using a LS20031 purchased from Sparkfun running it on 57,600 baud via NewSoftSerial and w/ 2Hz repitition rate. The RX is programmed to send GGA and RMC records only. The MC is an Arduino Nano 16MHz.

    There are two constraints we have to consider:

    @1 The timing within our program: ArduIMU's main loop is triggered every 20 milliseconds. The several sections (routines) without printdata() need about 5000 microseconds grand total on a ATmega328@16.

    GGA plus RMC mean about 160 bytes to send out by the RX. At 57,600 baud that needs around 2,200 microsends. Now everything depends on the nature and size of the RX buffer in the serial/asynchronous program section. NewSoftserial uses a ringbuffer of 64 bytes. I changed it to 128 bytes.
    Now the challenge: With 2Hz repetition frequency and 57,600 baud we have to await every 500 milliseconds a 2.2ms-burst of 160 bytes (more than fits into our RX buffer) which we have to receipt and process (maybe later on) synchronously in sequence. I built a "state machine" for the GPS data processing - what means that this routine can process every amount of bytes in buffer whenever we call it - not falling out of sequence concerning the processing of the byte stream.
    What we have to avoid is that the buffer runs full or even nearly full. In last consequence that leads to the demand that this routine has to be called at least every 1,800 microseconds roundabout. If we look at the different execution times of routines constituting the IMU's main loop we learn where "the time is over" (to avoid buffer overruns) we have to call the "state machine" to check/empty+process the buffer (needs 40 microseconds at max, only). This is after Read_adc_raw() (1,300us elapsed), after Matrix_update() (another 1,350us elapsed), after Euler_angles() (two other routines executed before, about 1,550us on top elapsed) . I have to mention that I process some more sensors in Read_adc_raw() and process it (normalization, temperature compensation etc) in read_adc(). Also, before calling printdata(), I spend 750us in a mag heading routine (HMC5843).
    Finally we consider the execution times in the part of printdata() we use, - textual (for LabView) as well as binary output (exclusive alternatively). I do some extended binary output via I2C (to a 'pilot') which leads to significant wast of time in the several sections. So I have to call the "state machine" three times more in between of these sections.

    In the end, - the IMU needed ~5ms, my version of binary output about 4ms, - we have a grand total of 9 milliseconds, - 11 milliseconds distance to the next call time of the 50Hz IMU loop. The only "trick" was to process the software-UART's buffer early enough in between. The time "gaps" of about 40 microseconds per each call shouldn't disturb the IMU in any way.

    @2 The GPS receiver itself: It depends on the hardware facilities of the microcontroller in the RX (UART, timer) AND the software implementation (how much of "spaghetti code") what time the receiver needs to process data - on the reception site/on the output site. Not to forget real-time tasks like SOG (speed over ground) - based on the Doppler effect only. My GPS receiver gave up if I tried to let it send more than NMEA GGA and RMC @2Hz. Every higher repetition frequency (the specs claim to can do 5Hz) did lose. The specification of the LS20031 to be a 5Hz-receiver insofar is a "soft lie".

    Cheers
    Tom
  • Those of you having issues with tilt related errors, don't give up hope. Even if magnetometers won't work for you, your results may help others. Remember, those errors are the biggest when you are closer to the (magnetic) poles. In North America, people in Washington state, New England, and Canada will have a lot to worry about. People in the south can get away with a few degrees of tilt.

    To reiterate Doug, anyone getting in to magnetometers should know their local magnetic variation (declination). If you are fairly close to an imaginary line from Minneapolis down to St. Louis then down to New Orleans (extended north and south) your variation may be small enough to ignore. People far east or west, especially at high latitudes again, for example, those of you in Washington & New England, your variation will be big (~15 to 20 degrees).
    Another place to look it up, http://www.nga.mil/MSISiteContent/StaticFiles/Files/mv-world.jpg
  • What great timing! I was cleaning up the back bedroom in preparation for some holiday guests when I came across a mislaid box of old parts including two (count em, two) Vector 2X compasses, never used, that I had purchased in the mid 90's. I'll see how the code works with this antique.

    I have a few days off, and it looks like the wind is finally settling down too. Might get a bird in the air for the first time in...don't ask...
  • I posted this some time ago regarding update rate of Ublox:
    ame across this post on the Mikrokopter forum and wondered how this might affect the Ardupilot fitted with the Ublox LEA5-H: " we did our tests with the LEA5H to use it with the NaviCtrl. We couldn't find a solution to get it work. The data rate of the LEA5 is not constant. (depends on how many satelites are received). Statement from ublox: this is a typical behavior, if you use refresh rates below 1 Hz.

    This is the reason, why we use the LEA4H for our MKGPS.

    So - LEA5H is not recommended to use together with the NaviCtrl."

    The NaviCtrl is an ARM based navigation/data logging board with GPS.

    regards Peter
  • Hey Happy: Maybe your proving that the lack of tilt compensation in the 6352 means that, for angles greater than a degree or so, the compass output algorithm becomes unreliable. But to give it your best shot, I agree with Michael (re: calibration). My compass spits out readings similar to those you describe (even without tilt) if I don't let it calibrate itself at initial start up. And if you're doing your testing indoors, what are the chances that you're near any form of interference? My compass is very unreliable indoors. If it's of any use, let me know and I'll upload a code snippet for setting mode bits and the like. You may also want to add a programmed offset for the estimated value of magnetic declination for the area in which you are operating (although lacking this would not contribute to your described problem), which you can get from http://www.ngdc.noaa.gov/geomagmodels/struts/calcDeclination.
  • I'll give that a try. I might have to get one of Jordi's new 360 degree servos and have a push-button to run the calibration....

    http://store.diydrones.com/ProductDetails.asp?ProductCode=SRV%2DGWS125
  • @HappyKillmore: Try User Calibration on each power up, "C" for Calibrate - "E" for Exit Calibrate. Within calibrate...rotate sensor horizontally, smoothly, 2 full revolutions 720 degrees over the course of about 20 seconds. Also try setting S/R bit ....automatically periodically performs offset calibration of wheatsone bridge for offset nulling during normal operation.
  • I did some more testing with the code tonight trying to get the heading to be more accurate using the roll and pitch of the ArduIMU. After some rather entensive testing, I can say with much confidence that there is absolutely no way to compensate for roll and pitch.

    I tried simple multipliers and I tried exponential curves. I'd get everything looking good and all of a sudden, nothing matches anymore. Power off, power on and any multiplier or expo value I had chosen was now completely wrong.

    At one point, I took a few data points. At -10 degrees pitch, it had changed by 30 degrees heading (1.5 times what the datasheet said), at -20 degrees pitch, it had changed by 90 degrees heading (4.5 times what the datasheet said). I set everything up to use a 1.5 expo and it all looked great... for about 2 minutes. Then all of a sudden, for no good reason, the offset values were 1 degree or less of error for every degree of tilt on the pitch. No rhyme or reason.
This reply was deleted.