Problem with reading I2C

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

Problem with reading I2C

Postby matejdro » Wed Mar 14, 2012 9:20 am

Hello!

I have I2C compass sensor, which I can't get to work properly.

Compass automatically sends data, when you connect to it, which means that I just have to send something to it and then I retreive 10-bit number (split into 2 bytes).

Here is the code I have:
Code: Select all
I2CPort i2cport = (I2CPort) SensorPort.S3;
byte[] input = new byte[2];
i2cport.i2cTransaction(0x42, new byte[] {0x00}, 0, 0, input, 0, 2);
System.out.println(new DataInputStream(new ByteArrayInputStream(input)).readUnsignedShort());


However, value seems to be a bit jumpy. I printed some more info on screen and figured out that second byte won't go over 127. It will go to 127 and then skip to 0. But it also won't return any negative numbers, so signed/unsigned is not a problem. It's like first bit is completely ignored. Here is RobotC code that works without problems on same sensor:

Code: Select all
   ubyte received[2];
   byte message[2] =
   {
      1,                 
      0x42               
   };

   while(nI2CStatus[I2Cport] == STAT_COMM_PENDING){}   
     sendI2CMsg(I2Cport, message[0], 2);             

   while(nI2CStatus[I2Cport] == STAT_COMM_PENDING){}   
     readI2CReply(I2Cport, received[0], 2);             

   int result = 256*message[0] + message[1];             //Here is the proper result that is not jumpy


Any idea what could be wrong?
matejdro
Novice
 
Posts: 54
Joined: Wed Mar 14, 2012 9:10 am

Re: Problem with reading I2C

Postby skoehler » Wed Mar 14, 2012 9:27 am

Hmm. Your code to convert the bytes to an int is not ideal. But it should work. Try EndianTools.decodeUShortBE(input, 0); and see if that improves anything.
Also check the return value of i2cTransaction for errors.
I'd also like to know which I2C compass you're using.
skoehler
leJOS Team Member
 
Posts: 1349
Joined: Thu Oct 30, 2008 4:54 pm

Re: Problem with reading I2C

Postby Aswin » Wed Mar 14, 2012 5:56 pm

Hi,
What compass are you using?

Two questions come to my mind. What is the byte order, MSB LsB or LSB MSB? Which bit holds the sign, is this the first bit of the MSB as would be the case in a 16 bit value or is this the seventh bit of the MSB? If it is not the first bit you will have to manually correct the integer value. The accelerometer of The IMU sensor from Dexter Industries also provides a 10 bit value. The sign bit of this sensor is not the first bit. So you could look at this driver as an example of how to deal with this.

Code: Select all
public void fetchRawAccel(int[] ret) {
288   getData(ACCEL, raw, 6);
289   for (int i = 0; i < 3; i++) {
290   ret[i] = ((raw[i * 2 + 1]) << 8) | (raw[2 * i] & 0xFF) & 0x03ff;
291   if (ret[i] > 512)
292   ret[i] -= 1024;
293   }
294   // ret[0]=-ret[0];
295   // ret[1]=-ret[1];
296   }
My NXT blog: http://nxttime.wordpress.com/
Aswin
leJOS Team Member
 
Posts: 186
Joined: Tue Apr 26, 2011 9:18 pm
Location: Netherlands

Re: Problem with reading I2C

Postby matejdro » Wed Mar 14, 2012 8:55 pm

It's HMC6352 compass. It sends unsigned MSB LsB. Problem is that second number(input[1]) never goes beyond 127 or less than 0.
matejdro
Novice
 
Posts: 54
Joined: Wed Mar 14, 2012 9:10 am

Re: Problem with reading I2C

Postby skoehler » Wed Mar 14, 2012 9:04 pm

matejdro wrote:It sends unsigned MSB LsB. Problem is that second number(input[1]) never goes beyond 127 or less than 0.


In Java bytes are signed. So if input[1] goes below zero, that is perfectly normal! Also, input[1] cannot become larger than 127 - it is impossible, since in Java, bytes range from -128 to 127.

That you believe, that input[1] goes beyond 127 leads me to the conclusion, that you're the victim of another common misconception. You're using LCD.drawString, but you don't take into account that LCD.drawString will not clear the digits that are already in the screen. So "overdrawing" 127 with 30 will lead to 307 on the screen. Use System.out.println() instead of LCD.drawString() for your debug output, or use LCD.clear() to clear the LCD before your calls to drawString.

Also try EndianTools.decodeUShortBE(input, 0); as I suggested earlier and avoid creating a new array every time your query the sensor for better performance.
skoehler
leJOS Team Member
 
Posts: 1349
Joined: Thu Oct 30, 2008 4:54 pm

Re: Problem with reading I2C

Postby matejdro » Wed Mar 14, 2012 9:16 pm

It does NOT go bellow zero OR above 127. And check first post, I'm using System.out.println.

I will try your solution as soon as I can.
matejdro
Novice
 
Posts: 54
Joined: Wed Mar 14, 2012 9:10 am

Re: Problem with reading I2C

Postby skoehler » Wed Mar 14, 2012 9:48 pm

matejdro wrote:It does NOT go bellow zero OR above 127. And check first post, I'm using System.out.println.

OK sorry. I was wrong.

In the meantime, I have taken a look at the datasheet:
http://www51.honeywell.com/aero/common/ ... MC6352.pdf

I assume you have told the sensor to enter continuous mode? Also, Example 2 is completely confusing, since the first byte is 0x55 and the second is 0x00. But if the value is 10 bit, then the MSB will range from 0 to 3 and 0x55 would be out of range.

For now, I'm just puzzled.
skoehler
leJOS Team Member
 
Posts: 1349
Joined: Thu Oct 30, 2008 4:54 pm

Re: Problem with reading I2C

Postby matejdro » Wed Mar 14, 2012 10:23 pm

Yes, it is in continuous mode. As I said, RobotC code works, so there is nothing wrong with NXT or sensor.

I have also linked to another datasheet two posts above. Maybe this one is more clear?
matejdro
Novice
 
Posts: 54
Joined: Wed Mar 14, 2012 9:10 am

Re: Problem with reading I2C

Postby gloomyandy » Thu Mar 15, 2012 12:00 am

Are you sure the robotic code is correct? It seems to be reading the results into a buffer called received but then extracting the data from the buffer called message.

Also have you tried printing out the value in the two reply bytes rather than printing the processed results what values do they have in them? Oh and make sure you check the return value from the i2c call it may be that this is failing. In which case the return values will be invalid. What i2c mode are you operating the sensor in?
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3630
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Problem with reading I2C

Postby matejdro » Thu Mar 15, 2012 7:05 am

I made mistake in RobotC code when translating (I translated variable names to English, so it's easier to understand). Result should sum received[] variable, not message[].

I'm already printing out each byte. That's how I found out about not going bellow 0 problem in the first place.

I will try checking output when I get into classroom. Here is my port initialization:

Code: Select all
SensorPort.S3.setTypeAndMode(SensorPort.TYPE_LOWSPEED_9V, SensorPort.STANDARD_MODE);


LEGO_MODE have same symptoms. In RobotC, mode is set to "Custom 9V", so my guess is that LOWSPEED_9V is closest one.
matejdro
Novice
 
Posts: 54
Joined: Wed Mar 14, 2012 9:10 am

Re: Problem with reading I2C

Postby matejdro » Thu Mar 15, 2012 10:06 am

i2cport.i2cTransaction returns 2
matejdro
Novice
 
Posts: 54
Joined: Wed Mar 14, 2012 9:10 am

Re: Problem with reading I2C

Postby Aswin » Thu Mar 15, 2012 10:06 am

I think it is better to try the compass in query mode at first. I have not yet seen a sensor to operate with continious mode. Not only does the sensor take continues measurements. It also sends them over to the master. Lejos expects a fixed number of return bytes, not a continuous stream.
My NXT blog: http://nxttime.wordpress.com/
Aswin
leJOS Team Member
 
Posts: 186
Joined: Tue Apr 26, 2011 9:18 pm
Location: Netherlands

Re: Problem with reading I2C

Postby skoehler » Thu Mar 15, 2012 10:27 am

Aswin wrote:I think it is better to try the compass in query mode at first. I have not yet seen a sensor to operate with continious mode. Not only does the sensor take continues measurements. It also sends them over to the master. Lejos expects a fixed number of return bytes, not a continuous stream.

Which particular part of the datasheet leads you to the conclusion that the sensor sends a continuous stream?
skoehler
leJOS Team Member
 
Posts: 1349
Joined: Thu Oct 30, 2008 4:54 pm

Re: Problem with reading I2C

Postby gloomyandy » Thu Mar 15, 2012 10:42 am

So are you sending any configuration commands to the device (to put it into continuous mode)? If so can you post both your code and the robotc version... You may also want to try using high speed mode, as this will also enable pulse stretching for the device, it may be that it is not always ready to send the data when we ask for it.

Oh and can you provide a sample of the actual values read from the device and the associated return value from i2c_transaction. I'd like to see that data pattern as the value switches from just below 127 to just above (or in your case I assume to 0). When the first byte changes from 127 to 0 does anything happen to the other byte?

Oh and is this a home built sensor? If so what pull up resistors are you using with it? What port are you trying this on? Can you try it on port 1 and on port 4 and report any differences... Oh and what version of leJOS are you running, if you are not using the very latest build can you try it again with that. I assume your code is running on the NXT and not via the PC side interface?

Andy
Last edited by gloomyandy on Thu Mar 15, 2012 6:23 pm, edited 1 time in total.
Reason: corrected post should have read "not via the PC...."
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3630
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Problem with reading I2C

Postby Aswin » Thu Mar 15, 2012 5:49 pm

skoehler wrote:
Aswin wrote:I think it is better to try the compass in query mode at first. I have not yet seen a sensor to operate with continious mode. Not only does the sensor take continues measurements. It also sends them over to the master. Lejos expects a fixed number of return bytes, not a continuous stream.

Which particular part of the datasheet leads you to the conclusion that the sensor sends a continuous stream?


1. There are no measurement registers according to the datasheet.
2. Measurements are returned after sending a (any?) command according to the first post.
3. There is no need to send another 'A' command after entering continuous mode.
Continuous Mode: (Operational Mode=2) The HMC6352 performs continuous sensor measurements and data computations at selectable rates of 1Hz, 5Hz, 10Hz, or 20Hz, and updates the output data bytes. Subsequent “A” commands are un-necessary unless re-synchronization to the command is desired. Data reads automatically get the most recent updates. This mode is useful for data demanding applications.


These three facts made me conclude this. Still I might be wrong. But what is the advantage of continuous mode if I am?
My NXT blog: http://nxttime.wordpress.com/
Aswin
leJOS Team Member
 
Posts: 186
Joined: Tue Apr 26, 2011 9:18 pm
Location: Netherlands

Next

Return to NXJ Software

Who is online

Users browsing this forum: No registered users and 2 guests

more stuff