Go to Post FIRST opened a door and I walked through it. - Erin Rapacki [more]
Home
Go Back   Chief Delphi > Technical > Programming > C/C++
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 03-02-2014, 07:59
kylelanman's Avatar
kylelanman kylelanman is offline
Programming Mentor
AKA: Kyle
FRC #2481 (Roboteers)
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Tremont Il
Posts: 189
kylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to all
I2C Arduino Port (Wii MotionPlus)

I'll start off by saying prior to this season our team has had no prior knowledge of I2C.

We successfully were able to talk to a LSM303D using the standard calls in the WPILib I2C class.

We are now trying to integrate with a Wii MotionPlus. We have a working setup with an Arduino. In hopes of eliminating the Arduino we tried to port the Arduino sketch to C++. Our limited knowledge of I2C has made this a little bit of a challenge.

Code:
/* Arduino */
void receiveData(){
  Wire.beginTransmission(0x52);    //now at address 0x52
  Wire.send(0x00);		     //send zero to signal we want info
  Wire.endTransmission();
  nunchuck)
  Wire.requestFrom(0x52,6);	  //request the six bytes from the WM+
  for (int i=0;i<6;i++){
    data[i]=Wire.receive();
  }
}
I realize there is additional initialization that needs to happen. But that is straight forward. The 2 new concepts that the LSM303D did not require but that the Wii MotionPlus does are:
1. Sending data over I2C with no register as a target.
2. Receiving data over I2C with out a particular register as a source.

