Raspi I2C 与 Arduino 的通信问题与 wiringPi
Raspi I2C communication with Arduino issues with wiringPi
我在使用 wiringPi
的 wiringPiI2CWriteReg16()
函数时遇到意外结果,我不确定这是由于使用不当还是其他原因造成的。这是函数的声明:
extern int wiringPiI2CWriteReg16 (int fd, int reg, int data);
wiringPiI2C.c
文件中有 notes 声明它类似于 Linux 的 SMBus
代码,如果有帮助的话。
在我的 Arduino(一个 Uno R3 和一个 Trinket Pro)上,我正在 运行 制作这个简化的草图:
#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 比较陌生),and/or 如果我能得到一些关于如何更彻底地解决这个问题的指示。
我发现问题出在我的 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 读取两个字节值并将字节放回一起的方法。
我在使用 wiringPi
的 wiringPiI2CWriteReg16()
函数时遇到意外结果,我不确定这是由于使用不当还是其他原因造成的。这是函数的声明:
extern int wiringPiI2CWriteReg16 (int fd, int reg, int data);
wiringPiI2C.c
文件中有 notes 声明它类似于 Linux 的 SMBus
代码,如果有帮助的话。
在我的 Arduino(一个 Uno R3 和一个 Trinket Pro)上,我正在 运行 制作这个简化的草图:
#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 比较陌生),and/or 如果我能得到一些关于如何更彻底地解决这个问题的指示。
我发现问题出在我的 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 读取两个字节值并将字节放回一起的方法。