HCM5883L - How to calculate MAGNETIC DECLINATION
geometrix
Posts: 27
All,
I am using two PMB-648 GPS receivers, XBEE transceivers, and a HMC5883L compass module.
The base and remote GPS receivers are wirelessly connected with XBEE transceivers.
My entire "system" is controlled by a PIC24F microcontroller.
So far, I am able to receive "base" and "remote" GPS coordinates, parse the coordinates, and calculate the distance and heading between the "base" and "remote" PMB-648 GPS receivers.
I also have the HMC5883L compass module working with I2C.
NOW I WANT TO determine the anglular difference between GEOGRAPHIC NORTH and the heading calculated between the "base" and "remote" GPS receivers. The HMC5883L reports magnetic north...not geographical north.
HOW CAN I CALCULATE THE MAGNETIC DECLINATION??????????????????????
TIA,
Neal
I am using two PMB-648 GPS receivers, XBEE transceivers, and a HMC5883L compass module.
The base and remote GPS receivers are wirelessly connected with XBEE transceivers.
My entire "system" is controlled by a PIC24F microcontroller.
So far, I am able to receive "base" and "remote" GPS coordinates, parse the coordinates, and calculate the distance and heading between the "base" and "remote" PMB-648 GPS receivers.
I also have the HMC5883L compass module working with I2C.
NOW I WANT TO determine the anglular difference between GEOGRAPHIC NORTH and the heading calculated between the "base" and "remote" GPS receivers. The HMC5883L reports magnetic north...not geographical north.
HOW CAN I CALCULATE THE MAGNETIC DECLINATION??????????????????????
TIA,
Neal
Comments
Neal,
I don't think you can calculate declination without some sort of data base that provides the "map" of earth's declination values. In other words, I don't think there's one formula that you can use that curve fits the entire planet. However, perhaps you can create some simple interpolations for a geographically limited area???
http://en.wikipedia.org/wiki/Magnetic_declination
I am currently trying to understand the program below for the compass sensor HCM5883L:
' {$STAMP BS2}
' {$PBASIC 2.5}
SDA PIN 0 ' SDA of compass to pin P0
SCL PIN 1 ' SCL of compass to pin P1
WRITE_Data CON $3C ' Requests Write operation
READ_Data CON $3D ' Requests Read operation
MODE CON $02 ' Mode setting register
X_MSB CON $03 ' X MSB data output register
X VAR Word
Y VAR Word
Z VAR Word
rawl VAR Word
rawh VAR Word
' Variables for I2C communications
I2C_DATA VAR Byte
I2C_LSB VAR Bit
I2C_REG VAR Byte
I2C_VAL VAR Byte
PAUSE 50 ' Power up delay
I2C_REG = MODE ' Set operating mode to continuous
I2C_VAL = $0
GOSUB I2C_Write_Reg
DO
GOSUB GetRawReading ' Get raw Compass reading
DEBUG HOME, "X = ",50, SDEC x, CR ' Print values
DEBUG "Y = ",50, SDEC y, CR
DEBUG "Z = ",50, SDEC z, CR
DEBUG CR
LOOP
GetRawReading:
PAUSE 400 ' Wait for new data
' Send request to X MSB register
GOSUB I2C_Start
I2C_DATA = WRITE_Data
GOSUB I2C_Write
I2C_DATA = X_MSB
GOSUB I2C_Write
GOSUB I2C_Stop
'Get data from register (6 bytes total, 2 bytes per axis)
GOSUB I2C_Start
I2C_DATA = READ_Data
GOSUB I2C_Write
' Get X
GOSUB I2C_Read
rawH = I2C_Data
GOSUB I2C_ACK
GOSUB I2C_Read
rawL = I2C_Data
GOSUB I2C_ACK
X = (rawH << 20) | rawL
' Get Z
GOSUB I2C_Read
rawH = I2C_Data
GOSUB I2C_ACK
GOSUB I2C_Read
rawL = I2C_Data
GOSUB I2C_ACK
Z = (rawH << 20) | rawL
' Get Y
GOSUB I2C_Read
rawH = I2C_Data
GOSUB I2C_ACK
GOSUB I2C_Read
rawL = I2C_Data
GOSUB I2C_NACK
Y = (rawH << 20) | rawL
GOSUB I2C_Stop
RETURN
'
I2C functions
' Set I2C_REG & I2C_VAL before calling this
I2C_Write_Reg:
GOSUB I2C_Start
I2C_DATA = WRITE_DATA
GOSUB I2C_Write
I2C_DATA = I2C_REG
GOSUB I2C_Write
I2C_DATA = I2C_VAL
GOSUB I2C_Write
GOSUB I2C_Stop
RETURN
' Set I2C_REG before calling this, I2C_DATA will have result
I2C_Read_Reg:
GOSUB I2C_Start
I2C_DATA = WRITE_DATA
GOSUB I2C_Write
I2C_DATA = I2C_REG
GOSUB I2C_Write
GOSUB I2C_Stop
GOSUB I2C_Start
I2C_DATA = READ_DATA
GOSUB I2C_Write
GOSUB I2C_Read
GOSUB I2C_NACK
GOSUB I2C_Stop
RETURN
I2C_Start:
LOW SDA
LOW SCL
RETURN
I2C_Stop:
LOW SDA
INPUT SCL
INPUT SDA
RETURN
I2C_ACK:
LOW SDA
INPUT SCL
LOW SCL
INPUT SDA
RETURN
I2C_NACK:
INPUT SDA
INPUT SCL
LOW SCL
RETURN
I2C_Read:
SHIFTIN SDA, SCL, MSBPRE, [I2C_DATA]
RETURN
I2C_Write:
I2C_LSB = I2C_DATA.BIT0
I2C_DATA = I2C_DATA / 2
SHIFTOUT SDA, SCL, MSBFIRST, [I2C_DATA\7]
IF I2C_LSB THEN INPUT SDA ELSE LOW SDA
INPUT SCL
LOW SCL
INPUT SDA
INPUT SCL
LOW SCL
RETURN
_______________________________________________________
I bought this robot with the intention of using it in a robot navigation project that I have. I am stuck because I do not understand how to use this code in my program.
Thanks
I have used the HCM5853L with the Propeller but I haven't used with a BS2. The sensor returns a vector pointing to the strongest magnetic field. This vector is made up x, y and z components. To convert the vector into a heading you need to use the ATAN2 function. I have no idea how to do this with the BS2. If you take the numbers given by the BS2 you could use the ATAN2 function in Excel or OpenOffice Calc to compute the header though I doubt this will do you much good.
I've kind of been watching for HCM5853L posts and I don't recall see one where the BS2 has been able to turn the vector into a heading. Maybe on of our resident BS2 experts could help.
If you want some awesome Spin code to use with the HCM5853L let me know. I have it.
BTW, welcome to the forum. While I understand you're reluctance to post a new thread (I was also reluctant to do so my first post), I think your question would probably have been better asked in a new thread since your quesion wasn't really about "magnetic declination". Not a big deal.
Also, you and anyone else is welcome to send me a private message with a link to a post they'd like me to see. A private message would probably work better than a visitor message to get my attention (the notifications are different).
Hopefully someone can help with how to convert the xyz vector into a heading using the BS2.