Hi everyone, I need some help regarding IOIO and I2C.

I'm working trying to read some data from an MPL3115A2 Breakout Board 
(Altitude / Barometric / Temperature sensor), device slave address is 0x60 
(7-bit), interface frequency set first at 100 KHz, now at 400 KHz (max. 
frequency admitted, according to datasheet). Since it is a breakout board, 
I connected directly the board to the IOIO (3.3v + GND, and SCL in pin 25, 
and SDA in pin 26. I didn't use other I2C because they're used already) 
without using pull-up resistors between the board and the IOIO in the clock 
and data lines. Meter shows voltage values up to 3.3v, so I assume that 
that IOIO pins (25 and 26) work at 3.3v maximum when in I2C mode using 
TwiMaster interface and using I2C voltage values, not the SMBus ones. Is 
that assumption correct? (I don't know very much of open-drain mode and 
related topics). I can read random binary data from the sensor but I 
couldn't make it readable, e.g. transforming some binary value in an 
altitude value. I'm assuming that sensor comes factory-calibrated.

My question is the following: when I use the writeRead instruction, how 
does IOIO know which parts of the request are register addresses where I'm 
going to write to, which parts are values that I'm going to write into 
those registers, and which parts are register addresses where I just need 
to read their value? I'm assuming that I can make the three operations in 
the same instruction, the writing and querying operations first, and then 
the reading operations.

The MPL3115A2 datasheet is located here: 
http://cache.freescale.com/files/sensors/doc/data_sheet/MPL3115A2.pdf
For more information about the sensor/board: 
https://www.sparkfun.com/products/11084 (includes schematics)

This is my initialization code (executed in the setup() method):

private final byte altAddress = (byte)0x60;
boolean transactResult;
...

request = new byte[]{(byte)0x26,(byte)0b10000010};//First byte is a 
register adress, second byte is data being written there
response = new byte[1];
transactResult = sensAltitude.writeRead(altAddress, false, request, request.
length, response, 1);
if(!transactResult){//If transactResult is false, show error message
    System.out.println("Error while configuring the sensor.");
}else{
    System.out.println("Setup Values:"+ new String(BinaryCodec.toAsciiString
(response)));//BinaryCodec is from Apache Commons
}

//Same lines as before but information written now has the last bit set to 
1 (sensor requirement)
request = new byte[]{(byte)0x26,(byte)0b10000011};//First byte is a 
register adress, second byte is data being written there
response = new byte[1];
transactResult = sensAltitude.writeRead(altAddress, false, request, request.
length, response, 1);
if(!transactResult){//If transactResult is false, show error message
    System.out.println("Error while configuring the sensor.");
}else{
    System.out.println("Setup Values:"+ new String(BinaryCodec.toAsciiString
(response)));//BinaryCodec is from Apache Commons
}


And this is my loop code. It just reads from register 0x01 through 0x05 
where altitude and temperature data are. Then I just print the raw bits 
from the first three bytes of the response.
0x01 is the MSB of the Altitude/Pressure Data
0x02 is the CSB of the Altitude/Pressure Data
0x03 is the LSB of the Altitude/Pressure Data. According to the datasheet, 
only bytes 7-4 are used, as the LSB only represents the fractional part of 
the altitude.
0x04 is the MSB of the Temperature Data.
0x05 is the LSB of the Temperature Data.

I assume that the bits inside each byte of the response are in order (from 
most significant to least significant) and there is no need to flip the 
order, and the bytes inside the response are in the same order as bytes 
requested (0x01, 0x02, etc.). According to the datasheet, only 0x01 and 
0x02 are the integer part of the altitude and is represented in 2's 
compliment (total value, including fractional part, takes 20 bits, but the 
last 4 bits are unsigned).

request = new byte[]{(byte)0x01,(byte)0x02,(byte)0x03,(byte)0x04,(byte)0x05
};response = new byte[5];//3 bytes para Altitud, 2 bytes para 
TemperaturasensAltitude.writeRead(altAddress, false, request, 0, response, 
response.length);byte[] altBits = new byte[3];altBits[0] = 
response[0];altBits[1] = response[1];altBits[2] = response[2];
    System.out.println("RAW ALT BITS:" +  BinaryCodec.toAsciiString(altBits
));ByteBuffer bb;//To perform byte-to-Short conversionbyte[] wholeAltBytes 
= new byte[2];wholeAltBytes[0] = request[0];wholeAltBytes[1] = request[1];
bb = ByteBuffer.allocate(2);bb.clear();bb.put(request[0]);bb.put(request[1
]);bb.rewind();
wholeAltitude = bb.getShort();    System.out.println("WHOLE ALT: " + 
wholeAltitude + " m");



The results are the following. For the raw bits of ALT, I separated them in 
three 8-bit bytes, believing that the first will be MSB, the second CSB and 
the last LSB regarding the Altitude values. Then I wrote the transformed 
value (bits to short) of the MSB + CSB bits that the getShort() method of 
the ByteBuffer class provides. So the result format, for a better reading 
here is:

Altitude MSB bits | Altitude CSB bits | Altitude LSB bits  --- Short 
integer representing the "converted" value taken from the MSB and CSB bits. 
Values were obtained while I was moving the setup up and down more than 30 
cm (sensitivity range for altitude, I move it up and down about a meter). 
If I interpreted correctly, the Altitude LSB should be something like 
abcd0000, where a,b,c and d could be 0 or 1.

10110001 | 00000000 | 00000000  -- 258
10101110 | 00000000 | 00000000 -- 258

I don't know why the short value always is 258. Not 257 or 259.
So, where is the LSB? Why the MSB shows those values? They, apparently, 
have no sense, even if that is a negative integer!

The values are doing between those two values. So I chose to print ALL the 
bits in the response (MSB,CSB,LSB bytes of Altitude, MSB and LSB bytes of 
Temperature, same format):

00010101 | 01010000 | 10110101 | 00000000 | 00000000
00010101 | 11010000 | 10110011 | 00000000 | 00000000
00010101 | 01000000 | 10110100 | 00000000 | 00000000
00010101 | 00010000 | 10110011 | 00000000 | 00000000

It seems that the second byte has the four last bits always in zero. Is 
that the Altitude LSB? Why is it there?

I have some knowledge/experience in Java, but I'm working with IOIO since 1 
month or a bit more only, and with I2C just 4 or 5 days. This is the only 
sensor in my setup that uses that protocol, and all examples for this 
sensor are Arduino-based, so I don't know what is going on when I perform a 
writeRead. If I move the sensor, raw binary data seems to change, but I 
can't interpret that. Excuse me if I made some grammar mistakes, English is 
not my mother tongue.

If anyone is wondering, I don't have a oscilloscope but maybe I ask for one 
as last resort. I'll need help trying to use it, though.

Thank you in advance!

-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/ioio-users.
For more options, visit https://groups.google.com/d/optout.

Reply via email to