1//////////////////////////////////////////////////////////////////////////////// 2// // 3// This software is supplied under the terms of a license agreement or // 4// nondisclosure agreement with Mitov Software and may not be copied // 5// or disclosed except in accordance with the terms of that agreement. // 6// Copyright(c) 2002-2016 Mitov Software. All Rights Reserved. // 7// // 8//////////////////////////////////////////////////////////////////////////////// 9 10#ifndef _MITOV_COMPASSHEADING_h 11#define _MITOV_COMPASSHEADING_h 12 13#include <Mitov.h> 14 15namespace Mitov 16{ 17enum TAngleUnits { auDegree, auRadians, auNormalized }; 18 19class CompassHeading :publicOpenWire::Component 20{ 21typedefOpenWire::Component inherited; 22 23public: 24OpenWire::VlaueSinkPin<float> InputPins[2]; 25OpenWire::TypedSourcePin<float> OutputPin; 26 27public: 28float DeclinationAngle =0.0; 29 TAngleUnits Units = auDegree; 30 31protected: 32bool FChangeOnly =false; 33 34protected: 35virtualvoidSystemLoopEnd() 36{ 37inherited::SystemLoopEnd(); 38 39// Hold the module so that Z is pointing 'up' and you can measure the heading with x&y 40// Calculate heading when the magnetometer is level, then correct for signs of axis. 41float AHeading =atan2( InputPins[1].Value, InputPins[0].Value );// Y , X 42 43// Serial.println( AHeading ); 44 45// Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location. 46// Find yours here: http://www.magnetic-declination.com/ 47// If you cannot find your Declination, comment out these two lines, your compass will be slightly off. 48 49float ADeclinationAngle; 50switch( Units ) 51{ 52case auDegree: 53 ADeclinationAngle = DeclinationAngle * M_PI /180; 54break; 55 56case auRadians: 57 ADeclinationAngle = DeclinationAngle; 58break; 59 60case auNormalized: 61 ADeclinationAngle = DeclinationAngle *2* PI; 62break; 63 64} 65 66 AHeading += ADeclinationAngle; 67 68// Correct for when signs are reversed. 69if(AHeading <0) 70 AHeading +=2*PI; 71 72// Check for wrap due to addition of declination. 73if(AHeading >2*PI) 74 AHeading -=2*PI; 75 76switch( Units ) 77{ 78case auDegree: 79 AHeading *=180/ M_PI; 80break; 81 82case auNormalized: 83 AHeading /=2* PI; 84break; 85 86} 87 88 OutputPin.SetValue( AHeading, FChangeOnly ); 89 90 FChangeOnly =true; 91} 92 93}; 94} 95 96#endif