HMC6343 compass

The refresh rate is refering to the speed the data is available (internal overheads)

The data rate is the speed of the bus (SDA,SCL) all I2C devices run at either 100khz or 400khz This is settable on the hardware… I2CDevice.Configuration.ClockRateKhz()

If the data sheet recomends 10k resistors its obviously a 100khz device… But the phillips recomendation for I2C bus pullups is 1.8k to 4.7k on all devices… and they made it.

If the resistors are missing the bus is floating and not pulled high.
The lower the resistance the quicker the voltage can return to high from low (cleaner pulses)
If you go too low you get ringing (bit banging noise) and the timings all off
If you go too high the slew rate is to high and you miss data…

Its up to you. All I can do is offer my own experience with I2C busses

update: so far no joy, i switched the resistors to the 10k and put in the capacitor and it still gives me the same data. i get the 6 bytes of data with them being defined in the datasheet as such:
“Send 0x33 and clock back six more response Bytes from the HMC6343. These will be the Heading, Pitch and Roll Byte pairs; binary format in tenths of a degree with 2s compliment on pitch and roll angles. (0 to 3600 heading, ±900 pitch, and ±900 roll)”

but im not really sure what that means, what does the first byte represent if the first 2 are heading?
for example(look at my screen capture):
byte[0]: 1
byte[1]: 185

how are these 2 numbers combined to create a value that is between 0 and 3600? in pitch and roll i know that the first byte is the + and - indicator but im not sure what the first byte is supposed to indicate, i have seen it as 0, 1, and 2 and the byte[1] up to ~600

Greg, can you try Ian’s failing code? I think that’s the only way we are going to find the issue. We know Greg has a good sensor.

I can’t see the rest of your code

Did you select the output mode first 0x32,0x50 to enable the heading ,pitch & roll

I assumed you did or there wouldn’t be valid data in your buffer.

Do you get a heading other than 44.0 degrees when you turn it?
Bad calibration has a habit of going from say… 10 degrees through to say 80 then for no apparent reason goes down toward 10 again ie… not a full circle (and certainly not round)

IanR: it does do other angles but like i said never out of a certain range (i.e never greater than ~ 80) and the first bit never gets higher than ~600 (when its supposed to get up to 3600). its performance is very close to what you said, not a full circle and not round.

I think you may need to make a slightly longer lead…

