Hi,
I'm trying to get my Nunchuck working with my Arduino (Duemilanove), but I'm facing an error that I can't really understand...
I've wired it up as the following:
Vcc - +5v
Gnd - Gnd
Clock - Analog 5
Data - Analog 4
I changed the I2C frequency to 400khz and uncommented "#define ATMEGA8" (altough I don't really understand what the second thing does) according to this (http://www.windmeadow.com/node/42) tutorial.
But I always get stuck in the Wire.endTransmission() function, and i don't know what to do...
I've found several threads concernig this (or similar) problems, but none of them revealed a real solution (except from adding additional pullup resostors, which I tried btw)
Wire.endtransmission does the actual sending. So it might be a hardware failure. How long is the cable? and did you use the recommended pullup resistors.
The sketch hangs up too, at least is doesn't generate any more output after the initial message for more than 1 min...
I tried it with and without pullup resistors(5,6K), always the same...
The cable is still the original from the Nunchuk, about 0.75 meters.
screwdriver:
That's the point. The function doesn't return, the Arduino gets stuck somewhere in it.
As I recall, Wire.endTransmission goes into two tight loops, relying on interrupts to pull it out of them. Interrupts like the end of the transmission.
Now they normally work. I would check your wiring, and in particular you may need pull-up resistors (eg. 4.7K) on both the SDA and SCL lines (to the +5V line).
A cable length of 0.75 meters sounds rather long to me. I2C is supposed to be "I²C (Inter-Integrated Circuit)", not "connect my processor to something a few feet away".
Try lower-value pull-up resistors, and also try slowing it down. After the Wire.begin () try adding something like:
I got it working now, you were right, it was the wire...It turned out it wasn't an original Nunchuk but a fake one (with an unshielded cable), so I sent it back and bought a new one and now it works...
BUT it still doesn't behave like I want it to...
I'm using this code to receive and process the data:
byte a,b,c,d,e,f;
uint16_t sx = 0;
uint16_t sy = 0;
uint16_t ax = 0;
uint16_t ay = 0;
uint16_t az = 0;
byte bit0 = 1;//00000001;
byte bit1 = 2;//00000010;
byte bit2 = 4;//00000100;
byte bit3 = 8;//00001000;
byte bit4 = 16;//00010000;
byte bit5 = 32;//00100000;
byte bit6 = 64;//01000000;
byte bit7 = 128;//10000000;
Wire.beginTransmission(NUNCHUCK_ADDRESS);
Wire.send(0x00);
Wire.endTransmission();
delayMicroseconds(250);
Wire.requestFrom(NUNCHUCK_ADDRESS,6);
a = Wire.receive();
b = Wire.receive();
c = Wire.receive();
d = Wire.receive();
e = Wire.receive();
f = Wire.receive();
sx = a;
sy = b;
ax = ((c<<2)+ ((f&bit3)>>2) + ((f&bit2)>>2));
ay = ((d<<2)+ ((f&bit5)>>4) + ((f&bit4)>>4));
az = ((e<<2)+ ((f&bit7)>>6) + ((f&bit6)>>6));
delay(25);
It all compiles and runs properly, and the values I get seem realistic, with one exception:
If I hold it horizontally the z value goes (as its supposed to) ~300, but if I turn it upside down, the z value doesn't go to ~720(as you would expect) but only to ~520.
Its the same with the other axis: if I tilt it fully left the value is about 300, but when I tilt it full right the value doesn't climb much higher than 520. The same with forward and backward tilting, in the "lower value" direction they all work fine, but in the "upper value" direction they don't (The "resting" value of those axis currently not affected by gravity/other acceleration is around 510). The only way to get higher values is rapidly moving it to one direction or shaking it.
I don't have any clue where this behavior comes from...
(The values for the stick seem allright...)
Can you display an example of what you get from a,b,c,d,e,f in the problem case?
I'm mildly suspicious of using bytes for a,b,c,d,e,f on the grounds that (c<<2) (etc.) would shift out the 2 most significant bits, unless the compiler promotes them to ints before. This would account for values not being much higher than 512. Actually they shouldn't be much higher than 256 so that theory doesn't totally hold water.
You could try changing the type for a,b,c,d,e,f to uint16_t, just to see if that helps.
Otherwise let's see the raw values, and hand-calculate them.
Further Googling seems to reveal that maybe you simply need to adjust your expected range (so if you get a max of 520, just allow for it). Also see this page about calibration of the nunchuck. Maybe you either need to send, or receive, calibration data to compensate the figures you are getting ...