Hello and welcome to our community! Is this your first visit?
Results 1 to 2 of 2
  1. #1
    Senior Pilot
    Join Date
    May 2011
    Reputation Points (Add)

    Using i2c interrupt for interrupt service routine

    It seems that the sensor loop could be sped up by making some mechanism to allow the "normal" (not sensor acquistion code run) while the i2c data is being shifted out of the sensor, by using an interrupt service routine based on the i2c data ready register...instead of holding up the loop waiting for the i2c data to be ready....at 400khz it taks approximately....

    with atmetga at 16mhz and i2c at 400khz it seems that every register read wastes about 1/400khz*8bits=20us/(1/16Mhz...62.5ns)= 320 clock cycles.... plus each sensor read takes 3 transactions and then you read the sensor a bunch of times...that adds up pretty quick...Check my math please or you could just say 16Mhz/(8bits@/400khz)=320 clock cycles per byte...

    There is probably some reason that an interrupt service routine is not used....the arduino only has one isr vector, so there would have to be some logic in it to tell the processor where to put the data and that would take some clock cycles...but I was just suggesting it. If you were looking for a speed increase..

    You all my be doing this but from what I saw it looks like the loop is just held up
    For example this code stops the loop until data is ready

    int readWordWaitI2C(int deviceAddress) {
    unsigned char msb, lsb;
    Wire.requestFrom(deviceAddress, 2); // request two bytes
    while(!Wire.available()); // wait until data available
    msb = Wire.receive();
    while(!Wire.available()); // wait until data available
    lsb = Wire.receive();
    return (((int)msb<<8) | ((int)lsb));

    If you were to some how use the interrupt register and jump to the interrupt service routine you would be able to speed things up a bunch!

    Let me know if I am wrong here!

    There is some register to set for the i2c interrupt enable somewhere. I will have to look it up later or something....Anyways let me know if someone has done this already...

    Looks like page 266 on atmega 2560 data sheet it is the TWCR register bit 0 is the interrupt enable bit. I am not sure how to enable that in arduino ide but I assume it is possible...Anyways cool stuff.

    Anyways I will have to look up the other registers that have to be set, and how to do that in arduino ide...hopefully somebody beats me too it!
    Last edited by blue23; 10-15-2011 at 11:03 PM.

  2. #2
    Senior Pilot
    Join Date
    May 2011
    Reputation Points (Add)
    hmmm it is worse than i thought. From what i see in the arduino ide the i2c is running only at 100khz by default....but you can increase the speed to 400khz by doing what is done in the following link...


    I just looked at my ide and mine was set to 100khz....so change that to 400Khz and you will get a pretty good speed increase!

    Or is this being done some other way already?

    I looked through the aeroquad code and did not find the register being set to 400khz anywere something like this????

    #define TWI_FREQ 400000L
    TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;

    Cause if that is left unset, then my estimate of 320 clock cycles is multiplied by 4 to yield 1280 clock cycles per 8 bits...thats a lot...I still like i2c interface though...we just need to use the interface a bit better to get more speed i think...but I have no real idea i have not dug into the code enough yet.

    EDIT:OOPS I am an idiot...I found it in aeroquad.pde

    #if defined(AeroQuad_v18) || defined(AeroQuadMega_v2) || defined(AeroQuad_Mini)
    // Recommendation from Mgros to increase I2C speed to 400kHz
    // http://aeroquad.com/showthread.php?9...ll=1#post11262
    TWBR = 12;
    Last edited by blue23; 10-16-2011 at 10:14 AM.



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts