ThisdoucmentoutlinestheimplementationofUserClibrationofthemagneticcompass.Specifically,itdescribesthemathematicalcomputationsinC/C++sourcecode.Thiscalibrationwillcorrectorcompensateforthehardironeffects.Hardironeffectsaremagneticfieldsuperimpositionsontheearth'smagneticfieldthatarefixedinmagnitudeandwhichdonotdependontheorientationofthecompass.Thecompasscalibrationshallbeinitiatedbyausercommandthatputthecompassintothecalibrtionmode.Onceinthatmodethecompassshallberotatedthrough360degreesabouththeForwardorLeftdirectionfollowedbya360rotationabouttheUp-Downdirection.Thatis,therearetwofullrotationsrequiredtocompletethephysicalmovementrequired.Attheendoftherotationsacommandtoendthecalibrationprocessshallbeissedbytheusertothecompass.ItisimportanttokeeptheForward(orLeft)axisleveldiringthefirstrotationandtokeeptheUp-Downaxisverticalduringtheseconcalibrationanduntilthefulcalibrtioniscomplete.Failuretofollowtheseprocesswillresultinlessthanoptimalcalibrationandheadingerrorsarelikely.ForwardDirection(+)LeftDirection(+)UPDirection(+)Figure1First360Rotation2nd360Rotation#defineCalThreshold0intXmax,Xmin,Ymax,Ymin,Zmax,Zmin;voidInitialize_Cal_Variables(intMagX,intMagY,intMagZ)voidCalibrate(intMagX,intMagY,intMagZ)voidCompute_and_Save(void)voidHard_Iron_Correction(intXoff,intYoff,intZoff)voidInitialize_Cal_Variables(intMagX,intMagY,intMagZ){//setMaxandMinvaluesofthemagoutputtothecurrentvaluesXmax=MagX;Xmin=MagX;Ymax=MagY;Ymin=MagY;Zmax=MagZ;Zmin=MagZ;}voidCalibrate(intMagX,intMagY,intMagZ){//thisroutinewillcapturethemaxandminvaluesofthemagX,Y,andZdatawhilethe//compassisbeingrotated360degreesthroughthelevelplaneandtheuprightplane.//i.e.horizontalandverticalcircles.//Thisfunctionshouldbeinvokedwhilemakingcontinuousmeasurements//onthemagnetometersintMagXreading,MagYreading,MagZreading;MagXreading=MagX;//justforclarification...canremovetheselinesMagYreading=MagY;MagZreading=MagZ;if(MagXreadingXmax)Xmax=MagXreading;if(MagXreadingXmin)Xmin=MagXreading;if(MagYreadingYmax)Ymax=MagYreading;if(MagYreadingYmin)Ymin=MagYreading;if(MagZreadingZmax)Zmax=MagZreading;if(MagZreadingZmin)Zmin=MagZreading;}voidCompute_and_Save(void){if(abs(Xmax-Xmin)CalThreshold){Mag_UserCal_Offset_X=(Xmax+Xmin)/2;//SaveparametersinEE}if(abs(Ymax-Ymin)CalThreshold){Mag_UserCal_Offset_Y=(Ymax+Ymin)/2;//SaveparametersinEE}if(abs(Zmax-Zmin)CalThreshold){Mag_UserCal_Offset_Z=(Zmax+Zmin)/2;//SaveparametersinEE}}voidHard_Iron_Correction(intXoff,intYoff,intZoff)//callthisfunctionforcorrection{MagX-=Mag_UserCal_Offset_X;MagY-=Mag_UserCal_Offset_Y;MagZ-=Mag_UserCal_Offset_Z;}