Magnetometer HMC5883L problems with IOIO

53 views
Skip to first unread message

heikki...@kolumbus.fi

unread,
Oct 15, 2015, 7:52:38 AM10/15/15
to ioio-users
Hi !
I am trying to use HMC5883L magnetometer sensor like in thread:

https://groups.google.com/forum/#!msg/ioio-users/V6riKrVsZnQ/JcEHz_u_an4J

I have connected SDA and SCL to IOIO pins 4,5 and power to IOIO 3.3V. I also have two 10kOhm pull-up resistors connected between IOIO 3.3v and SDA,SCL pins, double checked that wiring is ok.

Then in my IOIO setup TWI0 is opened, like this:

ps.twi_ = ioio_.openTwiMaster(0, TwiMaster.Rate.RATE_400KHz, false);

in my IOIO loop:

Boolean success;
byte [] acc = new byte [6];
success = ps.twi_.writeRead(0x1E, false, new byte[]{0x3C,0x02,0x01}, 2, acc,0); // single measurement mode
success = ps.twi_.writeRead(0x1E, false, new byte[]{0x3C,0x03}, 2, acc, 0); //register pointer to 03
success = ps.twi_.writeRead(0x1E, false, new byte[]{0x3D,0x06}, 2, acc, 6); // read 6 registers

if (success) {
int dataX = (acc[0]) + ((acc[1]) << 8);
int dataY = (acc[2]) + ((acc[3]) << 8);
int dataZ = (acc[4]) + ((acc[5]) << 8);
DisplayInfo(260, null, null, "X:" + String.valueOf(dataX) + " Y:" + String.valueOf(dataY) + " Z:" + String.valueOf(dataZ));
}

This info taken from the datasheet: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Magneto/HMC5883L-FDS.pdf
The problem is that data registers acc always have 6 zeros (0). So no data is never read.
What I am doing wrong here, have tried to find a working example using IOIO, but all seems to be with Arduino.
I have tried to use continous measure and single read mode, with no success. writeRead always returns success=true, but no data.
Can anybody help me, thanks !
Is there anywhere documentation, what the parameters in writeRead really mean ? Especially the lengths, is the first number of bytes to write, and the last length:
number of bytes will be read



Tyler

unread,
Oct 15, 2015, 1:41:26 PM10/15/15
to ioio-users
Hello, 

Tryout the code changes below.

...
ps
.twi_.writeRead(0x1E, false, new byte[]{0x3C,0x02,0x01}, 2, acc, 6); // Remove this line (it's set by default)
ps
.twi_.writeRead(0x1E, false, new byte[]{0x3C,0x03}, 2, acc, 6);  // Use this line
ps
.twi_.writeRead(0x1E, false, new byte[]{0x3D,0x06}, 2, acc, 6);  // Delete this line
...

As I understand the IOIO's implementation of I2C, one writeRead() is sufficient to perform a read, and a write operation to a single slave device on the I2C bus. By sending the above, you are requesting to read from register 0x03. Simply specifying a byte[] and a length is sufficient for writeRead() to automatically wait for a response from the slave and put the reply into the byte[] (acc).

Your first writeRead() is unnesessary because single read mode is set by default on the HMC5883L.
Your second writeRead() is about right. Modify as above.
Your third writeRead() attempt looks close, but based on what I read, that tells the slave that you would like to write to register 0x06. 

Hopefully that all makes sense,
Tyler

heikki...@kolumbus.fi

unread,
Oct 16, 2015, 4:57:37 AM10/16/15
to ioio-users
Thanks Tyler for your response, unfortunately it did not help.
The data registers (acc) are still zero.
I also tried this to read the deviceId:
success = ps.twi_.writeRead(0x1E, false, new byte[]{ 0x3C, 0x0A}, 2, acc,3); //trying to read deviceId from register 10

and get 3 zeros. I would expect some nonzero value.

If I initialize acc byte array with something else before calling writeRead the IOIO writeRead reads zeros.
Could it be that the sensor is damaged ?
If I unplug the power 3.3v from the sensor, I get zeros. The same thing if I remove the pull-au resistors.
But if I unplug SDA or SCL, writeRead returns false (otherwise true).
How could I verify that sensor works ? Can I "factory reset" it ?

Tyler Trombetta

unread,
Oct 16, 2015, 11:50:58 AM10/16/15
to ioio-...@googlegroups.com

I went back and re-read the data sheet more thoroughly, and it appears I was wrong. I just found the example on page 18 that details how to take a single measurement. Looking at your first post, I see that's where your code comes from. I now think you did everything right, except for waiting 6 ms for the data to be placed into the data registers. 

So, I would revert back to your first code attempt, but place the line:
Thread.sleep(6);
after writeRead() command #2, to have the IOIO wait 6 ms for the data to be available. Then you should be able to properly read the data.

It can't hurt to write to the configuration registers before the measurement (as in the example), so I would recommend that as well.  Sorry to lead you down the wrong trail.

Tyler

Ytai Ben-Tsvi

unread,
Oct 16, 2015, 12:04:04 PM10/16/15
to ioio-...@googlegroups.com

Did you remember pull up resistors on the bus?

--
You received this message because you are subscribed to the Google Groups "ioio-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ioio-users+...@googlegroups.com.
To post to this group, send email to ioio-...@googlegroups.com.
Visit this group at http://groups.google.com/group/ioio-users.
For more options, visit https://groups.google.com/d/optout.

heikki...@kolumbus.fi

unread,
Oct 18, 2015, 10:34:22 AM10/18/15
to ioio-users
Yes, I have two pull up resistors (10 kOhm) from pins 4 and 5 to 3.3V(IOIO) is that correct way of connecting them ? When I measure the resistance connected I get about 6.6 kOhm.
I don't have any delays between writeRead commands, but I am running the code with debugger, and all reads from the sensor always return 0's.
I also tried to change
TwiMaster.Rate.RATE_100KHz
when opening twi-line, but the same result

Ytai Ben-Tsvi

unread,
Oct 19, 2015, 1:44:56 PM10/19/15
to ioio-...@googlegroups.com
OK, I got around to reading the datasheet. The 0x3C/0x3D that you're sending is part of the address. You shouldn't send it. Also, make sure you check the return value of writeRead() or else you'd be reading garbage.
Reply all
Reply to author
Forward
0 new messages