IOWarrior56 USB Dongle using MPU6050 IMU via I2C

This is the English forum for all topics related to IO-Warrior. Please post in English only

Moderator: Guido Körber

Post Reply
Tom2014
Posts: 4
Joined: Tue Jul 08, 2014 2:19 pm

IOWarrior56 USB Dongle using MPU6050 IMU via I2C

Post by Tom2014 »

Hello,

I work with the IOWarrior56 USB Dongle and having some issues to talk to the connected MPU6050 (Inertial Measurement Unit) that is connected via I2C.

When I run the provided simple I2C Test Program under Windows I can properly address the unit, which means I can perform manual "write"-requests and set the register address in the IMU, followed by "read" to get the content of the register, or even set register content via "write".

What I did first ist that I build the linux library as described in the SDK and installed it together with the header file.
I develop my software under Linux (Ubuntu) running in a Virtual Machine (VMWare) on my Windows PC. The USB Dongle is routed to the VMware and I can access it and e.g. retrieve its serial number. Therefore I think that the driver and library are working.

But when I want to access the registers of the IMU I run into issues. I read the API documentation and the IO-Warrior56 documentation, also looked into some code examples, but without success so far.

Attached is some code that I used to read the "WhoAmI" register from the IMU. The result shall simply be to get the device address of the IMU (0x68).

Hope that one can help me out here. I have the IMU actually running with real I2C and also SPI, but with the IOWarrior API I am bit struggling.
Maybe it is only a minor issue with the way I set up the write/read reports for the IOWarrior API.

OK, here is the code I used for testing:

Code: Select all

IOWKIT56_SPECIAL_REPORT report;
ULONG ioLen = 0;
IOWKIT_HANDLE ioHnd = NULL;

// Open IOWarrior
ioHnd = IowKitOpenDevice();

memset(&report, 0x00, IOWKIT56_SPECIAL_REPORT_SIZE);

// Enable I2C
report.ReportID = 0x01; // ID: I2C-Mode
report.Bytes[0] = 0x01; // Enable
report.Bytes[1] = 0x00; // Flags = standard
ioLen = IowKitWrite(ioHnd, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT56_SPECIAL_REPORT_SIZE);


// set register address of device 0x68 (MPU6050) to 0x75 (WhoAmI)
report.ReportID = 0x02;   // ID: I2C-Write
report.Bytes[0] = 0xC2;   // flags: Start/Stop & length = 2
report.Bytes[1] = 0x68;   // device address
report.Bytes[2] = 0x75;   // register address

ioLen = IowKitWrite(ioHnd, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT56_SPECIAL_REPORT_SIZE);
// the following read blocks. when disconnecting the dongle and reconnecting is does not block, but the next read below fails.
// sometimes this read also fails with the error bit set ...
ioLen = IowKitRead (ioHnd, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT56_SPECIAL_REPORT_SIZE);

// read from register address of device 0x68 (MPU6050) to get the WhoAmI address (node address)
report.ReportID = 0x03;        // ID: I2C-Read
report.Bytes[0] = 1;           // count = 1
report.Bytes[1] = 0x68 + 0x01; // device address + READ

ioLen = IowKitWrite(ioHnd, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT56_SPECIAL_REPORT_SIZE);
// when this line is reached then it returns with the error bit set
ioLen = IowKitRead (ioHnd, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT56_SPECIAL_REPORT_SIZE);


// Disable I2C
report.ReportID = 0x01; // ID: I2C-Mode
report.Bytes[0] = 0x00; // Disable
report.Bytes[1] = 0x00; // Flags = standard speed
ioLen = IowKitWrite(ioHnd, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT56_SPECIAL_REPORT_SIZE);


// Close IOWarrior
IowKitCloseDevice(ioHnd);
Thanks a lot in advance for your help on this!

Regards,
Tom
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: IOWarrior56 USB Dongle using MPU6050 IMU via I2C

Post by Christoph Jung »

Are you sure the I2C-Device address are the right on?
The code looks right and should work.

Hint:
I would include the function IowKitSetTimeout() to prevent read freezes.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
Tom2014
Posts: 4
Joined: Tue Jul 08, 2014 2:19 pm

Re: IOWarrior56 USB Dongle using MPU6050 IMU via I2C

Post by Tom2014 »

Thanks for your answer!

Yes, I am sure that the 0x68 is the correct address. I use the same address when connecting the device via I2C directly or via SPI. I also can communicate with the device via the same Dongle when I use the SimpleI2C Windows software and this address.

Prior to use the test SW given above I build the iowkit library and its include file and installed it as described in the SDK that I downloaded actually from the website (configure, make, make install). As mentioned I am running ubuntu (12.10) in VMWare. I also tried it with another PC where I have ubuntu installed directly (13.04), with almost the same result. However, this time it does not block, but the result is still that the error bit gets set. I always run the software as "sudo", because this is also a prerequisite for the iotest program that gets build when building the library (access to dev).

If the code is correct I don't know how to proceed from here.

Maybe I provide some more info on the system so you can probably identify an issue:

- Ubuntu 10.04 running in VMWare - AND - Ubuntu 13.04 running on PC directly
- Library build based on actual SDK download from website
- Eclipse with gcc/g++ as IDE
- C++ Project where test software runs within
- IOWarrior56 Dongle
- I2C Device MPU6050 with address 0x68
- Test with Windows SimpleI2C successful (read/write, manual read-modify-write-read test)

Hope that this could help to identify a potential issue.

Regards,
Tom
Tom2014
Posts: 4
Joined: Tue Jul 08, 2014 2:19 pm

Re: IOWarrior56 USB Dongle using MPU6050 IMU via I2C

Post by Tom2014 »

Hello,

I guess I found the issue, after I tried it also with a modified Windows C# Example Version to access my I2C IMU device ... it seems to be really a device addressing issue. I missed to shift the address byte by one to the left (0x68 << 1 = 0xD0). So you were right! 0x68 is the original device address, but I2C requires to place this values in the upper part of the byte ... nice pit fall :-)

However, I still have the issue of a blocked read-call. Hope to get this issue fixed. It is probably because of running under VMWare.

Thanks a lot for your help on this!

Regards,
Tom
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: IOWarrior56 USB Dongle using MPU6050 IMU via I2C

Post by Christoph Jung »

To prevent blocking use IowKitSetTimeout() to kill the read function after a defined time or you use IowKitReadNonBlocking().
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
Tom2014
Posts: 4
Joined: Tue Jul 08, 2014 2:19 pm

Re: IOWarrior56 USB Dongle using MPU6050 IMU via I2C

Post by Tom2014 »

I used "IowKitSetTimeout()" and it works smoothly now! It also works with my Beaglebone after I cross build the iowkit library for arm.

Thanks again for your help on this little pit fall! Instead of using 8 Bits (8:0) for the address I had to use 7 bits for the address and 1 bit for the Read/Write (7:1) ... sounds a bit like the great success yesterday of "Jogis Jungs" against brasil :-)
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: IOWarrior56 USB Dongle using MPU6050 IMU via I2C

Post by Guido Körber »

Tom2014 wrote:... sounds a bit like the great success yesterday of "Jogis Jungs" against brasil :-)
We deny any participation in any kind of soccer match!

;)
Post Reply