Put it in the center of a swivel chair send command “C” do two revolutions (any direction) within three minutes (steady movement then send command “E” and see if it perfoms better…

I believe this chip has about four output modes 0x40,0x45,0x50 and 0x55 I think i defaults to 0x40 which if my memory serves me right is acceleration data (same format ) which would also give you this kind of reading… the reason I mention it is… if the command 0x32 …0x50 isn’t received properly, it will alway send you the 6 bytes of acceleration data, this will only go to 90.0 degrees max as its used for tilt compensation…

All Im trying to say is is the communication correct if the domino is set to 400khz data rate the compass WILL struggle, but the domino can recieve perfectly well at that speed.

I hate saying this but the smaller chip I’ve bought works fine…If I had a tilt compensated unit I would write a driver for you, then you could tell easily where the problem lies

Cheers Ian

I have just analysed Gregs HMC6343 driver

He sets the devie address to 0x32 (correct) and the divides it by 2 …

const ushort HMC6343_ADDRESS = 0x32 >> 1;

Why ? Does the “i2cdevice class” shift in the last byte depending on read or write?

It seems to work without the shift…

The address thing took me a LOOONG time to figure out. I was sort of flailing in the dark about it. I finally found a project elsewhere using the 6343 and walked through the code - the only difference was the address.

Now - as I recall from the spec sheet the 6343:

I remember when I was trying it with 0x33 I got nothing off the sensor, 0x32 at the time got nothing so I did some more searching and found an example that did the bit shift so I figured I’d give it a try - and it worked.

The example C code I’ve seen doesn’t do it that way but I wanted to go with what worked.

IanR: he is right (although i dont get why), i tested using 0x33 and 0x32 without the shift and get nothing back in both cases. my next step is to attempt to write a calibration function into his driver and test to see if that makes a difference. my problem now is the calibration instructions say that i need to rotate 360 degrees around the Y axis (no problem on a swivel chair) and the 360 degrees around the Z axis (which would be hard on a swivel chair unless i turn the compass on its side). i am not sure if the process of turning on its side during calibration will mess anything up.

GregO: this driver tested with the full rotation range for you (0-360)? did you ever have to do the calibration routine? why did you stop using the HMC6343?

thanks again guys for passing along your expertise, i am sure im not the last one who will hit these issues on the 6343. having these questions and answers on record will go a long way helping the next guy im sure. I wrote sparkfun an email but never got a response :frowning:

one additonal thing i have noticed is that moving the compass around and then bringing it back to the same angle with show the same (albeit wrong) heading angle. for exmple i start by pointing the compass north and it shows 54 degrees. i then rotate it all the way around (360 degrees) back to north and it shows me ~54 degrees. it also give me ~54 degress at due south as well. what i am trying to say is that it appears giving me magnetic data not random or accel data.

see what sucks about the forums is that i have questions that i want to ask specific users. what i need is a messaging feature so that when IanR or GregO logs in they see my message instead of just hoping they come back and reread this post. the chat feature doesnt really help because i dont think very many people use it and they would have to be on and logged in at the same time as me.

what i would suggest is using something like i do on my sites where you can click on a users name, see posts and comments that they have done, see projects that they are working on, as well as send them a private message. it will build community faster than this which only allows users to communicate publicly.

Sorry about not being available but my customer (the one I’m making this unit for) was with me all day today, so yesterday I was preparing all as necessary…

I had several minutes this afternoon to check things out…

Doesn’t matter a wallop about the pullup resistors atall! There are 2.2k pullups already installed on the board…

When I put the device in 5hz mode the compass is very erratic simular to what you got with the 6343 although mine is the smaller device, 6352. When I increased the allotted time for sampling ie… mode 1 and requested a reading every 333ms (3hz) it was considerably better I placed the unit on a small shoe box and rotated though 360 degrees, it wasn’t perfect but I did get the full 360 and north really was north (marked on thePCB)

Do remember that I use the Cobra, but I believe the domino is the same, and have a cool compass dial bitmap, being rotated via the built in rotateBitmap function, with a pointer bitmap mask placed on top…

I didn’t need to calibrate atall. What size decoupling capacitor did you end up with for the power rail… This would have to be VERY close to the Vcc and Vdd pins.

Cheers Ian

Ian: i am using a 1.0 uF cap and have it wired right between the vcc and vdd pins, i am actually a little unsure of why they would not include the resistors and capacitor on the board? wouldnt that simplify the connections to it?

anyways its still giving me bad data, can someone explain how the first 2 bytes of the data returned can be used to infer heading. i need a math explanation of how 2 bytes are converted to MSB and LSB and how those are converted into a value for heading that is 0-3600

also, are you using the driver made by GregO?

Yes! I’m using the driver from Greg… but I made changes to the I2CTransaction as it was developed on a lesser interface…

An example

6 bytes (0x01,0xE4,0x01,0x54,0x02,0x10)

they equate to
first two… (high byte) = 0x1 (low byte) = 0xE4 … 1 * 256 + 228 = 484 heading 48.4 degrees …
Second two… (high byte) = 0x1 (low byte) = 0x54 … 1 * 256 + 84 = 340 X raw data
Third two… (high byte) = 0x2 (low byte) = 0x10 … 2 * 256 + 16 = 528 Y raw data

therefore say 215.5 degrees would equate to first byte = 8 second byte = 107

I’m not a very good teacher but you should see that the first byte is a power of 256 and the second is the remainder…

Cheers Ian

IanR: awesome, thanks for the explanation, i wasnt able to understand from the code how the translation betweeen the bytes and the heading was being done, but now i get it, can you post the changes you made to the I2CTransaction?

I dont think it will make much difference but you can no longer reference by instance but by type


 //Init I2C Device & Read/Write Transactions
        I2CDevice cmp;
        I2CDevice.I2CWriteTransaction writeTrans;
        I2CDevice.I2CReadTransaction readTrans;

        public Compass()
            cmp = new I2CDevice(config);
            writeTrans = cmp.CreateWriteTransaction(A);
            readTrans = cmp.CreateReadTransaction(inBuffer);


 //Init I2C Device & Read/Write Transactions
        I2CDevice cmp;
        I2CDevice.I2CWriteTransaction writeTrans;
        I2CDevice.I2CReadTransaction readTrans;

        public Compass()
            cmp = new I2CDevice(config);
            writeTrans = I2CDevice.CreateWriteTransaction(A);
            readTrans = I2CDevice.CreateReadTransaction(inBuffer);

I had to do it… microsoft have changed it. Version 4.1.2821.0

Update: sparkfun got back to me and asked that i send the 6343 back to them so they can test it on their board. hopefully the turn around time wont be too long. in the mean time i think i will switch back over to testing the 9DOF IMU for the orientation. i tested that already with a small serial communication app ithat i wrote. next stop is just getting it to run on the domino using the same logic. ill post whatever sparkfun sends me back. thanks again IanR for your help!

Yes! I’ve also been checking this out.

The HMC works… sort of ok, but for the precision I need I think using a gyro may help a great deal. When I move the compass left or right the update is far to slow for my needs.

I hope they can help… One thing though. The address Greg uses is shifted right!! but when we ask on the 6352 for the heading we send,the 0x42 command before we read! This is the same as the address… I personally think this is only addressing the device once and the default data is being sent in my case heading… in your case exel data… Thats why my reading is slow…

Cheers Ian