Wire library(I2C connection) disables interrupts ?

Hi,

I didn't find answer anywhere so I'll just ask. Does the I2C connection with other devices (like compass), disable external interrupts (INT0 and INT1) ?

I have a program where servo is moving according to bearing that it gets from compass. One channel on the RC reciever(connected to INT0) is used as a switch and when it is "turned on" it should give me manual control of servo instantly, but instead I get control of it only after desired bearing from compass has been reached.(when the function with automated control ends). In this function there are mostly while loops where arduino constantly reads from I2C.

Does the I2C connection with other devices (like compass), disable external interrupts (INT0 and INT1) ?

No. But, when a message is being received, interrupts are disabled.

One channel on the RC reciever(connected to INT0) is used as a switch and when it is "turned on" it should give me manual control of servo instantly, but instead I get control of it only after desired bearing from compass has been reached.

But, it's not necessary that we see the code, even though you posted in the Programming section, where we, silly us, do expect to see some code. All of it, as a matter of fact.

Compass:

int compass(char option){
  byte highByte, lowByte; //, fine;              // highByte and lowByte store high and low bytes of the bearing and fine stores decimal place of bearing
   char pitch, roll;                          // Stores pitch and roll values of CMPS10, chars are used because they support signed value
   int bearing;                               // Stores full bearing
   
   Wire.beginTransmission(ADDRESS);           //starts communication with CMPS10
   Wire.write(2);                              //Sends the register we wish to start reading from
   Wire.endTransmission();

   Wire.requestFrom(ADDRESS, 4);              // Request 4 bytes from CMPS10
   while(Wire.available() < 4);               // Wait for bytes to become available
   highByte = Wire.read();           
   lowByte = Wire.read();            
   pitch = Wire.read();              
   roll = Wire.read();               
   
   int p= pitch;
   int r = roll;
   bearing = ((highByte<<8)+lowByte)/10;      // Calculate full bearing
   //fine = ((highByte<<8)+lowByte)%10;         // Calculate decimal place of bearing
 
  if(option=='B')
    return bearing;
  if(option=='P')
    return p;
  if(option=='R')
    return r;
}

Function for holding direction, Left and Right ... only turn servos in one or other direction (not much to see though)

void holdDirection(short dir, short tab[]){

  short d = compass('B');
  //Serial.println(d);
  short turnAmount=0;
  
  //for(int i=d;i>=0;i--)
    //turnAmount++;
  int index=d;  
  while(tab[index]!=dir){  
    index--;
    if(index==0)   
      index=360;
    turnAmount++;
  }
  
  if(!(turnAmount<10 || turnAmount>350) && onAuto){
    if(turnAmount<180){

      while(d>(dir-15)){   
        turnLeft(-20);
        d = compass('B');
      }
    }
    else{
      while(d<(dir+15)){
        //Serial.println(d);
        turnRight(20);
        d = compass('B');
        //Serial.println(d);
      }
    }
  }

  
  else{
    if(turnAmount<180){
      while(d>(dir-1)){   
        //Serial.println(d);
        turnLeft(-5);
        d = compass('B');
        //Serial.println(d);
      }
    }
    else{
      while(d<(dir+1)){
        if(!onAuto){goto bailout;}
        //Serial.println(d);
        turnRight(5);
        d = compass('B');
        //Serial.println(d);
      }
    }
  }

  }

Interrupt:
In void setup()

attachInterrupt(0,calcInput,CHANGE);

calcInput:

void calcInput()
{

  if(digitalRead(SW_SIGNAL_IN_PIN) == HIGH)
  { 

    ulStartPeriod = micros();
  }
  else
  {

    if(ulStartPeriod && (bNewSwSignal == false))
    {
      nSwIn = (int)(micros() - ulStartPeriod);
      ulStartPeriod = 0;
  
      if(nSwIn > 1600){
        onAuto = false;
      }
      bNewSwSignal = true;
    }
  }
}

Loop: Nothing is being controled here, it just uses the same channel as a proof of concept.

void loop() {
  if(bNewSwSignal)
 {

   pinV=nSwIn;
   bNewSwSignal = false;
 }

 if(nSwIn > 1600){
   servo1.writeMicroseconds(nSwIn);
 }
else{
  holdDirection(160,degreeTab);
}

}

One channel on the RC reciever(connected to INT0) is used as a switch and when it is "turned on" it should give me manual control of servo instantly, but instead I get control of it only after desired bearing from compass has been reached.

All those while loops in holdDirection are the problem. You need to restructure that whole function, so that each time it is called, it turns a little bit, in the required direction, rather than continuing to turn until it is lined up. Then, of course, you need to call the function often enough.

Until holdDirection() ends, new input is ignored.

I could use if statements instead, but that would be a lot of if's.

I could use if statements instead, but that would be a lot of if's.

No, you can't. It would still be a blocking function.

Think about what YOU do when trying to use a compass to head in a direction. You look at the compass, and see that you are not heading the right way. So, you turn a little and take a few steps. Then, you repeat the process until you are heading the right way.

You do not (at least I don't) say, "well, let's see. I'm 72 degrees off course, so I'll turn 72 degrees".

But, that is what your vehicle is doing. It shouldn't. It should determine that it is off course, and make a small correction (in the necessary direction), and then check again. Repeat until the off-course amount is tolerable.

I see. So I"ll do like this: check for desired direction and turn for let"s say, maximum of 10 degrees, if it is turned wrong way. So in worst case I wait for it to turn 10 deegrees, before I get control if switch is turned.

I see. So I"ll do like this: check for desired direction and turn for let"s say, maximum of 10 degrees, if it is turned wrong way. So in worst case I wait for it to turn 10 deegrees, before I get control if switch is turned.

10 degrees would be a huge course correction, wouldn't it? If the vehicle checks current course, and makes corrections often enough, I would not expect it to ever be off course more than a couple of degrees, unless it is slipping and the course is changing.

It's not exactly slipping, but when it's headed in one direction it can be moved for a degree or two by "external forces".