libraries / Mitov / Mitov_CompassHeading.hon commit Added link to project report (97a3ba0)
   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{
  17        enum TAngleUnits { auDegree, auRadians, auNormalized };
  18
  19        class CompassHeading : public OpenWire::Component
  20        {
  21                typedef OpenWire::Component inherited;
  22
  23        public:
  24                OpenWire::VlaueSinkPin<float>   InputPins[ 2 ];
  25                OpenWire::TypedSourcePin<float> OutputPin;
  26
  27        public:
  28                float   DeclinationAngle = 0.0;
  29                TAngleUnits     Units = auDegree;
  30
  31        protected:
  32                bool    FChangeOnly = false;
  33
  34        protected:
  35                virtual void SystemLoopEnd() 
  36                {
  37                        inherited::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.
  41                        float 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
  49                        float   ADeclinationAngle;
  50                        switch( Units )
  51                        {
  52                                case auDegree:
  53                                        ADeclinationAngle = DeclinationAngle * M_PI / 180;
  54                                        break;
  55
  56                                case auRadians:
  57                                        ADeclinationAngle = DeclinationAngle;
  58                                        break;
  59
  60                                case auNormalized:
  61                                        ADeclinationAngle = DeclinationAngle * 2 * PI;
  62                                        break;
  63
  64                        }
  65
  66                        AHeading += ADeclinationAngle;
  67
  68                        // Correct for when signs are reversed.
  69                        if(AHeading < 0)
  70                                AHeading += 2*PI;
  71    
  72                        // Check for wrap due to addition of declination.
  73                        if(AHeading > 2*PI)
  74                                AHeading -= 2*PI;
  75
  76                        switch( Units )
  77                        {
  78                                case auDegree:
  79                                        AHeading *= 180 / M_PI;
  80                                        break;
  81
  82                                case auNormalized:
  83                                        AHeading /= 2 * PI;
  84                                        break;
  85
  86                        }
  87
  88                        OutputPin.SetValue( AHeading, FChangeOnly );
  89
  90                        FChangeOnly = true;
  91                }
  92
  93        };
  94}
  95
  96#endif