View unanswered posts | View active topics It is currently Fri Oct 24, 2014 6:24 am






Reply to topic  [ 10 posts ] 
I²C device: Wii Nunchuck for NXT (accelerometer + joystick) 
Author Message
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post I²C device: Wii Nunchuck for NXT (accelerometer + joystick)
to attach a wii nunchuck to a NXT I²C port, you may find this interesting:
(RobotC driver source see below!)

http://www.mindstormsforum.de/viewtopic.php?t=3828

http://www.youtube.com/watch?v=HFQtyna58Kg

[url]<object width="425" height="344"><param name="movie"value="http://www.youtube.com/v/HFQtyna58Kg&hl=de&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/HFQtyna58Kg&hl=de&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>[/url]

Image

Image

Image

Image

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Sun Nov 16, 2008 12:51 pm, edited 3 times in total.



Sat Nov 15, 2008 1:23 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: I²C device: Wii Nunchuck for NXT (accelometer + joystick)
I asked the author to transcode this NXC code to RobotC, but he replied:
tom123 wrote:
Übrigens ist die Dokumentation von RobotC eine Katastrophe. Warum nimmst Du nicht NXC? John Hansen macht eine gute Arbeit. NXC ist kostenlos und sehr gut dokumentiert.


nothing to be added. :-$

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Sun Nov 16, 2008 5:33 am, edited 1 time in total.



Sat Nov 15, 2008 8:05 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3227
Location: Rotterdam, The Netherlands
Post Re: I²C device: Wii Nunchuck for NXT (accelometer + joystick)
Ford,

Very few people speak German, so a translation might be handy if you want to get your point across :)

Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Sun Nov 16, 2008 5:06 am
Profile WWW
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: I²C device: Wii Nunchuck for NXT (accelometer + joystick)
sorry, I thought I had added the Babelfish or Google translation...
here it is:
tom123 wrote:
Übrigens ist die Dokumentation von RobotC eine Katastrophe. Warum nimmst Du nicht NXC? John Hansen macht eine gute Arbeit. NXC ist kostenlos und sehr gut dokumentiert.

Babelfish wrote:
Incidentally, the RobotC documentation is a disaster. Why do not you take NXC? John Hansen does a good job. NXC is free and very well documented.

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sun Nov 16, 2008 5:30 am
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: I²C device: Wii Nunchuck for NXT (accelerometer + joystick)
The Nunchuck-RobotC-Driver is ready!
here it is: :bigthumb:
tom123 wrote:
OK, ich helfe gerne
Anbei mein erstes RobotC Programm
Code:
byte CMDNunchukInit[] = {0x03, 0xA4, 0x40, 0x00};
byte CMDNunchukWrite[] = {0x02, 0xA4, 0x00};
byte CMDNunchukRead[] = {0x01, 0xA4};

// byte nbytes;    //NXC
byte outbuf[6];
int outbuf1[6];   //ubyte workaround for RobotC

//  This function allows conversion of an unsigned byte to a signed int
//  This is a workaround for RobotC
int ubyteToInt(ubyte _byte) {
   int _ret = 0;
   _ret = (_byte & 0x80) ? (_byte & 0x7F) + 0x80 : _byte;
   return _ret;
}

// port is the NXT port, i2c_cmd is the nunchuk internal address register
// at i2c_cmd=0...5 are 6 Byte of sensor values
// at i2c_cmd=0x20 ... 0x2F  you get 16 Byte of calibration data

//sub NunchukGetParamter(byte port, byte i2c_cmd)    //NXC
sub NunchukGetParamter(tSensors port, byte i2c_cmd)  //RobotC
{
  // Initialize the Nunchuk
  //SetSensorLowspeed(port);  //NQC
   SensorType[port] = sensorI2CCustom;  //RobotC

  //LowspeedWrite(port, 0, CMDNunchukInit); //NXC ask for 0 bytes
   sendI2CMsg(port, CMDNunchukInit[0], 0); //RobotC

  //while(LowspeedStatus(port, nbytes)>0);  //NQC
  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // RobotC Wait for I2C bus to be ready

  //CMDNunchukWrite[1] =i2c_cmd;   //NXC at 0x00: 6 Bytes of sensor values
  CMDNunchukWrite[2] =i2c_cmd;     //RobotC

  //LowspeedWrite(port, 0, CMDNunchukWrite);   //NXC write Nunchuk register address
   sendI2CMsg(port, CMDNunchukWrite[0], 0);     //RobotC

  //while(LowspeedStatus(port, nbytes)>0);        //NXC
  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // RobotC Wait for I2C bus to be ready

  byte count = 6;
  //LowspeedWrite(port, count, CMDNunchukRead); //NXC: ask for count bytes
   sendI2CMsg(port, CMDNunchukRead[0], count);   //RobotC

  //while(LowspeedStatus(port, nbytes)>0);        //NXC
  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // Wait for I2C bus to be ready

  //if(nbytes == count){                  //NXC
  if(nI2CBytesReady[port] == count){      //RobotC

    //LowspeedRead(port, count, outbuf)  //NXC read data from buffer
      readI2CReply(port, outbuf[0], 6);    //RobotC

    for(int i=0; i<count; i++ ){
       outbuf1[i]=ubyteToInt(outbuf[i]);   //ubyte workaround for RobotC
      outbuf1[i]=(outbuf1[i]^0x17) + 0x17;
    }
  }
  else {
    //ArrayInit(outbuf,0,0);    //NXC: error
     memset(outbuf, 0, 0);       //RobotC
  }
}

