There seems to be interference between interrupts I am using and I2C. I have found a way round this but I do not understand how it works.
I have a homemade robot that was working but I have not used for about 2 years.
It does not work now.
It has an Raspberry Pi deciding where it wants to go and an Arduino Uno actually doing the operation of motors etc.
That Arduino is attached to:
- two motor controllers by I2C. The problem does not seem to affect these.
- another Arduino running homemade wheel encoders by I2C using Master reader/Slave writer mode
- 3 channel Radio Control allowing the thing to be steered when it gets lost. These are connected to 3
pins that have interrupts using the PinChangeInt library.(the problems also occur using the EnableInterrupt library)
The raspberry Pi is currently not connected
As I said all this used to work fine but I am about to integrate another sensor (Lidar) so I tried to get it
to work as it was before proceeding.
The RC and the motor controllers work happily but as soon as I try to read the wheel encoder Arduino
the program freezes.
The RC works fine by itself with the motor controllers and the wheel encoders work by themselves while the RC is not being used, so I can only think that the interrupt routines and the I2C are in some way interfering with each other. I only write to the motor controllers.
The function that reads the encoder is a straight copy of the example in the library
void getTicks( long *rightTicks, long *leftTicks)
{
byte right1, right2,right3,right4, left1, left2, left3, left4;
Wire.requestFrom(2, 8); // request 6 bytes from slave device #2
while (Wire.available() < 8); // Wait for bytes to become available
right1 = Wire.read();
right2 = Wire.read();
right3 = Wire.read();
right4 = Wire.read();
left1 = Wire.read();
left2 = Wire.read();
left3 = Wire.read();
left4 = Wire.read();
*rightTicks = (((long)right4) << 24) + (((long)right3) << 16) + (((long)right2) << 8) + ((long)right1);
*leftTicks = (((long)left4) << 24) + (((long)left3) << 16) + (((long)left2) << 8) + ((long)left1);
}
It occurrrred to me that if it somehow missed seeing 8 bytes it could wait for ever so I changed the code to have a time out as follows:
void getTicks( long *rightTicks, long *leftTicks)
{
byte right1, right2,right3,right4, left1, left2, left3, left4;
long dTime = 0;
long strt = micros();
while(dTime < 5000)
{
Wire.requestFrom(ENCODERS, 8,true); // request 8 bytes from slave device #2
if (Wire.available() == 8) break; // Wait for bytes to become available
dTime = micros()-strt;
}
Serial.println(dTime);
if( dTime <5000)
{
right1 = Wire.read();
right2 = Wire.read();
right3 = Wire.read();
right4 = Wire.read();
left1 = Wire.read();
left2 = Wire.read();
left3 = Wire.read();
left4 = Wire.read();
*rightTicks = (((long)right4) << 24) + (((long)right3) << 16) + (((long)right2) << 8) + ((long)right1);
*leftTicks = (((long)left4) << 24) + (((long)left3) << 16) + (((long)left2) << 8) + ((long)left1);
}
else
{
// remove any bytes
while(Wire.available())
{
Wire.read();
}
}
// just set to anything at the moment
*rightTicks = 123;
*leftTicks = 123;
}
}
This works BUT the line " Serial.println(dTime); " put in to see what was happening always prints zero. In other words there is never a time out and it never gets to the line " dTime = micros()-strt; ".
So putting in this bit of code seems to have stopped the supposed interference.
Can anybody explain what is happening?
Thanks
Alan