如何通过I2C发送数组?
我这几天一直在尝试通过I2C发送一个Python数组。
data = [x,x,x,x] # `x` is a number from 0 to 127.
bus.write_i2c_block_data(i2c_address, 0, data)
bus.write_i2c_block_data(addr, cmd, array)
在上面的函数中:addr 是 Arduino 的 I2C 地址;cmd - 我不太确定这是什么;array - 是一个包含整数的 Python 数组。
这能实现吗?实际上这个 cmd 是什么呢?
顺便提一下,这是我在 Arduino 代码中接收数组并将其放入 byteArray
的部分:
void receiveData(int numByte){ int i = 0; while(wire.available()){ if(i < 4){ byteArray[i] = wire.read(); i++; } } }
我遇到了这个错误:
bus.write_i2c_block_data(i2c_adress, 0, decodedArray) IOError: [Errno 5] Input/output error.
我试过这个:bus.write_byte(i2c_address, value)
,它可以工作,但只适用于从 0 到 127 的 value
,而我需要传递的不仅仅是一个值,而是一个完整的数组。
3 个回答
0
cmd是你想要写入数据的偏移量。
所以它就像这样:
bus.write_byte(i2c_address, offset, byte)
但是如果你想写入一个字节数组,那么你需要写入块数据,这样你的代码就会像这样:
bus.write_i2c_block_data(i2c_address, offset, [array_of_bytes])
3
这个函数是个好函数。
不过你需要注意一些要点:
- bus.write_i2c_block_data(addr, cmd, []) 会把 cmd 的值和列表里的值一起发送到 I2C 总线上。
所以
bus.write_i2c_block_data(0x20, 42, [12, 23, 34, 45])
实际上发送给设备的不是 4 个字节,而是 5 个字节。
我不知道 Arduino 上的 wire 库是怎么工作的,但设备只读取 4 个字节,它不会对最后一个字节发送确认信号(ACK),这就导致发送方检测到输出错误。
- I2C 设备地址有两种约定。I2C 总线有 7 位用于设备地址,还有一位用来表示是读取还是写入。另一种(错误的)约定是用 8 位来表示地址,并说你有一个用于读取的地址和一个用于写入的地址。smbus 包使用的是正确的约定(7 位)。
举个例子:在 7 位约定下,0x23 变成写入时的 0x46,读取时的 0x47。
0
我花了一些时间,但终于搞定了。
在Arduino那边:
int count = 0;
...
...
void receiveData(int numByte){
while(Wire.available()){
if(count < 4){
byteArray[count] = Wire.read();
count++;
}
else{
count = 0;
byteArray[count] = Wire.read();
}
}
}
在树莓派那边:
def writeData(arrayValue):
for i in arrayValue:
bus.write_byte(i2c_address, i)
就这样。