Having major HM55B compass accuracy problems
I am not getting this thing to work properly with the Javelin.· If anyone can offer me any assistance or ideas, I would be very grateful.·
The biggest problem is a dramatic inaccuracy in certain orientations.· It is 40 degrees off at its worst.· I made the following table of actual headings versus the readings the module gives me:
0 = heading,· compass says = 0 x = 33 y = 0
15 = heading,· compass says = 14 x = 32 y = -8
30 = heading,· compass says = 25 x = 30 y = -15
45 = heading,· compass says = 41 x = 26 y = -23
60 = heading,· compass says = 58 x = 20 y = -30
75 = heading,· compass says = 74 x = 11 y = -38
90 = heading,· compass says = 85 x = 4 y = -41
105 = heading,· compass says = 96 x = -5 y = -42
120 = heading,· compass says = 108 x = -13 y = -41
135 = heading,· compass says = 116 x = -20 y = -38
150 = heading,· compass says = 125 x = -24 y = -32
165 = heading,· compass says = 135 x = -26 y = -26
180 = heading,· compass says = 144 x = -26 y = -20
195 = heading,· compass says = 152 x = -23 y = -13
210 = heading,· compass says = 166 x = -20 y = -5
225 = heading,· compass says = 180 x = -15 y = 0
240 = heading,· compass says = 200 x = -10 y = 4
255 = heading,· compass says = 250 x = -4 y = 10
270 = heading,· compass says = 270 x =·0 y = 12
285 = heading,· compass says = 298 x = 8 y = 14
300 = heading,· compass says = 313 x = 13 y = 14
315 = heading,· compass says = 323 x = 19 y = 15
330 = heading,· compass says = 336 x = 25 y = 12
345 = heading,· compass says = 345 x = 30 y = 8
360 = heading,· compass says = 359 x = 32 y = 1
Note that the x and y values shown above·are already adjusted to calibrate the module, as per the instructions that come with the module.· I had to add 10 to the X value and subtract 2 from the y before computing the angle.· This is why 0 degrees and 270 degrees are on the money.
The·actual range of x as received from the module is -36 to +22, and the range of y is -39 to +13.· This is not a very wide range of values in my opinion.· Although·you shift in 11 bits for X and Y, the actual number of significant bits is·really only·5.
After exhausting all my ideas about what was wrong with this thing, I went out and bought another one just to see if it was the module, but it did the same thing.· I also tried sticking the·module up on a mast about 14 inches from any electronics and wrapped the motors that are even further away in that foil that is·supposed to block all magnetic fields.·· Nothing helps.· I am beginning to think it is an incompatibliity between the Javelin and the compass.·But Chris·Savage says no.·The code I am using to get the values is the following:
·· private static int readHorizPos(){
···· // averaging 10 readings to eliminate jitter effects
····· int runningTotX = 0;
····· int runningTotY = 0;
····· for( int i = 0; i < 10; i++){
······· getCompassAxes();
······· runningTotX += x; // x is global
······· runningTotY += y;·// y is·global
····· }
····· x = runningTotX / 10;
····· y = runningTotY / 10;
····· x = x + 10;
····· y = y -2;
····· return (IntegerMath.atan2(-y, x)); // Compute angle
··· }
··· private static void getCompassAxes(){
····· int statusHM55B = 0;
····· int resetHM55B = 0x0000;············ // Reset command for HM55B
····· int measureHM55B = (short) 0x8000;·· // Start measurement
····· int reportHM55B = (short) 0xC000;··· // Get status/axis values
····· int readyHM55B = 0x000C;············ // 1100 -> Done, 00 -> no errors
····· int mask = (short) 0xF800;
····· CPU.writePin(clkHM55B, false); // Initialize Clk for delivering positive pulses.
····· CPU.writePin(enableHM55B, ON);
····· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
····· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, resetHM55B);
····· CPU.writePin(enableHM55B, ON);
····· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
····· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, measureHM55B);
····· statusHM55B = 0x00;·· // Clear previous status flags
····· while(true ){··· // Status flag checking loop
······· CPU.writePin(enableHM55B, ON);
······· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
······· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, reportHM55B);
······· statusHM55B = CPU.shiftIn(dinDout, clkHM55B, 4, CPU.POST_CLOCK_MSB );
······· if(· statusHM55B == 12) break;
····· }
······CPU.delay(200); // I stuck this in to see it would help
····· x = CPU.shiftIn(dinDout, clkHM55B, 11, CPU.POST_CLOCK_MSB);
····· y = CPU.shiftIn(dinDout, clkHM55B, 11, CPU.POST_CLOCK_MSB);
····· if ((x & 0x400) != 0) x |= (short)0xF800; //range -1024 to +1023
····· if ((y & 0x400) != 0) y |= (short)0xF800; //ditto
··· }
I wrote a program·using a standard Java JDK·to check the accuracy of the atan2 function, and it is pretty accurate, deviating from the floating point calcualtions by 1.3 degrees at the most, so that is not the problem.
·
The biggest problem is a dramatic inaccuracy in certain orientations.· It is 40 degrees off at its worst.· I made the following table of actual headings versus the readings the module gives me:
0 = heading,· compass says = 0 x = 33 y = 0
15 = heading,· compass says = 14 x = 32 y = -8
30 = heading,· compass says = 25 x = 30 y = -15
45 = heading,· compass says = 41 x = 26 y = -23
60 = heading,· compass says = 58 x = 20 y = -30
75 = heading,· compass says = 74 x = 11 y = -38
90 = heading,· compass says = 85 x = 4 y = -41
105 = heading,· compass says = 96 x = -5 y = -42
120 = heading,· compass says = 108 x = -13 y = -41
135 = heading,· compass says = 116 x = -20 y = -38
150 = heading,· compass says = 125 x = -24 y = -32
165 = heading,· compass says = 135 x = -26 y = -26
180 = heading,· compass says = 144 x = -26 y = -20
195 = heading,· compass says = 152 x = -23 y = -13
210 = heading,· compass says = 166 x = -20 y = -5
225 = heading,· compass says = 180 x = -15 y = 0
240 = heading,· compass says = 200 x = -10 y = 4
255 = heading,· compass says = 250 x = -4 y = 10
270 = heading,· compass says = 270 x =·0 y = 12
285 = heading,· compass says = 298 x = 8 y = 14
300 = heading,· compass says = 313 x = 13 y = 14
315 = heading,· compass says = 323 x = 19 y = 15
330 = heading,· compass says = 336 x = 25 y = 12
345 = heading,· compass says = 345 x = 30 y = 8
360 = heading,· compass says = 359 x = 32 y = 1
Note that the x and y values shown above·are already adjusted to calibrate the module, as per the instructions that come with the module.· I had to add 10 to the X value and subtract 2 from the y before computing the angle.· This is why 0 degrees and 270 degrees are on the money.
The·actual range of x as received from the module is -36 to +22, and the range of y is -39 to +13.· This is not a very wide range of values in my opinion.· Although·you shift in 11 bits for X and Y, the actual number of significant bits is·really only·5.
After exhausting all my ideas about what was wrong with this thing, I went out and bought another one just to see if it was the module, but it did the same thing.· I also tried sticking the·module up on a mast about 14 inches from any electronics and wrapped the motors that are even further away in that foil that is·supposed to block all magnetic fields.·· Nothing helps.· I am beginning to think it is an incompatibliity between the Javelin and the compass.·But Chris·Savage says no.·The code I am using to get the values is the following:
·· private static int readHorizPos(){
···· // averaging 10 readings to eliminate jitter effects
····· int runningTotX = 0;
····· int runningTotY = 0;
····· for( int i = 0; i < 10; i++){
······· getCompassAxes();
······· runningTotX += x; // x is global
······· runningTotY += y;·// y is·global
····· }
····· x = runningTotX / 10;
····· y = runningTotY / 10;
····· x = x + 10;
····· y = y -2;
····· return (IntegerMath.atan2(-y, x)); // Compute angle
··· }
··· private static void getCompassAxes(){
····· int statusHM55B = 0;
····· int resetHM55B = 0x0000;············ // Reset command for HM55B
····· int measureHM55B = (short) 0x8000;·· // Start measurement
····· int reportHM55B = (short) 0xC000;··· // Get status/axis values
····· int readyHM55B = 0x000C;············ // 1100 -> Done, 00 -> no errors
····· int mask = (short) 0xF800;
····· CPU.writePin(clkHM55B, false); // Initialize Clk for delivering positive pulses.
····· CPU.writePin(enableHM55B, ON);
····· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
····· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, resetHM55B);
····· CPU.writePin(enableHM55B, ON);
····· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
····· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, measureHM55B);
····· statusHM55B = 0x00;·· // Clear previous status flags
····· while(true ){··· // Status flag checking loop
······· CPU.writePin(enableHM55B, ON);
······· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
······· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, reportHM55B);
······· statusHM55B = CPU.shiftIn(dinDout, clkHM55B, 4, CPU.POST_CLOCK_MSB );
······· if(· statusHM55B == 12) break;
····· }
······CPU.delay(200); // I stuck this in to see it would help
····· x = CPU.shiftIn(dinDout, clkHM55B, 11, CPU.POST_CLOCK_MSB);
····· y = CPU.shiftIn(dinDout, clkHM55B, 11, CPU.POST_CLOCK_MSB);
····· if ((x & 0x400) != 0) x |= (short)0xF800; //range -1024 to +1023
····· if ((y & 0x400) != 0) y |= (short)0xF800; //ditto
··· }
I wrote a program·using a standard Java JDK·to check the accuracy of the atan2 function, and it is pretty accurate, deviating from the floating point calcualtions by 1.3 degrees at the most, so that is not the problem.
·
Comments
'
[noparse][[/noparse] Subroutine - Compass_Get_Axes ]
Reset········· CON····· %0000··············· ' Reset command for HM55B
Measure······· CON····· %1000··············· ' Start measurement command
Report········ CON····· %1100··············· ' Get status/axis values command
Ready········· CON····· %1100··············· ' 11 -> Done, 00 -> no errors
NegMask······· CON····· %1111100000000000··· ' For 11-bit negative to 16-bits
status········ VAR····· Nib················· ' Status flags
Compass_Get_Axes:··························· ' Compass module subroutine
· HIGH En: LOW En··························· ' Send reset command to HM55B
· SHIFTOUT DinDout,clk,MSBFIRST,[noparse][[/noparse]Reset\4]
· HIGH En: LOW En··························· ' HM55B start measurement command
· SHIFTOUT DinDout,clk,MSBFIRST,[noparse][[/noparse]Measure\4]
· status = 0································ ' Clear previous status flags
· DO········································ ' Status flag checking loop
··· HIGH En: LOW En························· ' Measurement status command
··· SHIFTOUT DinDout,clk,MSBFIRST,[noparse][[/noparse]Report\4]
··· SHIFTIN· DinDout,clk,MSBPOST,[noparse][[/noparse]Status\4]· ' Get Status
· LOOP UNTIL status = Ready················· ' Exit loop when status is ready
· SHIFTIN· DinDout,clk,MSBPOST,[noparse][[/noparse]x\11,y\11]·· ' Get x & y axis values
· HIGH En··································· ' Disable module
· IF (y.BIT10 = 1) THEN y = y | NegMask····· ' Store 11-bits as signed word
· IF (x.BIT10 = 1) THEN x = x | NegMask····· ' Repeat for other axis
· RETURN
So I think your getCompassAxes() must be
··· private static void getCompassAxes(){
····· int statusHM55B;
····· int resetHM55B = 0x0;············ // Reset command for HM55B
····· int measureHM55B =·0x8;·· // Start measurement
····· int reportHM55B =·0xC;··· // Get status/axis values
····· int readyHM55B = 0xC;············ // 1100 -> Done, 00 -> no errors
····· int mask = (short) 0xF800;
····· CPU.writePin(clkHM55B, false); // Initialize Clk for delivering positive pulses.
····· CPU.writePin(enableHM55B, ON);
····· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
····· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, resetHM55B);
····· CPU.writePin(enableHM55B, ON);
····· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
····· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, measureHM55B);
····· statusHM55B = 0x0;·· // Clear previous status flags
····· do·{··· // Status flag checking loop
······· CPU.writePin(enableHM55B, ON);
······· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
······· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, reportHM55B);
······· statusHM55B = CPU.shiftIn(dinDout, clkHM55B, 4, CPU.POST_CLOCK_MSB );
····· } while (statusHM55B != readyHM55B);
······CPU.delay(200); // I stuck this in to see it would help
····· x = CPU.shiftIn(dinDout, clkHM55B, 11, CPU.POST_CLOCK_MSB);
····· y = CPU.shiftIn(dinDout, clkHM55B, 11, CPU.POST_CLOCK_MSB);
····· CPU.writePin(enableHM55B, ON); //disable module
····· if ((x & 0x400) != 0) x |= (short)0xF800; //store 11 bits as signed word (range -1024 to +1023)
····· if ((y & 0x400) != 0) y |= (short)0xF800; //ditto
··· }
Also from the 'features' on the datasheet:
[font=Arial,Bold size=4]Features
[/font]• Sensitive to microtesla (μT) variations in magnetic field strength
• Simplifies direction by resolving magnetic field measurements into two component axes
• Good for 6-bit (64-direction) resolution measurements after software calibration
• Only 30 to 40 ms between start measurement and data-ready
• Built-in resistor protection for data pins eliminates bus conflict risks
• Compact and breadboard-friendly 0.3 inch, 6-pin DIP package
• Compatible with all BASIC Stamp, Javelin Stamp and SX microcontrollers
• Makes communication and direction calculations especially easy with the PBASIC commands
SHIFTOUT, SHIFTIN, and ATN for the BASIC Stamp 2 series of microcontrollers
which states 6bit resolution (=64) which yields range -32 to +31.
regards peter
shiftout requires data to be left shifted if less than 16 bits are outputted
··· private static void getCompassAxes(){
····· int statusHM55B;
····· int resetHM55B = 0x0;············ // Reset command for HM55B
····· int measureHM55B =·0x8;·· // Start measurement
····· int reportHM55B =·0xC;··· // Get status/axis values
····· int readyHM55B = 0xC;············ // 1100 -> Done, 00 -> no errors
····· int mask = (short) 0xF800;
····· CPU.writePin(clkHM55B, false); // Initialize Clk for delivering positive pulses.
····· CPU.writePin(enableHM55B, ON);
····· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
····· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, resetHM55B<<12);
····· CPU.writePin(enableHM55B, ON);
····· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
····· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, measureHM55B<<12);
····· statusHM55B = 0x0;·· // Clear previous status flags
····· do·{··· // Status flag checking loop
······· CPU.writePin(enableHM55B, ON);
······· CPU.writePin(enableHM55B, OFF);· // Send reset command to HM55B
······· CPU.shiftOut(dinDout, clkHM55B, 4, CPU.SHIFT_MSB, reportHM55B<<12);
······· statusHM55B = CPU.shiftIn(dinDout, clkHM55B, 4, CPU.POST_CLOCK_MSB );
····· } while (statusHM55B != readyHM55B);
······//CPU.delay(200); //not necessary
····· x = CPU.shiftIn(dinDout, clkHM55B, 11, CPU.POST_CLOCK_MSB);
····· y = CPU.shiftIn(dinDout, clkHM55B, 11, CPU.POST_CLOCK_MSB);
····· CPU.writePin(enableHM55B, ON); //disable module
····· if ((x & 0x400) != 0) x |= mask; //store 11 bits as signed word (range -1024 to +1023)
····· if ((y & 0x400) != 0) y |= mask; //ditto
··· }
So it appears your getCompassAxes() was correct, apart from the disable module line.
regards peter
Post Edited (Peter Verkaik) : 10/9/2005 5:56:24 AM GMT
Your code is functionally equivalent to my code with the exception of the one line to disable the module after getting the data.· I had that in, but I recognized that it is superfluous since the module is always disabled before restarting the process.· Dropping that line had zero effect on the result.· Using the constant 0xC and then shifting it 12 bits left is no different than starting with 0xC000, except it takes a little more code and execution time.· And as you can see, my code works fine with the exception that the values returned are skewed more or less depending on the orientation of the compass.· If I was sending it the wrong measure or reset code, I would get no results at all.
-- Don
Another major problem that I discovered with using this module is that if it is the slightest bit out of level, the results are dramatically altered. So, if you want to use it for somthing that might not stay level, you need to have an automatic leveling device holding the compass. In fact, that may be the problem I am experiencing. Maybe I should put it on a float. Of course then acceleration and deceleration would cause sloshing problems. More likely, I am going to abandon this module. I have spent way too much time trying to make it work the way I need it to work. It is a cute toy, but not practical. Wish I hadn't bought two of them! Anyone want to buy mine?
With 2 of them you could measure 3 axis (x,y,z) and compensate/measure the tilt of your robot.
(I believe)
You can calculate x and y by using the cos() and sin() methods in the IntegerMath class.
cos and sin range from -100 to 100, so calculate
xc = cos(heading); //calculated x
yc = sin(heading); //calculated y
xs = (x*100)/32; //scale measured x for heading to range -100...+100
ys = (y*100)/32; //scale measured y for heading to range -100...+100
Since tan(heading) = y/x, a small error in x, yields a large change in the tan value, and thus the
calculated heading, especially if x is small.
edit:
the 32 in the scaling should really be the measured (calibrated) value for north (which·equals
the magnetic field strength in 1uT per unit, which is the maximum absolute value for your location)
regards peter
Post Edited (Peter Verkaik) : 10/9/2005 12:18:49 PM GMT
·· I'm sorry to hear you're having problems with the Compass Module.· I really think if you could implement the calibration code, as we have done for the BASIC Stamp, then this would correct your issues.· Most compass Modules have to be calibrated at some point.· Manufacturing Processes dictate that there's going to be some deviation in the 2 devices which detect the magnetic poles.· This is especially true of those packaged in a chip package.· Now, the more expensive modules are calibrated at the factory, and usually consist of a larger board.· These modules are compensated/calibrated at the code level.· We currently do not have a Javelin Calibration program, but I will see what I can come up with.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
I did write a calibration program but it doesn't save the results to EEPROM. I generated the output to the debug window, and from that created an array of ints containing the correction value for every 15 degrees. I then wrote a getPosition method that gets the compass value and uses the adjustment array, interpolating between points, to give a best possible adjustment for any given reading. But it fails miserably if the unit is tilted even a degree or two in either axis. So, unless I do a similar calibration for every degree or two of tilt in two different axes, it is futile. And to do this would entail not only a lot of work, but also many thousands of bytes to hold all those arrays. For example, if I wanted to calibrate over +-15 degrees tilt in both x and y axes for every 2 degrees of tilt, it would result in 225 (15 * 15) arrays each containing 24 ints (assuming 15 horizontal degrees per measurement). That's 5400 measurements, creating 10,800 bytes of adjustment data. And +-15 degrees isn't much. It should really be more like +- 30 degrees, which would result in 900 arrays of 24 ints, resulting in 43,200 bytes of adjustment data. In any case, it would take me many, many hours to complete.
Yes, if I had a precision, programmable, rotatable, tiltable table, I could automate the entire thing. But the memory storage alone makes it unreasonable. Keeping the compass level is undoubtedly a better solution. Not exactly sure what the best way to do that is for a unit that can accelerate, decelerate, rapidly change direction, etc.
·· Again, I am sorry for the trouble you're having.· A gimbaled compass would be considerably more, but they tend to be more accurate, compensating for changes in axis.· Obviously building such a system would increase the cost of this unit as well.· Do both modules give you the same trouble?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
“Good for 6-bit (64-direction) resolution measurements after software calibration”
That is direction resolution (after the mathematics)
The devise have 11bit resolution as I understand it.
The unit of sensitivity is LSB/uT.
The range of measurement for magnetic field is from –180 uT to +180 uT.
In the magnetic field out of +/-180 uT, the linearity of output cannot be assured.
1 tesla = 10000 gauss. Earth's magnetic field is ~0.5 gauss.
So 0.5 gauss equals 50uT and will give the number “50” (or -50 depending on direction)
(edit)
“The actual range of x as received from the module is -36 to +22, and the range of y is -39 to +13.”
This would lead me to believe that tilt or magnetic disturbance is the problem.
(I have done both mistakes, tilting breadboard and magnetic metal nearby)
The data sheet mentions:
Sensitivity 1.0 <> 1.6 LSB/uT
Linearity -5 <> 5 %
So if the error is an offset error and and linearity error isn't there an easier way to make the compensation? And I would use three axis, but I do not know how to write the mathematics. (I would use it as a sort of gyroscope in my application)
Post Edited (diafysal) : 10/10/2005 12:06:51 AM GMT
The device clearly does not have 11 bit resolution. There are some x and y values in my earlier post that are slightly out of the 6-bit range. It is possible I posted results that were already adjusted to compensate to make North and West correct. I can re-run it to be sure, but if x or y is ever more than +-32, it is not by much - not even a full bit's worth.
Chris,
Both devices act the same. I think it is mostly a tilt problem and possibly inadequate shielding of the motors. (My wrapping of the motor compartment with shielding foil was a little sketchy.) But I did the tests with the compass 14 inches from the electronics and 18 inches from the motors and had the same problem.
I was thinking that the inaccuracy problem introduced by tilt could be solved by adding an accelerometer to the platform holding the compass. You could then control a couple servos to balance the platform. I guess that is what you meant by a gimbaled compass. Or maybe there are less complicated and less expensive ways of doing that? I think that all gimballing methods might have a problem when experiencing acceleration other than gravity's, since the acceleration of gravity can't be distinguished from the acceleration of the bot carrying the accelerometer. When the bot accelerates, you end up making the platform out of level unnecessarily. But maybe that is OK too. Maybe the compass just doesn't like acceleration, gravity or otherwise, and countering the acceleration of the bot by tilting the compass might be just what the doctor ordered. Just thinking aloud here. Sounds like doing these experiments would make a good science fair project for some high school kid.
No it has 11bit resolution BUT the earth magnetic field is to weak. I think I have about 0.4 gauss were I live (if I remember it right) and that would result in a effective resolution of -40 to +40.(quite low resolution)
Acceleration(gravity) have no effect on the compass.(Well there might be a theoretical effect, but not measurable I believe)
The problem is that the measuring device is only sensitive enough to measure the field to six bits of accuracy. So why do they bother to give you 11 bits when the top five are always zero? It is like the difference between a speedometer that reports 55 miles per hour when the actual speed is more like 55.2987 miles per hour. If they could measure the field to 11 bits they would return 11 bits of significant data and the units of sensitivity would be in some fraction of what it is now. The fact is that the device only has 6 bits of resolving power. It has nothing whatsoever to do with how weak the magnetic field is. It is a question of how sensitive the device is in measuring that field.
-- Don
Is it sufficient to compensate for offset and scale error?
x = x + offsetX
y = y + offsetY
x = x * scaleX
y = y * scaleY
And could someone do the math/trigonometry for using tree axis (x y z).
I'm a bit curious about how it is done.
Per you last post, where are you getting a scale value?
·· Please note that putting a strong magnetic field near the compass would likely permanently damage it (Affect it's accuracy in a BIG way)!· =(
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
x -28 to 32
and
y -26 to 28
then:
offsetX = -2
scaleX = 1
offsetY = -1
scaleY = ~ 1.11
So before one would calculate the angles the raw data would be corrected for offset and scale error. But I'm not sure if this is sufficient or if there are other types of errors. I have not tested my devise for accuracy (yet).
For example an aeroplane going west or upside down going east could give the same values on the sensor(a loping could give the same results).
A car with a 2-axis sensor tries to go northwest. If it tilted to the left (larger tires on the right side?) then it would deviate (to west ?).
A 3-axis magnetic sensor can tell the direction of the magnetic field but I'm not sure how(if possible) to mathematically “gimbal” a compass. Maybe it's not possible without knowing the gravity vector.(and then only while standing still)
http://www.ssec.honeywell.com/magnetic/products.html
regards peter
·
regards peter
·
into account. If pitch and roll angles are 0, then X' = X and Y' = Y.
Equation 4 calculates the actual pitch and roll angles using measured magnetic field strength on
X, Y and Z axis. The HM55B only supplies X and Y axis values.
regards peter
I know that the HM55B only supplies X and Y, but I was looking at a 3-axis solution that did not involve the HM55B.
(as long as X, Y and Z have equal sensetivity)
All values (eg. angles) are relative to the absolute value SQR(X*X + Y*Y + Z*Z)
The absolute magnetic field strength SQR(...) is·the same no matter
how a 3-axis sensor is oriented (at the same spot).
regards peter
"The Honeywell HMC6343 digital compass circuit is three-axis magnetic and three-axis accelerometer compassing solution with tilt compensation."
"The HMC6343 contains all sensors, microcontroller, and analog support circuits; plus all the firmware for heading computation and ard-iron calibration."
But I think the price will reflect the competence.
To be honest, I really don't know if you can substitute magnetic field values (in units of gauss) for acceleration values in equation 4 of the document you referenced. I kind of doubt it though. One is the result of the effect of gravity and the other is the result of the effect of the Earth's magnetic field. I suspect more likely you need to get the known magnetic inclination value for your longitude and latitude and subtract that from the Z value of the magnetomoter reading to get tilt. And then you can use tilt to correct the x and y readings per the other equations in that document. But I am just guessing.
-- Don