I2C Class Issues

Disclaimer: I’m aware that the I2C class states “This class is intended to be used by sensor (and other I2C device) drivers. It probably should not be used directly.”

We have been playing with the I2C class a fair amount lately and I wanted to share those results with others and see if anyone else can confirm some of these odd behaviors. I’m not sure if its just the device we are using or if several of the class methods are really broken.

We have a Lidar Lite v3 plugged into the kOnBoard I2C port. We have the Logic 4 as a scope/logic analyser. We have a working Pixy that we add to the bus, adding the Pixy doesn’t change the behavior.

Class functions/members/methods:

AddressOnly()  // Doesn't appear to work at all
Transaction() // Write portion might work, but it reads back the same value all the time
Read() // reads back the same value all the time

ReadOnly() // works fine
WriteBulk() // Works fine
Write() // Works fine, but requires a two byte write

It appears as if the Read() and Transaction() always return the first value returned by the device. I can confirm this is the pattern on the bus, due to the logic analyser. So the problem has to be either the SDA pin is being driven by the RoboRio (I2C Slave Periph is active on the same pins) or somehow the Start/Stop/ReStart/ACK sequence is not being handled correctly and the Lidar gets stuck in some way that repeats the answer to the first request…which is really really weird.

A few specific questions:
1.) Can anyone else confirm that AddressOnly() doesn’t work at all?
2.) Has anyone seen issues with “addressed” reads from I2C devices? (Pixy uses ReadOnly())

More generally, does anyone have experience with this type of behavior? Any other thoughts?

We were able to successfully read and write to the Lidar with the following code snippet (utilizing only “working” methods):

#define LIDAR_I2C_DEFAULT_ADDR           0x62
I2C* i2c_Lidar; //Declare i2c for Lidar
   i2c_Lidar = new I2C(I2C::Port::kOnboard, LIDAR_I2C_DEFAULT_ADDR); //(I2C::Port::kOnboard or kMXP, Pixy Address)
...
      i2c_Lidar->Write(0x00, 0x00);
      Wait(.025);
      i2c_Lidar->Write(0x00, 0x04);
      Wait(.005);

      djoSendData[0] = 0x01;  // Bulk Write Based Read_Only for a single register Read of 0x01 (status)
      i2c_Lidar->WriteBulk(djoSendData,1);
      i2c_Lidar->ReadOnly(1,LidarMassData);
      printf("Mass Data 0 %4X 
", LidarMassData[0]);
      Wait(0.001);

      djoSendData[0] = 0x8F;  // Bulk Write Based Read_Only for a two register Read of 0x8F (distance)
      i2c_Lidar->WriteBulk(djoSendData,1);
      i2c_Lidar->ReadOnly(2,LidarMassData);
      printf("Mass Data 0 %4X 
", LidarMassData[0]);
      printf("Mass Data 1 %4X 
", LidarMassData[1]);

Have you made any additional progress or observations about the v3 and using it with this year’s game?

Our team is using Java, but have had similar problems with using the Lidar Lite v3 with i2c on the roboRio. We’ve been seeing that addressOnly() always returns true (error) and we were always getting values of 0 from the device. We will try your approach of using the writeBulk/readOnly methods tonight to see if that is any better.

Any help appreciated. Thanks!

Yes, I have come to the same conclusion and only rely on the i2c write and readonly methods. I spent oodles of time with a scope and logic analyzer trying to get i2c (via java) running on the roborio. At least I had the luxury of designing the other end, so I could define the protocol to avoid the broken methods.

I also found that the MXP i2c port is not working for me (which bummed me out since I designed a board for it and then had to scab a cable to the onboard port) – navx can use mxp i2c apparently, so I am missing something on enabling the mxp port other than specifying kMXP.

see my java i2c code at:

We’ve been having a terrible time with I2C this year. It has been very intermittent and gets stuck far too often.

I don’t know if it is EMI-based, bad wiring, bad code, or just the I2C bus hardware is poorly done.

Linked below are our two classes that utilize I2C (Pixy and Lidar v3), just in case they should be of interest to anyone. I’m sorry its late, but the last few weeks of build season probably wasn’t the best time to bring this up :slight_smile:

http://forums.rogue-robotics.com/download/pixyandlidarclasses.zip

Hi David:

I feel your pain – the roborio I2C is buggy (imho). We have only been able to rely on the (2-byte) write and the read-only methods. Transactions and such with repeated-start hang and barf. I have spent way too much time with the storage scope and logic analyzer trying to get roborio I2C running.

There is a recent wpilib I2C update (we use java), but I am not planning on disrupting currently-working code with a last-minute library change, which I cannot test on the final bot until regionals. Yeah, I don’t think so. Perhaps they fixed some things, but it will be off-season before I update that library and test again.

We did just get a pixy, so I will definitely peek at your pixy code, and may have a question or two :slight_smile: Thanks for posting that.

We have had problems with the lidar-lite in the past as well – see a reply of mine at:
https://www.chiefdelphi.com/forums/showthread.php?p=1648729#post1648729