task main()
{
  while (true)
  {
    NunchukGetParamter(S1, 0x00);          //see comment for i2c_cmd

    //if (ArrayLen(outbuf)==6) {     //NXC
    if (sizeof(outbuf)==6)    {      //RobotC

       //string Nunchuk="aXaYgXgYgZCZ";     //NXC
       char Nunchuk[16];                    //RobotC
       strcpy(Nunchuk, "aXaYgXgYgZCZ");     //RobotC

       if ((outbuf1[5]&0x01)!=0) {Nunchuk[11]=122;}  //Show Z-Button
       if ((outbuf1[5]&0x02)!=0) {Nunchuk[10]=99;}   //Show C-Button

       // ClearScreen();  //NXC
       eraseDisplay();   //RobotC

       // for(int i=0; i<ArrayLen(outbuf); i++ ) {  //NXC
       for(int i=0; i<6; i++ ) {  //RobotC

         //TextOut(15*i, LCD_LINE3, SubStr(Nunchuk, 2*i, 2));   //NXC
         nxtDisplayStringAt(15*i,50,"%c", Nunchuk[2*i]);         //RobotC
         nxtDisplayStringAt(15*i+5,50,"%c", Nunchuk[2*i+1]);       //RobotC

         //TextOut(15*i, LCD_LINE5, FormatNum("%02X", outbuf[i]));     //NXC
         nxtDisplayStringAt(15*i,40,"%02X", outbuf1[i]);               //RobotC
       }

       // CircleOut((outbuf[0]-0x1E)/2, (outbuf[1]-0x1E)/3, 3);    //NXC analog stick
       nxtDrawCircle((outbuf1[0]-0x1E)/2, (outbuf1[1]-0x1E)/3, 3);   //RobotC

       // RectOut((outbuf[2]-0x46), (outbuf[3]-0x46)/2, 6, 6);    //NXC acceleration value
       nxtDrawCircle((outbuf1[2]-0x46), (outbuf1[3]-0x46)/2, 6);
    }
    // Wait(100);  //NXC
    wait1Msec(100);    //RobotC
  }
}

Ich habe auf meinem NXT extra für Dich die RobotC Firmware installiert :no:

Damit Du Dich in NXC einarbeiten kannst, habe ich die NXC Zeilen auskommentiert und die RobotC Zeilen darunter geschrieben.
Am längsten habe ich gebraucht, das UBYTE Problem von RobotC zu knacken. Ich habe dazu die zusätzliche Funktion ubyteToInt() eingefügt.

Anbei ein Screenshot vom RobotC-Programm:
Image
Diese Demo bewegt einen kleinen Kreis mit dem Analog-Stick und ein großen Kreis mit den Beschleunigungssensor.


Image


OT:
@Xander: actually not "very" few people speak German - it's maybe about 120 Million native speakers plus 50-80 Million in neighbouring countries like Belgium, Holland,... ;-)

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sun Nov 16, 2008 12:18 pm
Profile
Expert

Joined: Sun Sep 09, 2007 10:12 am
Posts: 116
Post Re: I²C device: Wii Nunchuck for NXT (accelerometer + joystick)
Here you can see the youtube film that i make about this:

http://www.youtube.com/watch?v=zIlEmtnaGgI

_________________
http://www.apcsguarda.com
My Project: http://www.robotc.net/forums/viewtopic.php?f=15&t=712


Tue Mar 03, 2009 4:41 pm
Profile
Rookie
User avatar

Joined: Tue Aug 11, 2009 11:49 pm
Posts: 38
Location: Tasmania, the Land Down Under, the Land Downunder!
Post Re: I²C device: Wii Nunchuck for NXT (accelerometer + joystick)
Here's my modifed NunChuck Controller code to control motors:

Code:
byte CMDNunchukInit[] = {0x03, 0xA4, 0x40, 0x00};
byte CMDNunchukWrite[] = {0x02, 0xA4, 0x00};
byte CMDNunchukRead[] = {0x01, 0xA4};

byte outbuf[6];
int outbuf1[6];   //ubyte workaround for ROBOTC

