0

I am currently working with I2C in Arch Linux Arm and not quite sure how to calculate the absolute minimum delay there is required between a write and a read. If i don't have this delay the read naturally does not come through. I have just applied usleep(1000) between the two commands, which works, but its just done empirically and has to be optimized to the real value (somehow). But how?.

Here is my code sample for the write_and_read function i am using:

int write_and_read(int handler, char *buffer, const int bytesToWrite, const int bytesToRead) {
    write(handler, buffer, bytesToWrite);
    usleep(1000);
    int r = read(handler, buffer, bytesToRead);
    if(r != bytesToRead) {
        return -1;
    }
    return 0;
}
JavaCake
  • 4,075
  • 14
  • 62
  • 125

1 Answers1

1

Normally there's no need to wait. If your writing and reading function is threaded somehow in the background (why would you do that???) then synchronizating them is mandatory.

I2C is a very simple linear communication and all the devices used my me was able to produce the output data within microsecs.

Are you using 100kHz, 400kHz or 1MHz I2C?

Edited: After some discuss I suggest you this to try:

void dataRequest() {
    Wire.write(0x76);
    x = 0;
}

void dataReceive(int numBytes)
{
    x = numBytes;
    for (int i = 0; i < numBytes; i++) {
        Wire.read();
    }
}

Where x is a global variable defined in the header then assigned 0 in the setup(). You may try to add a simple if condition into the main loop, e.g. if x > 0, then send something in serial.print() as a debug message, then reset x to 0.

With this you are not blocking the I2C operation with the serial traffic.

KZD76
  • 122
  • 7
  • Thats what i thought initially, but it does not work without the delay between the write and read. – JavaCake Jan 28 '15 at 06:35
  • What is the write function? What device are you communicating with? – KZD76 Jan 28 '15 at 06:36
  • I am using the `linux/i2c-dev.h`. The devices are simple Atmel/Arduino controllers. – JavaCake Jan 28 '15 at 06:41
  • On Arduino is there any delay in your main loop or in the receive / request events? – KZD76 Jan 28 '15 at 07:03
  • I have no delays in my loop what so ever. Actually my loop is empty as we speak. There are only the interrupts for the receive and request functions. – JavaCake Jan 28 '15 at 07:10
  • Other options in my mind to try: clear all in receive and request events to not block the code there, then if it works, try to do everything in the receive event, request event should be a simple answering function without any "logic" there. – KZD76 Jan 28 '15 at 08:07
  • I only return data in the request, and do pretty much everything in the receive as you describe. I have a logic analyzer which i intend to use in order to determine the frequency the I2C bus is running with. – JavaCake Jan 28 '15 at 08:32
  • Is some part of your arduino code public? I would try to run in my architecture. – KZD76 Jan 28 '15 at 08:47
  • This is basically what i have now: https://gist.github.com/anonymous/0b62be94302c26b4c6fb – JavaCake Jan 28 '15 at 09:23
  • Serial communication can slows the processing and in this case your code is delaying the I2C communication. I edited my answer with some code, could you please try it? – KZD76 Jan 28 '15 at 09:58
  • I just did the test and only the først receive command goes through, everything else afterwards does not trigger the recieve callback. – JavaCake Jan 28 '15 at 10:07
  • Sorry, forgot to read the data you sent. Modified the code with a for loop. – KZD76 Jan 28 '15 at 10:11
  • 1
    Very stupid mistake. I forgot to read in the Arduino. FYI i did not downvote. – JavaCake Jan 28 '15 at 12:19
  • 1
    I'm glad I could help you in the end. – KZD76 Jan 28 '15 at 12:25