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.
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);
}
}
}
}
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.
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.