2013-06-24 73 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主库完成相同的程序。 您可以使用该示例轻松修改您的代码以采用新库。