Code:
/* WPILib */
        // _wmp is an instance of I2C
	uint8_t buffer[6];
	_wmp->Transaction(0x00, 1, buffer, sizeof(buffer);
Are these code snippets functionally equivalent? If not what are the equivalent of requestFrom() and read() in the WPILib?

Thanks in advance to anyone that can assist us.

Kyle
__________________
"May the coms be with you"

Is this a "programming error" or a "programmer error"?

Reply With Quote
  #2   Spotlight this post!  
Unread 03-02-2014, 09:00
Mike Bortfeldt Mike Bortfeldt is offline
Registered User
FRC #1126 (& 1511)
Team Role: Mentor
 
Join Date: Oct 2004
Rookie Year: 2004
Location: Rochester, NY
Posts: 119
Mike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud of
Re: I2C Arduino Port (Wii MotionPlus)

Kyle,

I'll take a shot at this. My experience is with I2C in Java and an Arduino, but most of that should apply here. First, if you are using an address of 0x52 on an Arduino to communicate with the Wii MotionPlus, then you will most likely need to use an address of 0xA4 on the cRio. Your code doesn't show how you are setting up the I2C object. For the "receiveing data" portion, you should be able to use the following code to just receive data.

Code:
_wmp->Transaction(0x00, 0, buffer, sizeof(buffer));
The zero length of the send buffer will prevent the cRIO from transmitting any data. As for the sending without any address, the register address typically is the first byte in the transmission string. It is all up to the Wii MotionPlus on how it interprets the data it receives, so this should not be a problem.

Mike

Last edited by Mike Bortfeldt : 03-02-2014 at 09:16. Reason: incorrect address
Reply With Quote
  #3   Spotlight this post!  
Unread 03-02-2014, 09:43
kylelanman's Avatar
kylelanman kylelanman is offline
Programming Mentor
AKA: Kyle
FRC #2481 (Roboteers)
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Tremont Il
Posts: 189
kylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to all
Re: I2C Arduino Port (Wii MotionPlus)

Quote:
Originally Posted by Mike Bortfeldt View Post
Kyle,

I'll take a shot at this. My experience is with I2C in Java and an Arduino, but most of that should apply here. First, if you are using an address of 0x52 on an Arduino to communicate with the Wii MotionPlus, then you will most likely need to use an address of 0xA4 on the cRio. Your code doesn't show how you are setting up the I2C object. For the "receiveing data" portion, you should be able to use the following code to just receive data.
Thanks for the quick response can you explain why the change in address is needed when switching from the Arduino to the cRio? We did notice it was on a different address but don't understand why.

Thanks

Kyle
__________________
"May the coms be with you"

Is this a "programming error" or a "programmer error"?

Reply With Quote
  #4   Spotlight this post!  
Unread 03-02-2014, 10:26
Mike Bortfeldt Mike Bortfeldt is offline
Registered User
FRC #1126 (& 1511)
Team Role: Mentor
 
Join Date: Oct 2004
Rookie Year: 2004
Location: Rochester, NY
Posts: 119
Mike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud of
Re: I2C Arduino Port (Wii MotionPlus)

Kyle,

The I2C specification calls out for a 7 bit device address (there is also a 10 bit address, but that doesn't apply here), along with a single bit to indicate read/write. This information is combined where the address is the high 7 bits and the read/write is the LSB as shown below, where 'A' indicates an address bit and R indicates the read/write bit (write is 0, read is 1)

Code:
Bit (MSB) 76543210 (LSB)
          AAAAAAAR
Some devices interpret this (or at least sometimes describes it) as two 8 bit addresses, one for read one for write. The Arduino uses the specificed 7 bit address and internally bit shifts it by 1 (effectively multiplying the address by 2) and then adds the read/write. The cRio wants you to specifiy the address already bit shifted. You'll notice that the cRio addresss I gave is the same as the Arduino * 2.

Hopefully this makes sense.

Mike

For reference, I found the I2C bus specification here : http://www.nxp.com/documents/user_manual/UM10204.pdf

Last edited by Mike Bortfeldt : 03-02-2014 at 10:46. Reason: added reference
Reply With Quote
  #5   Spotlight this post!  
Unread 03-02-2014, 13:39
kylelanman's Avatar
kylelanman kylelanman is offline
Programming Mentor
AKA: Kyle
FRC #2481 (Roboteers)
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Tremont Il
Posts: 189
kylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to all
Re: I2C Arduino Port (Wii MotionPlus)

Your explanation of the addresses makes sense and clears things up.

I realized I misread your first post and didn't catch the difference between your snippet and mine.

Quote:
Originally Posted by kylelanman View Post

Code:
/* Arduino */
void receiveData(){
  Wire.beginTransmission(0x52);    //now at address 0x52
  Wire.send(0x00);		     //send zero to signal we want info
  Wire.endTransmission();
  nunchuck)
  Wire.requestFrom(0x52,6);	  //request the six bytes from the WM+
  for (int i=0;i<6;i++){
    data[i]=Wire.receive();
  }
}
Code:
/* WPILib */
        // _wmp is an instance of I2C
	uint8_t buffer[6];
	_wmp->Transaction(0x00, 1, buffer, sizeof(buffer);
Quote:
Originally Posted by Mike Bortfeldt View Post

Code:
_wmp->Transaction(0x00, 0, buffer, sizeof(buffer));
With my 1 transaction call I was trying to kill 2 birds with one stone. The Wii MotionPlus requires that you send 0x00 in order for it to return data. That is why I was using a size of 1. Will this work all in one transaction or do we need to do 2 separate transactions. 1 for sending 0x0 and the other for receiving?

Thanks

Kyle
__________________
"May the coms be with you"

Is this a "programming error" or a "programmer error"?

Reply With Quote
  #6   Spotlight this post!  
Unread 03-02-2014, 13:53
Mike Bortfeldt Mike Bortfeldt is offline
Registered User
FRC #1126 (& 1511)
Team Role: Mentor
 
Join Date: Oct 2004
Rookie Year: 2004
Location: Rochester, NY
Posts: 119
Mike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud of
Re: I2C Arduino Port (Wii MotionPlus)

Kyle,

Quote:
Originally Posted by kylelanman View Post
Will this work all in one transaction or do we need to do 2 separate transactions. 1 for sending 0x0 and the other for receiving?
You should be able to do this in one transaction as you had in your original post. I misunderstood what you were asking.

Mike

- You may also want to verify if the transmit data (buffer) needs to be passed as an address to a byte array. I know in Java this is true.

Last edited by Mike Bortfeldt : 03-02-2014 at 14:48.
Reply With Quote
  #7   Spotlight this post!  
Unread 03-02-2014, 23:42
kylelanman's Avatar
kylelanman kylelanman is offline
Programming Mentor
AKA: Kyle
FRC #2481 (Roboteers)
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Tremont Il
Posts: 189
kylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to all
Re: I2C Arduino Port (Wii MotionPlus)

Thanks for all the help. We had moderate success tonight.

The biggest thing that we never would have figured out was the addressing. On the Arduino you have to initialize the Wii MotionPlus on 0x53. Then communicate with it on 0x52.

When switching to the cRio we initially were trying to initialize it at 0xa5 and then communicate with it on 0xa4. Thanks to your advice we figured out it needed to be 0xa6 and 0xa4.

We were having a load of problems with execution hanging at the Transaction call. After separating it out into 7 separate transactions. 1 write and 6 reads things smoothed out. Some additional searching on chief delphi leads us to believe that WPILib only supports reading or writing 4 bytes at a time. The comments in the source indicate 7 so that was mildly frustrating. At this point I think we have it working.

Provided we end up going this route once we get the code cleaned up and all the bugs worked out we hope to share our seemingly robust wrapper for the Wii MotionPlus with the rest of the first community.

Thanks Again!!!

Kyle
__________________
"May the coms be with you"

Is this a "programming error" or a "programmer error"?

Reply With Quote
  #8   Spotlight this post!  
Unread 04-02-2014, 09:09
Mike Bortfeldt Mike Bortfeldt is offline
Registered User
FRC #1126 (& 1511)
Team Role: Mentor
 
Join Date: Oct 2004
Rookie Year: 2004
Location: Rochester, NY
Posts: 119
Mike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud of
Re: I2C Arduino Port (Wii MotionPlus)

Kyle,

Glad to hear you are making progress. If you could post what you are (or are not seeing) when you try transactions > 4 bytes, perhaps I could help. The cRio should be able to communicate in up to 7 byte transactions (at least it was able to last year). One thing you could try is to call "setCompatibilityMode(true)" on the I2C object. This will probably not do anything as I read that it was set to TRUE by default this year (unlike last year), but it won't hurt to try. I also had some initial issues last year with Java and the bytes > 4 (wrong data), but that was specific to Java and should be corrected this year.

Mike
Reply With Quote
  #9   Spotlight this post!  
Unread 04-02-2014, 15:11
kylelanman's Avatar
kylelanman kylelanman is offline
Programming Mentor
AKA: Kyle
FRC #2481 (Roboteers)
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Tremont Il
Posts: 189
kylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to all
Re: I2C Arduino Port (Wii MotionPlus)

When trying to troubleshoot the lockups we slowly broke the following line into multiple calls.

Code:
_wmp->Transaction(0x00, 1, &buffer[0], sizeof(buffer));
Code:
printf("I2C Write\n");
_wmp->Transaction(0x00, 1, 0, 0;
printf("I2C Read Start\n");
_wmp->Transaction(0, 0, &buffer[0], sizeof(buffer));
printf("I2C Read Finish\n");
At this point it would lockup and the console would show the following.
Code:
...
I2C Write
I2C Read Start
Whenever a lockup occurred we found that momentarily removing power from the Wii MotionPlus would unlock the system and it would continue executing for 10s of seconds before the same thing happened.

We ended the night with the following code and had successfully run 5 minutes with no lockups. That may just be a coincidence

Code:
_wmp->Transaction(0x00, 1, 0, 0);
_wmp->Transaction(0, 0, &buffer[0], 1));
_wmp->Transaction(0, 0, &buffer[1], 1));
_wmp->Transaction(0, 0, &buffer[2], 1));
_wmp->Transaction(0, 0, &buffer[3], 1));
_wmp->Transaction(0, 0, &buffer[4], 1));
_wmp->Transaction(0, 0, &buffer[5], 1));
Thanks again and appreciate your willingness to assist!!!

