element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Sensors
  • Technologies
  • More
Sensors
Sensor Forum Help with 5883L crazyness.
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Sensors to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Suggested Answer
  • Replies 16 replies
  • Answers 1 answer
  • Subscribers 342 subscribers
  • Views 3877 views
  • Users 0 members are here
  • 5883l
Related

Help with 5883L crazyness.

screamingtiger
screamingtiger over 10 years ago

shabaz

jw0752

 

I have collected data and cannot get it to point to the correct heading.  Its off quite a bit and I cannot adjust as the amount it is off is non-linear.  For example, at 0 degrees it shows 100 degrees.  But at 45 degrees it shows 170 degrees.  Z axis is level and remain constant for the most part.

 


Here is the data I collected, does it makes sense?  I used a compass on my phone and compared to the readings I am getting.

 

 

 

0 degrees North
X 0
Y 155
Z -530

 

Calculated heading: 100

 

 

90 degrees east

 

X -165
Y 100 (shouldn't this read 0 since it is pointing in same direction X was just at?)
Z -530
Calculated Heading: 224

 


180 degress South
X: 0
Y: -290
Z: -540

 

Calculating Heading: 286

 

 

 

270 degrees West

 

X: 250
Y: -100
Z: -550
Calculated Heading: 252

 


One thing I am thinking is odd, if at 0 degrees north X axis reads 0, if I rotate 90 degrees to right, would Y axis now read 0?

 

I am not sure what the axis is measuring, I thought it was force and it I point x axis in one direction, then Y axis in same direction, they would show the same reading...

 

X and Y are 90 degrees in parallel plane.
I ordered another magnometer hoping a different brand will help.  Its still 5883L but different maker of breakout.

  • Sign in to reply
  • Cancel

Top Replies

  • shabaz
    shabaz over 10 years ago in reply to screamingtiger +2
    Hi Joey, I took your code and added ALG_TEST stuff to it and modifying the declinationAngle variable: //#include "heading.h" #include <stdio.h> #include <iostream> //#include <wiringPi.h> //#include…
  • jw0752
    jw0752 over 10 years ago +1
    Hi Joey, This may be off base but if I treat your X and Y data as vectors and calculate Result = Sqrt( X^2 + Y^2) I get a Result that is at least in the ball park for the headings that you listed. Like…
  • jw0752
    jw0752 over 10 years ago +1
    Ok now you can see I really don't grasp it quickly as that is exactly what you were doing. No wonder my calculations matched yours. I will put my thinking cap back on and let you know if something better…
Parents
  • shabaz
    0 shabaz over 10 years ago

    Also, if you can post the code then I can give it a visual inspection, in case anything seems odd.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • shabaz
    0 shabaz over 10 years ago

    Also, if you can post the code then I can give it a visual inspection, in case anything seems odd.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
  • screamingtiger
    0 screamingtiger over 10 years ago in reply to shabaz

    Go to https://github.com/screamingtiger/QuadCOP

    And look at head.h and heading.cpp

     

    I think I have missed a stip.  there is some code that is setting up gains

    static float _hmc5883_Gauss_LSB_XY = 1100.0F;
    static float _hmc5883_Gauss_LSB_Z  = 980.0F;

    I'm not using these but I did think I confirmed I am getting same values as the arduino I was using.

    Anyways have a look at the code if you will.  Its pretty simple actually.

     

     

    The god news is that I can still have a test auto flight today.  Because my magnometer is consistent, I can use it to fly in a square pattern.  I think that will be a good test.  But would love to have this working.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • shabaz
    0 shabaz over 10 years ago in reply to screamingtiger

    Hi Joey,

     

    I took your code and added ALG_TEST stuff to it and modifying the declinationAngle variable:

    //#include "heading.h"
    #include <stdio.h>
    #include <iostream>
    
    
    //#include <wiringPi.h>
    //#include <wiringPiI2C.h>
    #include <math.h>
    
    
    using namespace std;
    
    
    // comment out the next line if there is a WiringPi library
    #define NO_WIRING
    
    
    #define SENSORS_GAUSS_TO_MICROTESLA       (100)
    #define     PI 3.1415926535897932384626433832795
    #define HEADINGADDRESS          0x1e
    #define HEADINGDEADBAND 2
    #define ALG_TEST 1
    
    
    
    
    static float _hmc5883_Gauss_LSB_XY = 1100.0F;
    static float _hmc5883_Gauss_LSB_Z  = 980.0F;
    
    
    
    
    
    
    class Heading
    {
      public:
      int memsBoard;
      int address;
      float fx,fy,fz;
      short int x,y,z;
      float currentHeading,previousHeading;
    
    
      Heading(int address);
      int Initialize();
      float GetHeading();
      bool HeadingReached(double);
    
    };
    
    
    
    
    Heading::Heading(int address)
    {
      this->address = address;
    }
    
    
    
    
    int Heading::Initialize()
    {
      cout << "HEADING INIT here" << endl;
      int t;
      if (ALG_TEST)
      {
      cout << "Heading::Initialize()" << endl;
      return(0);
      }
    
    
    #ifndef NO_WIRING
      memsBoard = wiringPiI2CSetup(address);
      t = wiringPiI2CWriteReg8(memsBoard,0x02,0x00);
      if(memsBoard < 0)
      return memsBoard;
    
    
      if(t < 0)
      return t;
    
    
      t = wiringPiI2CWriteReg8(memsBoard,0x01,0x20);
      if(t < 0)
      return t;
    #endif
      return 0;
    
    }
    
    
    
    
    float CorrectHeading(float heading)
    {
      float _0to90 = -100;
      float _91to180 = -136;
      float _181to270 = -100;
      float _270to360 = 20;
    
    
      if(heading >=100 && heading <= 100+90)
      return heading + _0to90;
    
    
            if(heading >= 91 && heading <= 180)
                    return  heading + _91to180;
            if(heading >=181 && heading <= 271)
                    return  heading + _181to270;
            if(heading >=271 && heading <= 360)
                    return  heading + _270to360;
    
    
      return heading;
    
    
    
    
    
    
    }
    
    
    float Heading::GetHeading()
    {
      if (ALG_TEST)
      {
      cout << "Heading::GetHeading" << endl;
      x=-238; // this is 0xff12
      y=-342; // this is 0xfeaa
      z=-479; // this is 0xfe21
    
    
      }
    #ifndef NO_WIRING
      x  = wiringPiI2CReadReg8(memsBoard,0x03) << 8;
            x |=   wiringPiI2CReadReg8(memsBoard,0x04);
    
    
      z = wiringPiI2CReadReg8(memsBoard,0x05) << 8;
            z |=   wiringPiI2CReadReg8(memsBoard,0x06);
    
    
      y =  wiringPiI2CReadReg8(memsBoard,0x07) << 8;
            y |=   wiringPiI2CReadReg8(memsBoard,0x08);
    #endif
      fx = x;
      fy = y;
      fz = z;
    
    
      float heading = atan2(fy,fx);
    
    
            float declinationAngle = 0.0404; //0.22;
      heading += declinationAngle;
      if(heading < 0)
        heading += 2*PI;
      if(heading > 2*PI)
        heading -= 2*PI;
    
    
      previousHeading = currentHeading;
      currentHeading = heading * 180/M_PI;
      //currentHeading = CorrectHeading(currentHeading);
    
    
      return currentHeading;
    
    
    
    
    
    
    
    
    }
    
    
    
    
    
    
    bool Heading::HeadingReached(double heading)
    {
            double b = GetHeading();
            if(fabs(b - heading) <= HEADINGDEADBAND)
                    return true;
            else
                    return false;
    }
    
    
    Heading *magHeading;
    
    
    int
    main(void)
    {
      float heading;
    
    
      magHeading=new Heading(1);
      heading=magHeading->GetHeading();
    
    
      printf("Heading is %lf\n", heading);
      if (ALG_TEST)
      {
      printf("Expected value is 237.48\n");
      }
      return(0);
    }

     

    You can compile it on any Linux machine by saving it to a file (called say mag-test.c) and then typing g++ mag-test.c and then you can run it by typing ./a.out

    This is the result I get:

    Heading::GetHeading
    Heading is 237.480469
    Expected value is 237.48

     

    So, the algorithm appears working (the code uses the values 0xff12, 0xfeaa and 0xfe21 for the x, y and z values it pretends to read from the sensor,

    and expects the output to be around 237.48 because that was the value in the example on the web page I mentioned ( Creative Electronic!: Arduino: simple compass with HMC5883L + Library ).

    So, if it doesn't work, then either the code on that site is giving incorrect values (it is a possibility, even though the author claims it works, we must never assume!),

    or I2C values read are incorrect.

    The latter could occur with faulty or long wiring perhaps, or faulty/counterfeit sensor IC/module for example.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • screamingtiger
    0 screamingtiger over 10 years ago in reply to shabaz

    shabaz  Sorry man I got side tracked.  I will be working on this today.  Thanks for your help, I'll post back.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube