2013-06-24 75 views
1

我正在開發一個項目,將Nintendo Nunchuk與Arduino同步。我發現了一個碼在線爲相同的http://letsmakerobots.com/node/5684Arduino代碼不會在Wire.endTransmission線後執行

這裏,是代碼

#include <Wire.h>; 

void setup(){ 
Serial.begin(19200); 
nunchuck_setpowerpins(); 
nunchuck_init(); 
Serial.print("Nunchuck ready\n"); 
} 

void loop(){ 
nunchuck_get_data(); 
nunchuck_print_data(); 
delay(1000); 
} 
//======================================================================================================================================================================================================// 
//Do not modify!!!!!!!! 
//======================================================================================================================================================================================================// 


// 
// Nunchuck functions 
// 

static uint8_t nunchuck_buf[6]; // array to store nunchuck data, 

// Uses port C (analog in) pins as power & ground for Nunchuck 

static void nunchuck_setpowerpins() 
{ 
#define pwrpin PORTC3 
#define gndpin PORTC2 
DDRC |= _BV(pwrpin) | _BV(gndpin); 
PORTC &=~ _BV(gndpin); 
PORTC |= _BV(pwrpin); 
delay(100); // wait for things to stabilize 
} 

// initialize the I2C system, join the I2C bus, 
// and tell the nunchuck we're talking to it 
void nunchuck_init() 
{ 
Wire.begin(); // join i2c bus as master 
Wire.beginTransmission(0x52); // transmit to device 0x52 
Wire.send(0x40);  // sends memory address 
Wire.send(0x00);  // sends sent a zero. 
Wire.endTransmission(); // stop transmitting 
} 

// Send a request for data to the nunchuck 
// was "send_zero()" 
void nunchuck_send_request() 
{ 
Wire.beginTransmission(0x52); // transmit to device 0x52 
Wire.send(0x00);  // sends one byte 
Wire.endTransmission(); // stop transmitting 
} 

// Receive data back from the nunchuck, 
// returns 1 on successful read. returns 0 on failure 
int nunchuck_get_data() 
{ 
int cnt=0; 
Wire.requestFrom (0x52, 6); // request data from nunchuck 
while (Wire.available()) { 
// receive byte as an integer 
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive()); 
cnt++; 
} 
nunchuck_send_request(); // send request for next data payload 
// If we recieved the 6 bytes, then go print them 
if (cnt >= 5) { 
return 1; // success 
} 
return 0; //failure 
} 

// Print the input data we have recieved 
// accel data is 10 bits long 
// so we read 8 bits, then we have to add 
// on the last 2 bits. That is why I 
// multiply them by 2 * 2 
void nunchuck_print_data() 
{ 
static int i=0; 
int joy_x_axis = nunchuck_buf[0]; 
int joy_y_axis = nunchuck_buf[1]; 
int accel_x_axis = nunchuck_buf[2]; // * 2 * 2; 
int accel_y_axis = nunchuck_buf[3]; // * 2 * 2; 
int accel_z_axis = nunchuck_buf[4]; // * 2 * 2; 

int z_button = 0; 
int c_button = 0; 

// byte nunchuck_buf[5] contains bits for z and c buttons 
// it also contains the least significant bits for the accelerometer data 
// so we have to check each bit of byte outbuf[5] 
if ((nunchuck_buf[5] >> 0) & 1) 
z_button = 1; 
if ((nunchuck_buf[5] >> 1) & 1) 
c_button = 1; 

if ((nunchuck_buf[5] >> 2) & 1) 
accel_x_axis += 2; 
if ((nunchuck_buf[5] >> 3) & 1) 
accel_x_axis += 1; 

if ((nunchuck_buf[5] >> 4) & 1) 
accel_y_axis += 2; 
if ((nunchuck_buf[5] >> 5) & 1) 
accel_y_axis += 1; 

if ((nunchuck_buf[5] >> 6) & 1) 
accel_z_axis += 2; 
if ((nunchuck_buf[5] >> 7) & 1) 
accel_z_axis += 1; 

Serial.print(i,DEC); 
Serial.print("\t"); 

Serial.print("joy:"); 
Serial.print(joy_x_axis,DEC); 
Serial.print(","); 
Serial.print(joy_y_axis, DEC); 
Serial.print(" \t"); 

Serial.print("acc:"); 
Serial.print(accel_x_axis, DEC); 
Serial.print(","); 
Serial.print(accel_y_axis, DEC); 
Serial.print(","); 
Serial.print(accel_z_axis, DEC); 
Serial.print("\t"); 

Serial.print("but:"); 
Serial.print(z_button, DEC); 
Serial.print(","); 
Serial.print(c_button, DEC); 

Serial.print("\r\n"); // newline 
i++; 
} 

// Encode data to format that most wiimote drivers except 
// only needed if you use one of the regular wiimote drivers 
char nunchuk_decode_byte (char x) 
{ 
x = (x^0x17) + 0x17; 
return x; 
} 

// returns zbutton state: 1=pressed, 0=notpressed 
int nunchuck_zbutton() 
{ 
return ((nunchuck_buf[5] >> 0) & 1) ? 0 : 1; // voodoo 
} 

// returns zbutton state: 1=pressed, 0=notpressed 
int nunchuck_cbutton() 
{ 
return ((nunchuck_buf[5] >> 1) & 1) ? 0 : 1; // voodoo 
} 

// returns value of x-axis joystick 
int nunchuck_joyx() 
{ 
return nunchuck_buf[0]; 
} 

// returns value of y-axis joystick 
int nunchuck_joyy() 
{ 
return nunchuck_buf[1]; 
} 

// returns value of x-axis accelerometer 
int nunchuck_accelx() 
{ 
return nunchuck_buf[2]; // FIXME: this leaves out 2-bits of the data 
} 

// returns value of y-axis accelerometer 
int nunchuck_accely() 
{ 
return nunchuck_buf[3]; // FIXME: this leaves out 2-bits of the data 
} 

// returns value of z-axis accelerometer 
int nunchuck_accelz() 
{ 
return nunchuck_buf[4]; // FIXME: this leaves out 2-bits of the data 
} 

當我寫,Serial.Println( 「結束」),在Wire.endTransmission後線();在函數nunchuck_init()中,它不會顯示在串行監視器上。

此外,由於在nunchuck_init()被調用後寫入,它不會在串行監視器上顯示Nunchuck。 我在Arduino 0023,Windows 7上工作。

+0

首先,我推薦使用最新的IDE版本。沒有很好的理由去調試已知問題的舊代碼/庫。 – mpflaga

+0

是否會發生同樣的問題,如果您將Serial.Println(「結束」);在nunchuck_init()之後;在setup()中? – mpflaga

回答

3

現存的Arduino Wire庫存在的問題是沒有超時。
endTransmission函數可能會在不同的場景中掛起微控制器。

此問題已在其他幾個forums中討論過,到目前爲止我發現的最佳解決方案是使用備用庫。

Arduino的I2C主圖書館由韋恩·Truchsess
http://www.dsscircuits.com/index.php/articles/66-arduino-i2c-master-library

通過適當的超時,它固定在我的系統讀取MMA7455的Accelero

在提供的源代碼上的問題,有一個例子它顯示瞭如何使用Wire與I2C主庫完成相同的程序。 您可以使用該示例輕鬆修改您的代碼以採用新庫。