我正在尝试通过 I2C 将从 Arduino Uno 发送的数据发送到 Raspberry Pi 4。我似乎能够从 Uno 毫无问题地发送数据,但是数据没有在 Raspberry Pi 4 上读入。我对下面的代码做了不同的排列,似乎没有任何效果。
在下面的代码中,我将从属进程设置为0x08。我知道 RPi 可以看到它,
i2cdetect -y 1 # returns 08
许多不同的网站建议使用 gpio 和 WiringPi,但这些不再可用?
这是 Arduino 的代码:
#include <Wire.h>
byte val = 0;
void setup() {
Serial.begin(9600);
Serial.print(" Starting slave ");
Wire.begin();
}
void loop() {
Wire.beginTransmission(0x08);
Wire.write(val++);
Serial.print("sent: "); Serial.println(val-1);
Wire.write(val++);
Serial.print("sent: "); Serial.println(val-1);
Wire.write(val++);
Wire.endTransmission();
delay(500);
}
这是我的 Raspberry Pi 4 的 C++ 代码:
#include <unistd.h> //Needed for I2C port
#include <fcntl.h> //Needed for I2C port
#include <sys/ioctl.h> //Needed for I2C port
#include <linux/i2c-dev.h> //Needed for I2C port
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
int main() {
int file_i2c;
int length;
unsigned char buffer[60] = {0};
//----- OPEN THE I2C BUS -----
char *filename = (char*) "/dev/i2c-1";
cout << "Starting the program \n";
if ((file_i2c = open(filename, O_RDWR)) < 0) {
cerr << "Failed to open the i2c bus\n";
return -1;
}
int addr = 0x08; //<<<<<The I2C address of the slave
if (ioctl(file_i2c, I2C_SLAVE, addr) < 0) {
cerr << "Failed to acquire buss access and / or talk to slave.\n";
return -1;
}
//----- READ BYTES -----
while (true) {
length = 24; //<<< Number of bytes to read
if (read(file_i2c, buffer, length) != length) {
//ERROR HANDLING: i2c transaction failed
cerr << "Failed to read from the i2c bus\n";
}
else {
if (strlen((char*)buffer))
printf("Data read: %s -> %d\n", buffer, strlen((char*)buffer));
}
}
}
感谢您的帮助!
这不是 I2C 的工作原理。
在 UART 通信中,您有两个或多或少相同的设备相互通信,并且它们都可以随时发送(除非流量控制等)。
I2C 中并非如此。在 I2C 中,您有一个主机和多个从机(或您想使用的任何术语),并且“所有”通信都必须由主机发起。您正在尝试让 RPi 主控从 Arduion 主控写入进行读取 - 这永远不会起作用。 好的一面是,Arduino Wire 库实际上似乎支持通过使用
onReceive()
和
onRequest()
注册回调函数来将 Arduino 设置为从设备。阅读此处:https://docs.arduino.cc/learn/communication/wire并查看Controller Reader和Controller Writer示例。在这两个示例中,您都想查看外围草图部分。