简体   繁体   中英

How to send an array by i2c?

I've been trying for several days now to send a python array by i2c.

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) 

In the function above: addr - arduino i2c adress; cmd - Not sure what this is; array - python array of int numbers.
Can this be done? What is actually the cmd?


FWIW, Arduino code, where I receive the array and put it on the byteArray :

 void receiveData(int numByte){ int i = 0; while(wire.available()){ if(i < 4){ byteArray[i] = wire.read(); i++; } } }

It gives me this error:
bus.write_i2c_block_data(i2c_adress, 0, decodedArray) IOError: [Errno 5] Input/output error.
I tried with this: bus.write_byte(i2c_address, value) , and it worked, but only for a value that goes from 0 to 127, but, I need to pass not only a value, but a full array.

The function is the good one.

But you should take care of some points:

  • bus.write_i2c_block_data(addr, cmd, []) send the value of cmd AND the values in the list on the I2C bus.

So

bus.write_i2c_block_data(0x20, 42, [12, 23, 34, 45])

doesn't send 4 bytes but 5 bytes to the device.

I doesn't know how the wire library work on arduino, but the device only read 4 bytes, it doesn't send the ACK for the last bytes and the sender detect an output error.

  • Two convention exist for I2C device address. The I2C bus have 7 bits for device address and a bit to indicate a read or a write. An other (wrong) convention is to write the address in 8 bits, and say that you have an address for read, and an other for write. The smbus package use the correct convention (7 bits).

Exemple: 0x23 in 7 bits convention, become 0x46 for writing, and 0x47 for reading.

It took me a while,but i got it working.

On the arduino side:

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();
      }
    }
}  

On the raspberry side:

def writeData(arrayValue):

    for i in arrayValue:
        bus.write_byte(i2c_address, i)

And that's it.

cmd is offset on which you want to write a data. so its like

bus.write_byte(i2c_address, offset, byte)

but if you want to write array of bytes then you need to write block data so your code will look like this

bus.write_i2c_block_data(i2c_address, offset, [array_of_bytes])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM