I2C smbus2 block data
Posted: Tue Sep 12, 2017 3:19 am
Hello, I'm working on a project exchanging data between an RPi and Arduino, and have been forced to switch to I2C as my communication protocol for several reasons. I've had success using simple read and write requests to pass single bytes of data back and forth. But I'm trying to pass a bunch of bytes, so I'm trying to use read_i2c_block_data from the smbus2 library. I continue to get the following error no matter what I try:
Line 17 is the " x = bus.read_i2c_block_data(address, 0, numBytes)" line. I've read that this is sometimes related to there being nothing on the other end of the i2c bus, but I can't see where the problem is. I've also tried several different ways of doing the read_i2c_block_data and this is most similar to the very limited examples I've found. Any suggestion is appreciated. Many thanks.
Here is my code for the Pi:
Here is the Arduino code:
Code: Select all
Traceback (most recent call last):
File "/home/pi/sketchbook/I2Ctalk04/I2Ctalk04.py", line 36, in <module>
readBunchOfData(4)
File "/home/pi/sketchbook/I2Ctalk04/I2Ctalk04.py", line 25, in readBunchOfData
myDataHere = readBlockData(numBytes)
File "/home/pi/sketchbook/I2Ctalk04/I2Ctalk04.py", line 17, in readBlockData
x = bus.read_i2c_block_data(address, 0, numBytes)
File "/usr/local/lib/python3.4/dist-packages/smbus2/smbus2.py", line 391, in read_i2c_block_data
ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O errorHere is my code for the Pi:
Code: Select all
from smbus2 import SMBus
import time
bus = SMBus(1)
address = 0x04
def writeNumber(value):
bus.write_byte(address, value)
return -1
def readNumber():
number = bus.read_byte(address)
return number
def readBlockData(numBytes):
res3 = []
x = bus.read_i2c_block_data(address, 0, numBytes)
res3.extend(x)
return res3
def readBunchOfData(numBytes):
# Send number of bytes we are requesting
writeNumber(numBytes)
# Receive data
myDataHere = readBlockData(numBytes)
# Show what we've got
print ("We received ", numBytes, " of data")
for i in range(0, numBytes):
print (myDataHere[i])
while True:
# For now, hard-code 4 bytes of data
print ()
print ("We are requesting ", 4, " bytes of data")
readBunchOfData(4)
print ()
Code: Select all
#include <Wire.h>
#define SLAVE_ADDRESS 0x04
int number = 0;
int dataNo = 0;
void setup() {
Serial.begin(9600);
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
Serial.println("Ready!");
}
void loop() {
doingSomething(10);
}
void doingSomething(int loops) {
for (int i = 0; i<loops; i++) {
Serial.print("I'm doing something else...");
Serial.println(i);
delay(50);
}
}
void receiveData(int byteCount) {
while(Wire.available()) {
number = Wire.read();
if (dataNo == 0) {
// dataNo, so this is how many bytes to send - currently hard-coded at 4
dataNo = number;
}
else {
// We should not get here
Serial.println("We got to hole 1");
}
}
}
void sendData() {
byte output[] = {0x01,0x02,0x03,0x04}; // This is just some sample data for testing
Wire.write(output, 4);
dataNo = 0;
}