I have a fairly complex autonomous robot program that is getting into trouble when executing controlled turns. I constructed a very small program to test just the turns, and this works fine. When I port the turn algorithm into the main program, however, it behaves erratically, and I suspect the culprit is a TIMER5 interrupt ISR that is in the main program but not in the test program.
To troubleshoot, I added the TIMER5 ISR code to the test program, and I want to be able to enable and disable the ISR using keyboard commands, to see if I can cause the anomalous behavior with the ISR enabled, and prevent it by disabling the ISR.
From reading about TIMER interrupts, it appears that setting TIMSKx (TIMSK5 in my case) to 0 will disable the ISR, and setting bit 0 to 1 (using TIMSKx |= OCIExA) will enable it. I have a 'CheckForUserInput()' routine which allows me to input commands from the keyboard, so I added a 'T' command, as follows:
switch (incomingByte)
{
case 0x54: //ASCII 'T'
case 0x74: //ASCII 's'
Serial.println(F("Toggle TIMER5 Enable/Disable"));
if (TIMSK5 == 0)
{
Serial.println(F("Enable TIMER5"));
TIMSK5 |= OCIE5A;
mySerial.printf("TIMSK5 = %x\n", TIMSK5);
}
else
{
Serial.println(F("Disable TIMER5"));
TIMSK5 = 0;
mySerial.printf("TIMSK5 = %x\n", TIMSK5);
}
break;
I have an LED set up to blink each time the ISR fires, and I can see that I can stop the ISR from firing reliably with the first 'T' input, but I can't reliably restart it with the second 'T' command, even though I can tell from the printouts that the proper piece of code executed, like in the following output
Opening port
Port open
Checking for MPU6050 IMU at I2C Addr 0x69
MPU6050 connection successful
Initializing DMP...
Enabling DMP...
DMP ready! Waiting for MPU6050 drift rate to settle...
MPU6050 Ready at 0.52 Sec
End of test - Stopping!
I received: 63
ENTERING COMMAND MODE:
0 = 180 deg CCW Turn
1 = 180 deg CW Turn
A = Back to Auto Mode
S = Stop
F = Forward
R = Reverse
Faster
8
Left 4 5 6 Right
2
Slower
Got D
Got A
Got 74
Toggle TIMER5 Enable/Disable
Disable TIMER5
TIMSK5 = 0
Got D
Got A
Got 74
TEnabling DMP...
DMP ready! Waiting for MPU6050 drift rate to settle...
MPU6050 Ready at 0.52 Sec
End of test - Stopping!
I received: 63
ENTERING COMMAND MODE:
0 = 180 deg CCW Turn
1 = 180 deg CW Turn
A = Back to Auto Mode
S = Stop
F = Forward
R = Reverse
Faster
8
Left 4 5 6 Right
2
Slower
Got D
Got A
Got 74
Toggle TIMER5 Enable/Disable
Disable TIMER5
TIMSK5 = 0
Got D
Got A
Got 74
Toggle TIMER5 Enable/Disable
Enable TIMER5
TIMSK5 = 1
Got D
Got A
I'm sure I'm doing something wrong in the way I am attempting to re-enable the TIMER5 ISR, but I really can't see it. Anyone have a clue?
TIA,
Frank
1 Answer 1
You wrote:
TIMSK5 |= OCIE5A;
You mean
TIMSK5 |= _BV(OCIE5A);
or, equivalently,
TIMSK5 |= 1 << OCIE5A;
-
Hmm, not sure I understand. The 'TIMSK5 |= OCIE5A' line comes directly from my currently-working code as the last line of the TIMER5 interrupt setup block, so I'm pretty sure it's correct. The 'TIMSK5 = 0' line will reliably stop the ISR from firing, so I'm pretty sure it is correct as well.starship15– starship152021年06月02日 00:20:22 +00:00Commented Jun 2, 2021 at 0:20
-
Do you mean that the 'TIMSK5 |= _BV(OCIE5A);' should be used to re-enable the ISR, instead of 'TIMSK5 |= OCIE5A'starship15– starship152021年06月02日 00:21:43 +00:00Commented Jun 2, 2021 at 0:21
-
-
Aw, rats! I mis-read the TIMERx setup code. What I thought was 'TMSK5 |= OCIE5A;' was actually 'TMSK5 |= (1 << OCIE5A);' which (I think) is the equivalent of 'TIMSK5 |= _BV(OCIE5A);' Sorry for wasting your time :(starship15– starship152021年06月02日 01:53:40 +00:00Commented Jun 2, 2021 at 1:53