2017-06-23 84 views
0

我遇到意外的结果使用wiringPiwiringPiI2CWriteReg16()函数,我不确定是否由于不正确的用法或其他原因。这是该函数的声明:Raspi I2C通信与Arduino问题与wiringPi

extern int wiringPiI2CWriteReg16 (int fd, int reg, int data); 

noteswiringPiI2C.c文件说明它类似于linux的SMBus代码,如果这能帮助内。

在我的Arduino(既是乌诺R3和饰品专业版),我运行这个削减的草图:

#include <Wire.h> 

#define SLAVE_ADDR 0x04 

void receive_data (int num_bytes){ 
    Serial.print("bytes in: "); 
    Serial.println(num_bytes); 

    while(Wire.available()){ 
    int data = Wire.read(); // tried char, uint8_t etc 
    Serial.println(data); 
    } 
    Serial.print("\n"); 
} 

void setup() { 
    Serial.begin(9600); 
    Wire.begin(SLAVE_ADDR); 
    Wire.onReceive(receive_data); 
} 

void loop() { 
    delay(500); 
} 

我认为Wire.read()将在字节边界打散的事情,但是这没有发生在我的情况。也许这是我的问题......一个误解。

不过,我有这样的C代码(需要安装wiringPi v2.36+):

// word.c 

#include <wiringPiI2C.h> 

void main(){ 
    int fd = wiringPiI2CSetup(0x04); 
    wiringPiI2CWriteReg16(fd, 0x00, 255); 
    wiringPiI2CWriteReg16(fd, 0x01, 256); 
} 

编译如下:

gcc -o word word.c -lwiringPi 

运行时,./word,我收到我的Arduino的串行以下输出:

bytes in: 3 
0 
255 
0 

bytes in: 3 
1 
0 
1 

在第一次打电话给wiringPiI2CWriteReg16(),我期望输出中的第一个字节为零(0x00),因为这是我请求的寄存器地址。第二个字节(255)也是正确的。第三个字节(0)与我所能说的没有任何关系(因为我只是将一个字节作为数据发送)。

但是,在第二次调用该函数时,我确实得到了寄存器的正确输出(第一个字节为0x01 == 1),但第二个字节为零,而第三个字节具有看起来是正确的余数(255 ==一个字节,+ 1)。问题是,第二个字节是0

如果我通过511或通过任何号码作为通话中的数据,则会产生完全相同的效果。

我的问题是我是否缺少显而易见的东西(我对C和Arduino相对较新),以及/或者如果我能得到一些关于如何更彻底地排除故障的指示。

+1

这是C?原谅我的可能inguorance Arduino,但'Serial.print()'等疑似C++成员函数? – ThingyWotsit

+0

我已经删除了该标签,因为这比平台更特定于任何语言。谢谢@ThingyWotsit – stevieb

回答

0

我发现问题出在我的Arduino代码中。在官方的Raspi论坛上,Gordon告诉我这些字节是分开读取的,LSB在第一位。在我所有的搜索过程中,我都没有遇到过这种情况,真的不太明白发生了什么。在我的Arduino草图中将I2C读取循环代码更改为:

while(Wire.available()){ 
    Wire.read(); // throw away register byte 

    int16_t data = Wire.read(); // LSB 
    data += Wire.read() << 8; // MSB 

    Serial.print("data: "); 
    Serial.println(data); 
} 

...一切正常。实际上,至少有一种方法可以通过Arduino上的I2C读取两个字节的值,并将这些字节重新组合在一起。