Kyle
__________________
"May the coms be with you"

Is this a "programming error" or a "programmer error"?

Reply With Quote
  #10   Spotlight this post!  
Unread 04-02-2014, 19:16
Mike Bortfeldt Mike Bortfeldt is offline
Registered User
FRC #1126 (& 1511)
Team Role: Mentor
 
Join Date: Oct 2004
Rookie Year: 2004
Location: Rochester, NY
Posts: 119
Mike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud of
Re: I2C Arduino Port (Wii MotionPlus)

Kyle,

It's interesting that it hangs on the read transaction. The actual I2C communication is handled by the FPGA so it's a little difficult to know exactly what is happening. Normally, I would expect the transaction to return an error if it couldn't complete. My only thought is that the Wii MotionPlus is holding the clock signal low preventing the transaction from completing. Removing power from the Wii would allow the clock to resume. There are two things I can suggest you try.

First, the transaction routine expects a pointer to a byte array for the "dataToSend" argument. So I think your 0x00 in the send transmission is getting converted to a pointer to memory address 0x00 rather than a value of zero. Try changing to the following:
Code:
uint8_t sendBuffer[1]={0};
_wmp->Transaction(sendBuffer, 1, 0, 0);
Second, ensure the setCompatibilityMode is set to true in your initiation routine.
Code:
_wmp->setCompatibilityMode(TRUE);
Other than these two things, your code looks like it should work.

Mike
Reply With Quote
  #11   Spotlight this post!  
Unread 05-02-2014, 02:26
Joe Hershberger Joe Hershberger is offline
National Instruments
AKA: jhersh
FRC #2468 (Appreciate)
Team Role: Mentor
 
Join Date: Nov 2005
Rookie Year: 1997
Location: Austin, TX
Posts: 148
Joe Hershberger is a name known to allJoe Hershberger is a name known to allJoe Hershberger is a name known to allJoe Hershberger is a name known to allJoe Hershberger is a name known to allJoe Hershberger is a name known to all
Re: I2C Arduino Port (Wii MotionPlus)

Quote:
Originally Posted by kylelanman View Post
Some additional searching on chief delphi leads us to believe that WPILib only supports reading or writing 4 bytes at a time. The comments in the source indicate 7 so that was mildly frustrating.
For the first year or two the cRIO FRC personality in the FPGA supported only 4 bytes per transaction. Since then it has supported 7. Perhaps that's why you found out-of-date information on CD.
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 14:35.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi