0

I am working with I2C for the first time and having an issue with a very simple problem.

I want to send 2 bytes from an Arduino and nvidia jetson orin.

On the Arduino, my code looks like this:

    #include <Wire.h>
    int distance;
    byte array2send[2];
    int i2c_addr = 0x30;
    void setup(){
     //… other code

     Wire.begin(i2c_addr);
     Wire.onRequest(sendData);
    }
    // other code
    void sendData(){
     array2send[0] = distance >> 8;
     array2send[1] = distance & 0xFF;
     Wire.write(array2send, 2);
    }

And on the jetson I simple use python smbus library:

    import smbus
    bus = smbus.SMBus(7)
    bus.read_i2c_block_data(0x30,0,2)

This results in an TimeOutError and I can’t figure out why. On the hardware side, everything should be fine and sending/receiving a single byte (with bus.read_byte(0x30)) works just fine.

New contributor
Bobipuegi is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
4
  • what is your specific question? ... please edit your post ... add a focused, answerable question to your post Commented 2 days ago
  • "I want to send 2 bytes from an Arduino"... Your Arduino code is not sending anything, it waits for a REQUEST from an I2C master before sending the data. i.e. your Arduino code configure itself as a Slave Receiver. And your Jetson code is also just reading data from I2C bus. If you want to send data, look at the [master_writer](I want to send 2 bytes from an Arduino) example. Commented 2 days ago
  • One more thing, since you are connecting two hosts directly, make sure you have pull-up resistors on both SDA and SCL lines. Commented 2 days ago
  • @hcheung: On the Jetson, both bus.read_byte() and bus.read_i2c_block_data() are "master reader" actions. Commented 2 days ago

1 Answer 1

1

I know a lot about I2C in general, but very little about the Arduino libraries that implement it. So this might not answer your question, but perhaps it will shed a little light on the situation. (And it's too long for a comment.)

I think that the key difference between bus.read_byte() and bus.read_i2c_block_data() is that the former does a simple I2C bus read cycle, while the latter is doing a more complex sequence involving a write cycle, a repeated start and then a read cycle. This is because bus.read_i2c_block_data() is assuming that the slave device (your Arduino in this case) has "registers", and it needs to transmit the register number before it tries to read data from the register.

I spent some time looking at the source code for the Wire library for the Arduino, and it appears to me that this should Just Work. There is a default handler for the write cycle, which should simply stuff the register address into a buffer (which you never look at), and then the read cycle should complete as usual, with the callback to your sendData() function. But perhaps there's some subtlety in the either the library code or the Arduino hardware that's preventing that from happening.

Another issue is that you have basically only one I2C clock cycle (i.e., 10 µs, assuming that the Jetson is adhering to the 100 kHz SMBus clock speed) to prepare the data to transmit on the Arduino side. It's possible that the software overhead in the library and in your callback before you actually call Wire.write() exceeds this, resulting in no data transmitted to the Jetson at all, causing the timeout.

The library documentation is not at all helpful regarding more complex scenarios like this one. And I really don't have time right now to dig into the hardware documentation to see how the hardware would handle this sequence.

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.