2

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.

4
  • I took the liberty to edit your question. Could you review it. In addition, could you explain what is "not working" ? Syntax error ? data not send ? ... ? Commented Aug 29, 2014 at 11:59
  • Hi there. Thanks for your help. i Tried your solution, and it still gives me the same error: bus.write_i2c_block_data(i2c_adress, 0, decodedArray) IOError: [Errno 5] Input/output error. I'am out of ideas... Commented Aug 29, 2014 at 12:12
  • I didn't try to provide an answer. Just to fix your question formating. If you have more info, like the error message above, please edit you question to mention it. Other peoples will not necessary take the time to "dig" into the comments to find various clues. Commented Aug 29, 2014 at 12:18
  • Just did that right now. Commented Aug 29, 2014 at 12:21

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Ok that explained really well the i2c protocol, but what i can't understand is what cmd value is used for? I tried again and again and it keep failing. Sorry to be a newbie.
In practice the byte of cmd and bytes of data are all send exactly the same way. The general use case in I2C is to write a value in a register. So you select the device address, the register on the device, and after you write your data.
I think the problem you have is in the arduino code, or electrical. I suggest you to try with a compliant I2C device first before trying to communicate to your arduino. (eeprom, thermal captor... lot of cheap chip exist)
I totally agree with you, but the i2c is functional, i can send a byte and receive it, i just can't send an array of data. And that's what i really need.
I already use this particular function a lot of time without any problem sending plenty of data. The fact it's functional with only one byte but not more made me nearly sure it's a problem on the arduino side. (Witch I never used, can't help)
|
0

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.

Comments

0

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])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.