Tuesday, January 29, 2013

AVR Atmega HMC5883L magnetometer lib 01

The Honeywell HMC5883L is a surface-mount, multi-chip module designed for low-field magnetic sensing with a digital interface for applications such as lowcost compassing and magnetometry.

This library implements a way to get values from hmc5883l.

If your magnetometer stands with z-axis parallel to ground, you can get y and x raw values from magnetometer, and trasform it degrees using this formula:
heading = atan2(y_raw, x_raw) * 57.29578;
Then you should add magnetic declination (in degrees) for your location, to get yours visit http://magnetic-declination.com, if you have an EAST declination use +, if you have a WEST declination use -.
Then add this value to your heading.

Calibration is suggested to get more accurate parameters.

Setup parameters are stored in file hmc5883l.h

This library was developed on Eclipse, built with avr-gcc on Atmega8 @ 1MHz.
If you include math.h add libm library to linker.


Code


Notes
  • read risk disclaimer
  • excuse my bad english

36 comments:

  1. Hello sir,
    1) Can you please tell me how did you got this constant 57.29578 ?
    2) What value we will get in the heading variable?
    3) Transform your magnetic declination value to radiant, if you have an EAST declination use +, if you have a WEST declination use -.Then add this value to your heading.
    = my area shows Magnetic declination: 0° 31' WEST
    Declination is NEGATIVE
    Inclination: 27° 12'
    You got float declination = 0.03025; how should i calculate from above information.
    Thanks in advance

    ReplyDelete
    Replies
    1. hello,
      1) 1 radian = 57.29578 degrees
      2) "heading" of your magnetometer board in degrees
      3) my magnetic declination is 1° 73' degrees, in radians 0.03025
      anyway i've an made an ERROR here, i have to use radians and not degree as magnetic declination, because i've already trasform heaading in degrees, thank you for let me see this error. now it is corrected.

      Delete
  2. Can i use this formula for LSM303DLHC to calculate magnetometer in degree?

    ReplyDelete
    Replies
    1. if you mean, the heading from raw values, yes.

      Delete
  3. Hi,
    I have managed to get the heading from LSM303 thanks to you but one more problem i am facing that sensor is not giving me proper 180 degree i.e. it gives output in between 160 -170. i was expecting at least +/- 5% error. please help me with this issue.

    ReplyDelete
    Replies
    1. it might be your sensor, try with other one if you have, also try the adafruit or some arduino libraries. let me know results.

      Delete
  4. Here are the raw axis data I'm getting. Can you tell me what might be the reason? I'm using this module http://www.dipmicro.com/store/GY271-MOD

    and the raw data
    x y z
    ------------------------
    -509 -509 -509
    -510 -509 -510
    -510 -511 -512
    -513 -513 -514
    -515 -515 -515
    -514 -516 -514
    -515 -514 -515
    -514 -513 -513
    -511 -511 -510
    -509 -509 -510
    -508 -508 -508
    -508 -509 -509
    -508 -509 -509
    -510 -510 -510
    -511 -512 -512
    -513 -514 -514
    -515 -514 -516
    -515 -515 -514
    -514 -514 -512
    -513 -513 -511
    -512 -511 -510
    -510 -508 -509
    -509 -508 -508
    -509 -509 -509
    -508 -509 -509
    -509 -509 -510
    -513 -514 -514
    -515 -513 -514
    -514 -514 -515
    -514 -516 -514
    -514 -514 -513
    -514 -512 -511
    -511 -511 -510

    ReplyDelete
    Replies
    1. It may be your startup stage. Anyway, check your magnetometer with other firmware and hardware, like arduino library for HMC5883L, also check your firmare and hardware, with another HMC5883L magnetometer.

      Delete
    2. Got my solution, pasting here for future. Whenever I load new .hex file onto my AVR, it seems that HMC5883L modules somehow "doesn't reset" it's micro-compass inside the chip. The capacitor somehow pump the charge to the micro-compass- as far as my theory suggest!

      The solution was to power off the whole system for a couple of seconds so the capacitor on board, might discharge and reset. Thus I managed it to work!

      Delete
  5. Great job Davide!

    Can you describe or link calibration procedure? I mean how to fill hmc5883l.h with proper values.

    ReplyDelete
    Replies
    1. yes. Take a look here: http://davidegironi.blogspot.it/2013/01/magnetometer-calibration-helper-01-for.html

      Delete
  6. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Hello,
      thank you for your support.
      Magnetometer calibration it's a pretty copmlex thing. You have to adjust soft and hard iron distorsions.
      If you look here, you will find my implementation of a magnetometer calibration: http://davidegironi.blogspot.it/2013/01/magnetometer-calibration-helper-01-for.html#.U3OFd4F_vh4
      Hard iron distorsion are pretty simple to compensate, for hard+soft iron errors things changes.
      The alg. behind is much more sophisticated, basically it's an ellipsoid to circle fit althoritm, and too me it's too much for the non floating math and low resources of a microcontroller. It seems to me that what you are doing with your alghoritm is to compensate hard iron errors, it the robot rotate only on one axis, your are compensating one axis of course, but it's a few that i do not look at magnetometer distorsions, so i may be wrong.
      Hope this helps ;)

      Delete
  7. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Thanks for sharing your code!
      It could be usefull for an hard iron runtime compensation.

      Delete
  8. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Hello,
      at first you have to be sure that it display without errors on your uart terminal, so, use a uart library to send values to your terminal.
      Than check that the conversion of the values obtained (mx and so on), is correct for your LCD display function.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. This comment has been removed by the author.

      Delete
  9. This comment has been removed by the author.

    ReplyDelete
  10. Hallo,
    can you help me, code for hmc5883l with CVAVR for atmega32?

    fungkyking01@gmail.com

    tangks

    ReplyDelete
    Replies
    1. Hello, the code in the download link above in this page can be compiled using avrgcc. If you just recompile it for ATmega32 it should work.

      Delete
  11. Hi Davide,

    What is the device address you have used in your code for this sensor?

    I'm having trouble with my sensor and code to communicate. I'm receiving a NACK when I send the device address to slave. I have posted my question in the following forum.

    http://www.avrfreaks.net/forum/twii2c-communication-hmc5883l-3-axis-digital-compass

    if you could shed some light, would be much appreciated.

    Thanks,
    -Jinantha

    ReplyDelete
    Replies
    1. Hello, I'm using the 3C address. Have you try another board? Or have you try this board with some other driver, like Arduino one? It may be your chip damaged.

      Delete
    2. Thanks for the info.
      you were right my chip was damaged due to 5v signaling.
      I was not aware that clock and data lines should be level converted to 3.3v.

      Delete
    3. It happens, mistakes are here to let us grow :)

      Delete
  12. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  13. Hi
    I want display on lcd, value x and y. I don't know, how do it, becouse i try use your code but I do not know whether the processor retrieves the values ​​of the magnetometer. I have a reqest to you. Do you can help me and you can write code which It will aim to display the X and Y on lcd. I'm working with atmega 32 hmcl5883l and lcd hd44780. Thank's
    I would like to X and Y changed with the movement of the magnetometer

    ReplyDelete
    Replies
    1. Hello, I'm sorry but I can not write the code for your project, or you will never learn and grow.
      At first, try to understaind if you get heading from magnetometer, you can use UART for debug purpose.
      If you are really a beginner, take a look to Arduino, which is fairly simple than avrgcc plain code. Also another place you could take a look is the AVR Freaks forum, there you can find plenty of informations.

      Delete
    2. I have a problem with this error. Can You help me?
      #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
      ../uart/uart.c:86:36: error: attempt to use poisoned "SIG_UART_RECV"
      My program is Avr Studio 4...

      Delete
    3. Seems you are using an out of date interrupt name for you compiler. Take a look here: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

      Delete
    4. Note: this project it is written and tested using avrgcc and the Eclipse AVR plugin.

      Delete
  14. dear sir i have written code for pic16. but not working. plz help me.aviraje8@gmail.com

    ReplyDelete
    Replies
    1. Hello, I'm sorry but this code is for ATmega AVR. You can port my code.

      Delete