![]() ![]() |
Nov 15 2008, 01:01 PM
Post
#1
|
|
|
Member ![]() ![]() Group: Members Posts: 25 Joined: 20-February 08 From: Germany Member No.: 4,776 |
The cheap Nunchuk controller features an analog stick with a 3-axis-accelerometer for motion-sensing over a I2C-Connector.
http://www.wiili.org/index.php/Wiimote/Ext...rollers/Nunchuk For technical details (pullups, I2c) see: http://forums.nxtasy.org/index.php?showtopic=3043&st=0 There are good C-Code for Nunchuk at http://www.windmeadow.com/node/42 used parts 1x Nunchuk (ebay 15EUR) 1/2 NXT cable (0,75EUR, at legoshop 7 hole cables for 10EUR) 2x resistors 33k (0,10EUR) 1x diode 1N4148 (0,10EUR) ...the Lego Accelerometer Sensor costs 55EUR by www.lego.de (Item: MS1040). construction manual 1. Open the nunchuk case with a small screw-driver (1,5mm). Video: http://www.youtube.com/watch?v=V4Jc2usqBIg 2. you are here: http://wiire.org/Wii/nunchuk 3. Now desolder the 1,8k pullup-resistors R1 and R2. No fear of SMD. SMDs sticks to soldering iron
R1.jpg ( 18.71k )
Number of downloads: 12
R2.jpg ( 19.38k )
Number of downloads: 104. Now solder the new pullup resistors. The Lego reference design suggests 82kohm pullup resistors for i2c. I found out, that 33kohm is the best value for stable connection. I changed the SMD resistors, but if you have no SMS resistors use common 1/4W size and solder the resistors on the connection cables. Additionally I mounted a drop-voltage-diode to reduce the voltage of the nunchuk. see specification of motion sensor (3,6V) http://www.st.com/stonline/products/literature/ds/11668.pdf Quite a few people connect the Nunchuk to 5V without problems. You decide. circuit:
circuit.png ( 3.38k )
Number of downloads: 14Here you can see the diode. There are enough places for non-smd-resistors:
diode.jpg ( 19.04k )
Number of downloads: 135. cut the cable and connect it:
connect.jpg ( 20.28k )
Number of downloads: 106. ready:
Nunchuk.jpg ( 26.79k )
Number of downloads: 97. Download the test programm . I use NXC with the enhanced firmware by John Hansen. I love FormatNum("%02X", ...). NXT-G also is possible. CODE #include "NXCDefs.h" byte CMDNunchukInit[] = {0xA4, 0x40, 0x00}; byte CMDNunchukWrite[] = {0xA4, 0x00}; byte CMDNunchukRead[] = {0xA4}; byte nbytes; byte outbuf[]; // 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) { // Initialize the Nunchuk SetSensorLowspeed(port); LowspeedWrite(port, 0, CMDNunchukInit); //ask for 0 bytes while(LowspeedStatus(port, nbytes)>0); // Wait(1) is needless, the NXT command interpreter delays next i2c access 3ms CMDNunchukWrite[1] =i2c_cmd; //at 0x00: 6 Bytes of sensor values LowspeedWrite(port, 0, CMDNunchukWrite); // write Nunchuk register address while(LowspeedStatus(port, nbytes)>0); byte count = 6; LowspeedWrite(port, count, CMDNunchukRead); //ask for count bytes while(LowspeedStatus(port, nbytes)>0); if(nbytes == count){ LowspeedRead(port, count, outbuf) //read data from buffer for(int i=0; i<count; i++ ){ outbuf[i]=(outbuf[i]^0x17) + 0x17; } } else { ArrayInit(outbuf,0,0); //error } } task main() { while (true) { NunchukGetParamter(S1, 0x00); //see comment for i2c_cmd if (ArrayLen(outbuf)==6) { string Nunchuk="aXaYgXgYgZCZ"; if ((outbuf[5]&0x01)!=0) {Nunchuk[11]=122;} //Show Z-Button if ((outbuf[5]&0x02)!=0) {Nunchuk[10]=99;} //Show C-Button ClearScreen(); for(int i=0; i<ArrayLen(outbuf); i++ ) { TextOut(15*i, LCD_LINE3, SubStr(Nunchuk, 2*i, 2)); TextOut(15*i, LCD_LINE5, FormatNum("%02X", outbuf[i])); } CircleOut((outbuf[0]-0x1E)/2, (outbuf[1]-0x1E)/3, 3); //analog stick RectOut((outbuf[2]-0x46), (outbuf[3]-0x46)/2, 6, 6); //acceleration value } Wait(100); } } the code draw a circle controlled by the analog stick and a rectangle controlled by the acceleration sensor ![]() 8. a video at youtube: http://www.youtube.com/watch?v=HFQtyna58Kg |
|
|
|
Nov 16 2008, 09:47 AM
Post
#2
|
|
|
Newbie ![]() Group: Members Posts: 8 Joined: 29-December 07 Member No.: 4,421 |
Great job!
Would you have any test results on the polling speed, the resolution and the maximum g-range? |
|
|
|
Nov 16 2008, 11:14 AM
Post
#3
|
|
|
Advanced Member ![]() ![]() ![]() Group: Members Posts: 1,384 Joined: 29-March 07 From: a black hole in a Gallaxy far far away Member No.: 1,687 |
I believe on the documentation of the Acelleration chip, I think it was 2G.
-------------------- Seeing if I can combine VB.net and NXT together :]
Status: Worried that my hard drive will fail... T.E.C Date is in 5 days... |
|
|
|
Nov 16 2008, 03:15 PM
Post
#4
|
|
|
Member ![]() ![]() Group: Members Posts: 25 Joined: 20-February 08 From: Germany Member No.: 4,776 |
Would you have any test results on the polling speed, the resolution and the maximum g-range? for details about the resolution read the first link: http://www.wiili.org/index.php/Wiimote/Ext...rollers/Nunchuk the datasheet of ST Microelectronics LIS3L02AL 3-axis accelerometer: http://www.st.com/stonline/products/literature/ds/11668.pdf some people ask me for working RobotC-Code 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; sendI2CMsg(port, CMDNunchukInit[0], 0); while (nI2CStatus[port] == STAT_COMM_PENDING); // Wait for I2C bus to be ready CMDNunchukWrite[2] =i2c_cmd; sendI2CMsg(port, CMDNunchukWrite[0], 0); while (nI2CStatus[port] == STAT_COMM_PENDING); //Wait for I2C bus to be ready byte count = 6; sendI2CMsg(port, CMDNunchukRead[0], count); while (nI2CStatus[port] == STAT_COMM_PENDING); // Wait for I2C bus to be ready if(nI2CBytesReady[port] == count){ 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 { memset(outbuf, 0, 0); //RobotC } } task main() { while (true) { NunchukGetParamter(S1, 0x00); //see comment for i2c_cmd if (sizeof(outbuf)==6) { char Nunchuk[16]; strcpy(Nunchuk, "aXaYgXgYgZCZ"); if ((outbuf1[5]&0x01)!=0) {Nunchuk[11]=122;} //Show Z-Button if ((outbuf1[5]&0x02)!=0) {Nunchuk[10]=99;} //Show C-Button eraseDisplay(); //RobotC for(int i=0; i<6; i++ ) { //RobotC nxtDisplayStringAt(15*i,50,"%c", Nunchuk[2*i]); nxtDisplayStringAt(15*i+5,50,"%c", Nunchuk[2*i+1]); nxtDisplayStringAt(15*i,40,"%02X", outbuf1[i]); } nxtDrawCircle((outbuf1[0]-0x1E)/2, (outbuf1[1]-0x1E)/3, 3); nxtDrawCircle((outbuf1[2]-0x46), (outbuf1[3]-0x46)/2, 6); } wait1Msec(100); } } the code draw a small circle controlled by the analog stick and a large circle controlled by the acceleration sensor ![]() |
|
|
|
Nov 17 2008, 04:15 AM
Post
#5
|
|
|
Member ![]() ![]() Group: Members Posts: 25 Joined: 20-February 08 From: Germany Member No.: 4,776 |
t.wolf -- WOW great job!!! I wish I had more time to do cool stuff like this! I believe you could use something like the TI P82B96 DUAL BIDIRECTIONAL BUS BUFFER http://focus.ti.com/lit/ds/symlink/p82b96.pdf -- it should eliminate the need to hack into the Nunchuck and desolder the resistors, as it would provide isolation between the NXT and the nunchuck. I did get a sample and it worked great with a Parallax BS2 microcontroller -- just haven't had a chance to try it with my NXT. I think this could be useful for all other NXT to i2c projects as well. Does any one else think this would be helpful, or am I missing something? You are right. alternative: use the simple level shifter with two MOSFETs see Philips Application note: http://www.nxp.com/acrobat_download/applic...s/AN10441_1.pdf and Philips AN97055 Rp left: 1,8k insight Nunchuk / Rp right: 82k Lego ![]() Edit: This is not tested but I think, that this circuit don't beat the low-level-voltage problem of NXT (4,7k input resistor) Use an IC like TI P82B96 DUAL BIDIRECTIONAL BUS BUFFER. Google for -> i2c level shifter ---------------------- Alternatives for cut up the cord on your Nunchuck variant 1: Four thick wires soldered on a circuit board. I used a breadboard for connection: ![]() variant 2: a commercial adapter: http://store.fungizmos.com/index.php?main_...products_id=212 ![]() variant 3: an old floppy adapter and a plug-in connector of an old ISA card.
|
|
|
|
Nov 17 2008, 12:41 PM
Post
#6
|
|
|
Member ![]() ![]() Group: Members Posts: 26 Joined: 17-November 08 From: The Netherlands Member No.: 6,274 |
Looks absolutely awesome!
Is there already an NXT-G block available? I'm not much of a programmer so I'd rather steer clear of RobotC, NXC and other fancy programming languages. I am pretty good with a soldering iron, if I may say so myself, so modifying a Wii Nunchuck shouldn't be a problem. -------------------- If you ain't Dutch, you ain't much ;)
|
|
|
|
Nov 17 2008, 04:20 PM
Post
#7
|
|
|
Member ![]() ![]() Group: Members Posts: 29 Joined: 29-October 06 Member No.: 414 |
You are right. alternative: use the simple level shifter with two MOSFETs see Philips Application note: http://www.nxp.com/acrobat_download/applic...s/AN10441_1.pdf Rp left: 1,8k insight Nunchuk / Rp right: 82k Lego ![]() ---------------------- Alternatives for cut up the cord on your Nunchuck variant 1: Four thick wires soldered on a circuit board. I used a breadboard for connection: ![]() variant 2: a commercial adapter: http://store.fungizmos.com/index.php?main_...products_id=212 ![]() variant 3: an old floppy adapter and a plug-in connector of an old ISA card. ![]() Hi if you use Variant 2, do you have a schema to connect the adapter with NXT Wire? Fantastic work! |
|
|
|
Nov 18 2008, 06:18 PM
Post
#8
|
|
|
Member ![]() ![]() Group: Members Posts: 25 Joined: 20-February 08 From: Germany Member No.: 4,776 |
QUOTE(McKaamos) Is there already an NXT-G block available? you can write a NXT-G program with i2c blocks: http://www.mindsensors.com the NXT-G Blocks Repository IIC_Read.zip - I2C Read block version 1.0b by xw25adc 09/29/2007 IIC_Write.zip - I2C Write block version 1.0b by xw25adc 09/29/2007 QUOTE(esmetabot) Hi if you use Variant 2, do you have a schema to connect the adapter with NXT Wire? Cut down your quote please! this is the wiring diagram to connect the adapter with NXT Wire (see above): http://freenet-homepage.de/tomasf/nunchuk/circuit.png |
|
|
|
Nov 20 2008, 03:55 AM
Post
#9
|
|
|
Member ![]() ![]() Group: Members Posts: 21 Joined: 21-March 07 From: Delft, Holland Member No.: 1,607 |
You are right. alternative: use the simple level shifter with two MOSFETs see Philips Application note: http://www.nxp.com/acrobat_download/applic...s/AN10441_1.pdf and Philips AN97055 Rp left: 1,8k insight Nunchuk / Rp right: 82k Lego ![]() Edit: This is not tested but I think, that this circuit don't beat the low-level-voltage problem of NXT (4,7k input resistor) Use an IC like TI P82B96 DUAL BIDIRECTIONAL BUS BUFFER. Google for -> i2c level shifter So, it's not possible to use this level shifter? It is indeed the thing that I have tried, but it doesn't work out. What exactly is the low-level-voltage problem you refer too? I've used the Rp resistance at the NXT side of 82k as Lego prescribes. Apparently the NXT is not able to get the SDA or SCL lines to 0V if I look on a oscilloscope. |
|
|
|
Nov 20 2008, 05:59 PM
Post
#10
|
|
|
Member ![]() ![]() Group: Members Posts: 25 Joined: 20-February 08 From: Germany Member No.: 4,776 |
I've used the Rp resistance at the NXT side of 82k as Lego prescribes. Apparently the NXT is not able to get the SDA or SCL lines to 0V if I look on a oscilloscope. You are right. See my detailed description of the series resistors of 4,7kohm in this post: http://forums.nxtasy.org/index.php?showtop...ost&p=23376
|
|
|
|
Nov 23 2008, 10:21 AM
Post
#11
|
|
|
Member ![]() ![]() Group: Members Posts: 25 Joined: 20-February 08 From: Germany Member No.: 4,776 |
I've used the Rp resistance at the NXT side of 82k as Lego prescribes. Apparently the NXT is not able to get the SDA or SCL lines to 0V if I look on a oscilloscope. How to beat the series resistors of 4,7kohm inside NXT without desoldering the internal 1,8k pullup-resistors of Nunchuk? Try this simple bidirectional level shifter with a npn and pnp transistor. I have not tested my proprietary development, but the free Spice Simulator : LTspice IV simulate the circuit and works OK. With the two transistors (BC550 / BC560) the NXT pull down the LOW Level to 0,8V on the Nunchuk side. The 1,8k pullup inside the Nunchuk is the voltage source of this level booster. If the Nunchuk sinks the I2C-level to LOW the supply voltage of complementary Darlington transistors is zero.
level.png ( 3.7k )
Number of downloads: 6Hint: For DATA- and CLOCK-line you need 4 transistors and two resistors ;-) |
|
|
|
Dec 11 2008, 04:41 PM
Post
#12
|
|
|
Newbie ![]() Group: Members Posts: 1 Joined: 11-December 08 Member No.: 6,452 |
I found this post while search for some Wii Nunchuk info. If someone has made a video of this adapted Wii Nunchuk in action please post up a link. I'd love to put the video up on my Wii Nunchuk website. Awesome use of the device.
|
|
|
|
Dec 11 2008, 06:40 PM
Post
#13
|
|
|
Advanced Member ![]() ![]() ![]() Group: Members Posts: 1,384 Joined: 29-March 07 From: a black hole in a Gallaxy far far away Member No.: 1,687 |
It should be on NXTasy.org blog. It should be a few posts down...
-------------------- Seeing if I can combine VB.net and NXT together :]
Status: Worried that my hard drive will fail... T.E.C Date is in 5 days... |
|
|
|
May 28 2009, 05:48 PM
Post
#14
|
|
![]() Advanced Member ![]() ![]() ![]() Group: Members Posts: 207 Joined: 25-May 09 From: El país del taco! Member No.: 7,516 |
-------------------- One King to rule them all, One King to find them,
One King to bring them all and in the darkness bind them On Earth where shadows lie. |
|
|
|
Jun 27 2009, 07:47 PM
Post
#15
|
|
![]() Advanced Member ![]() ![]() ![]() Group: Members Posts: 207 Joined: 25-May 09 From: El país del taco! Member No.: 7,516 |
-EDIT- Double post.
-------------------- One King to rule them all, One King to find them,
One King to bring them all and in the darkness bind them On Earth where shadows lie. |
|
|
|
Feb 14 2010, 10:37 AM
Post
#16
|
|
|
Newbie ![]() Group: Members Posts: 6 Joined: 14-February 10 Member No.: 9,561 |
Could you post a picture of your program or attach it to a reply? I have made the sensor and would like to know how to program it in NXT-G. I already have the I2C Read/Write blocks but do not know how to use them for the nunchuck. Thanks! AZ_RobotLab |
|
|
|
Feb 14 2010, 10:43 AM
Post
#17
|
|
|
Newbie ![]() Group: Members Posts: 6 Joined: 14-February 10 Member No.: 9,561 |
Whoops! Double post.
|
|
|
|
Feb 18 2010, 10:40 PM
Post
#18
|
|
![]() Advanced Member ![]() ![]() ![]() Group: Members Posts: 207 Joined: 25-May 09 From: El país del taco! Member No.: 7,516 |
I actually never created the program, I never got around to buying a Nunchuk (I did find them for $8 on eBay though). It seems fairly easy. Get the multibyte I2C read block from this page. This page makes it seem like all you need to do is write 0x00 to register 0x40 at address 0x52 and read back 6 bytes (possible with the multibyte block; not possible with the regular I2C block). Then you need to interpret the bytes coming back.
I will try to get a nunchuk as soon as possible so that I can actually make sure that this works. For eight dollars.... -------------------- One King to rule them all, One King to find them,
One King to bring them all and in the darkness bind them On Earth where shadows lie. |
|
|
|
Feb 18 2010, 11:08 PM
Post
#19
|
|
|
Newbie ![]() Group: Members Posts: 6 Joined: 14-February 10 Member No.: 9,561 |
I actually never created the program, I never got around to buying a Nunchuk (I did find them for $8 on eBay though). It seems fairly easy. Get the multibyte I2C read block from this page. This page makes it seem like all you need to do is write 0x00 to register 0x40 at address 0x52 and read back 6 bytes (possible with the multibyte block; not possible with the regular I2C block). Then you need to interpret the bytes coming back. I will try to get a nunchuk as soon as possible so that I can actually make sure that this works. For eight dollars.... Thanks! |
|
|
|
Feb 23 2010, 08:01 PM
Post
#20
|
|
|
Newbie ![]() Group: Members Posts: 6 Joined: 14-February 10 Member No.: 9,561 |
I tried t.wolf's RobotC code and got three errors with the portion of code below when I tried to compile it.
CODE 60 if (sizeof(outbuf)==6) { 61 char Nunchuk[16]; 62 strcpy(Nunchuk, "aXaYgXgYgZCZ"); 63 64 if ((outbuf1[5]&0x01)!=0) {Nunchuk[11]=122;} //Show Z-Button 65 if ((outbuf1[5]&0x02)!=0) {Nunchuk[10]=99;} //Show C-Button 66 67 eraseDisplay(); //RobotC 68 69 for(int i=0; i<6; i++ ) { //RobotC 70 71 nxtDisplayStringAt(15*i,50,"%c", Nunchuk[2*i]); 72 nxtDisplayStringAt(15*i+5,50,"%c", Nunchuk[2*i+1]); 73 74 nxtDisplayStringAt(15*i,40,"%02X", outbuf1[i]); 75 } Here are the errors: Line 62 = **Error**:Procedure call Parameters don't match declaration for 'strcpy(byte &pToBuffer, const byte &pFromBuffer)' Line 71 **Error**:Multiple overloads for 'nxtDisplayStringAt' match [including some typedef promotions] Line 72 **Error**:Multiple overloads for 'nxtDisplayStringAt' match [including some typedef promotions] Does anybody know how to fix this? |
|
|
|
![]() ![]() |
| Lo-Fi Version | Time is now: 1st August 2010 - 04:30 AM |