私は、I2Cを使用して前後に話す複数のアルドゥーノを持っています。マスタは2バイトを書き込んだ後、1バイトの応答を返します。すべてが素晴らしいとhorray働いた。しかし今、私はマスターをラズベリーパイに切り替えています。私が書いたコードは問題なく動作しますが、200回の読み取り/書き込みごとに1回、時々間違った読みを返します。これはシステムの信頼性に大きく影響します。誰かが私に間違ってやっていることを誰かが見た場合や、他の誰かがこれまでに同様の問題に遭遇した場合に備えて、私のコードを添付しています。ラズベリーパイI2C
RPI C++コード:
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "../HaMiD_Lib/StopWatch.h"
using namespace std;
int file_i2c;
int length;
uint8_t buffer[2] = {0};
int timingLoopFreq = 500;
int timingLoopMicroSeconds = 1000000/timingLoopFreq; //500 us
StopWatch loopTime(timingLoopMicroSeconds); // My own stopwatch livrary
uint8_t addr = 0x11;
using namespace std;
int main(void)
{
//-------------- OPEN THE I2C BUS--------------------------
char *filename = (char*)"/dev/i2c-1";
if((file_i2c = open(filename, O_RDWR))< 0){
//ERROR HANDLING: you can check errno to see what went wrong;
cout << "Failed to open the i2c bus" << endl;
return 0;
}
while(1){
if (loopTime.check()) {
loopTime.reset();
if (ioctl(file_i2c, I2C_SLAVE, addr) < 0){
cout << "Failed to acquire bus access and/or talk to slave" << endl;
//ERROR HANDLING: you can check errno to see what went wrong;
}
// ------------- WRITE BYTES -------------
buffer[0] = 4;
buffer[1] = 0;
length = 2; //<<<<< Number of bytes to write
if (write(file_i2c, buffer, length) != length){ // write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
// ERROR HANDLING: i2c transaction failed
cout << "Failed to write to the i2c bus " << endl;
} else {
// ------------ READ BYTES -------
length = 1;
if (read(file_i2c, buffer, length) != length){ // read() returns the number of bytes actually read, if it doesn't match then an error occurred (e.g. no response from the device)
//ERROR HANDLING: i2c transaction failed
cout <<"Failed to read from the i2c bus" << endl;
} else {
cout << "Data read:" << buffer[0] << endl;
}
}
}
}
cout << "exiting" << endl;
return 0;
}
ArduinoのI2Cスニペット:
//I2C functions
void receiveEvent(int byteCount) {
while (Wire.available()) {
I2C_cmd_1st = Wire.read(); // 1 byte (maximum 256 commands)
I2C_cmd_2nd = Wire.read(); // 1 byte (maximum 256 commands)
}
}
void slavesRespond() {
byte returnValue = 0;
switch (I2C_cmd_1st) {
case status_cmd: // 40
returnValue = module;
if (module == DONE) {
module = STOP; //reset the machine
}
break;
case test_cmd:
returnValue = ID;
break;
}
Wire.write(returnValue); // return response to last command
}
そして、ここではCOUTからの出力の小さなセクションです。データの読み込みは常に2を返しますが、i2cバスからの読み書きは失敗します(500分の1)場合は、間違った値が返されます(下の例では2を返しますが、時には3事故やそれが97などである可能性があります)。
Data read:2
Data read:3 //This is wrong!
Data read:2
Failed to read from the i2c bus
Failed to read from the i2c bus
Data read:3 //This is wrong!
Data read:2
任意の助けいただければ幸いです。他の誰かがRPiとArduinoに似た何かを見ましたか?配線は、RPiがマスターであるため、かなり単純です。
いいですよね。それは間違った読み書きを避けるためには間違いなく助けになりました。しかし、 "i2cバスからの読み込みに失敗しました"というメッセージが残っています。 答えとしてあなたのことを確認する前に、私は一日か二日待つか、誰か他の人が答えを持っているかどうかを確認します。 –
ルーカが言ったことは間違いなく助けになりました。しかし、さらに、スレーブが何かを送り返したことを確認して、メッセージが配信されたことを再確認する必要がありました。 –