//  This function allows conversion of an unsigned byte to a signed int
//  This is a workaround for ROBOTC
int ubyteToInt(ubyte _byte) {
  int _ret = 0;
_ret = (_byte & 0x80) ? (_byte & 0x7F) + 0x80 : _byte;
  return _ret;
}

// port is the NXT port, i2c_cmd is the nunchuk internal address register
// at i2c_cmd=0...5 are 6 Byte of sensor values
// at i2c_cmd=0x20 ... 0x2F  you get 16 Byte of calibration data

sub NunchukGetParamter(tSensors port, byte i2c_cmd)
{
  // Initialize the Nunchuk
  SensorType[port] = sensorI2CCustom;

  //Ask for 0 bytes
  sendI2CMsg(port, CMDNunchukInit[0], 0);

  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // ROBOTC Wait for I2C bus to be ready

  //Write at 0x00: 6 Bytes of sensor values
  CMDNunchukWrite[2] =i2c_cmd;

  //Write Nunchuk register address
  sendI2CMsg(port, CMDNunchukWrite[0], 0);

  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // ROBOTC Wait for I2C bus to be ready

  byte count = 6;
  //Ask for count bytes
  sendI2CMsg(port, CMDNunchukRead[0], count);

  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // Wait for I2C bus to be ready

  if(nI2CBytesReady[port] == count){

    //Read data from buffer
    readI2CReply(port, outbuf[0], 6);

    for(int i=0; i<count; i++ ){
      outbuf1[i]=ubyteToInt(outbuf[i]);   //ubyte workaround for ROBOTC
      outbuf1[i]=(outbuf1[i]^0x17) + 0x17;
    }
  }
  else {
    // error
    memset(outbuf, 0, 0);
  }
}


task main()

{
  while (true)
  {
    NunchukGetParamter(S1, 0x00);          //see comment for i2c_cmd

    if (sizeof(outbuf)==6)    {

      // analog stick
      eraseDisplay();
      nxtDrawCircle((outbuf1[0]-0x1E)/2, (outbuf1[1]-0x1E)/3, 3);

      {motor[motorA] = ((outbuf1[0])-0x80);}   //Set Motor A & Adjust the Subtract 0x80 Value to Suite Joystick controller
      {motor[motorB] = ((outbuf1[1])-0x80);}   //Set Motor B & Adjust the Subtract 0x80 Value to Suite Joystick controller

//      {motor[motorA] = ((outbuf1[2])-0x80);}   //Set Motor A & Adjust the Subtract 0x80 Value to Suite Accelaratoin Sensor controller
//      {motor[motorB] = ((outbuf1[3])-0x80);}   //Set Motor B & Adjust the Subtract 0x80 Value to Suite Accelaratoin Sensor controller
    }
  }
}


Thanks to everyone who did the ground work.


Attachments:
File comment: Photograph of my modified Wiimote Controller.
NXT-Wiimote.jpg
NXT-Wiimote.jpg [ 62.39 KiB | Viewed 7152 times ]

_________________
regards

Sparra Mc


Image
Wed Aug 12, 2009 1:05 am
Profile WWW
Rookie

Joined: Fri Nov 13, 2009 7:48 pm
Posts: 5
Post Re: I²C device: Wii Nunchuck for NXT (accelerometer + joystick)
Das ist keine schöne Bemerkung!




.. and this is excellent work by you guys. very out of the box


Fri Dec 04, 2009 9:51 pm
Profile
Rookie

Joined: Sat Jan 30, 2010 12:10 am
Posts: 1
Post Re: I²C device: Wii Nunchuck for NXT (accelerometer + joystick)
I don't know if this is a bug in my version of robotc, but this code returns negative values, despite the fact it sounds like it is trying to treat the byte as unsigned.

int ubyteToInt(ubyte _byte) {
int _ret = 0;
_ret = (_byte & 0x80) ? (_byte & 0x7F) + 0x80 : _byte;
return _ret;
}

on my version of robotc I had to change this to the following:

int ubyteToInt(byte _byte) {
int result = _byte;
if (_byte & 0x80) {
result = _byte & 0x7F;
result += 128;
}
return result;
}

I'm using verion 2.01 (7.88) Dec 8th 2009.

This same bug stopped the HiTechnic Experimenters Kit examples from working properly also.


Sat Jan 30, 2010 12:19 am
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3227
Location: Rotterdam, The Netherlands
Post Re: I²C device: Wii Nunchuck for NXT (accelerometer + joystick)
What version of the 3rd party drivers are you using? I've been slowly fading that function out of the driver suite since it's no longer needed in most cases.

You should download version 1.2 of the driver suite here: http://rdpartyrobotcdr.sourceforge.net/

Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Sat Jan 30, 2010 3:40 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 10 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.