Hello All,
This post is quite long, but the issue I am reporting is quite easy to follow and I decided to add a lot of details to avoid confusion. I hope you'll be interested. Thanks!
==
I'm doing some basic testing to check the behavior of the Pin Change Interrupt on an Arduino Nano.
Among other things, it seems that the interrupt routine gets called only one time, no matter how many pins have changed their state "recently". I was testing this with a two pin configuration and using another microcontroller to drive the arduino port with a highly predictable timing.
However, I got stuck in an issue and decided to send this post asking for help. I've made a simplified version of the code, dealing with a single pin:
volatile unsigned short rxInterruptCount = 0;
unsigned short rxInterruptCountCopy;
unsigned int busyWaitCount = 0;
void setup() {
Serial.begin(115200);
pinMode(7, INPUT);
digitalWrite(7, LOW);
Serial.println("Init!");
delay(1000);
Serial.println("Enabling interrupts!");
cli(); // switch interrupts off while messing with their settings
PCICR = 0x04; // Enable PCINT2 interrupt
PCMSK2 = 0b10000000;
sei(); // turn interrupts back on
}
ISR(PCINT2_vect) {
rxInterruptCount++;
}
void loop() {
while (1) {
busyWaitCount = 0;
while (busyWaitCount<50000) { busyWaitCount++; }
delayMicroseconds(1); // this is the weird part of the code (the issue I am referring to)
if (rxInterruptCount > 0) break;
}
rxInterruptCountCopy = rxInterruptCount;
rxInterruptCount = 0;
Serial.print("rxInterruptCountCopy = ");
Serial.println(rxInterruptCountCopy, DEC);
}
Basically, the code sets up the interrupt on pin D7 and spends most of the time either on the "busy" loop or printing on the serial port. Every time the busyWaitCount reaches the target, the code checks the interrupt counter to see if we had an interrupt. If not, it goes back to the loop and keeps checking for an interrupt counter greater than zero. Once it finds it, it makes a copy of that value, resetting the counter, and prints the original value over the serial port.
The D7 pin is being driven by this code (running on a PIC12F1822):
while (1) {
PORTA = 0b00100000;
Delay_us(50);
PORTA = 0b00000000;
Delay_us(50);
PORTA = 0b00100000;
Delay_us(50);
PORTA = 0b00000000;
Delay_us(50);
PORTA = 0b00100000;
Delay_us(50);
PORTA = 0b00000000;
Delay_ms(5000);
}
That is, the PIC pin is changed "quickly" (6 times with a 50us delay between changes), and then the line is kept "low" for 5 seconds. This pin (called RA5 on the PIC) is directly tied by a wire to pin D7 on the arduino.
This is the output I get from the arduino (which is expected):
Init!
Enabling interrupts!
rxInterruptCountCopy = 6
rxInterruptCountCopy = 6
rxInterruptCountCopy = 6
However, if I remove the "delayMicroseconds(1)" and upload, I start getting:
Init!
Enabling interrupts!
rxInterruptCountCopy = 1
rxInterruptCountCopy = 5
rxInterruptCountCopy = 1
rxInterruptCountCopy = 5
rxInterruptCountCopy = 1
rxInterruptCountCopy = 5
Which does not make sense for me. That is: why are these 6 "pin changes" being split in two groups? I've tested changing the "delayMicroseconds(1)" to another loop "while (busyWaitCount<50000) { busyWaitCount++; }", but the results kept like:
Init!
Enabling interrupts!
rxInterruptCountCopy = 1
rxInterruptCountCopy = 5
rxInterruptCountCopy = 1
rxInterruptCountCopy = 5
I have not yet find any good reasoning on why this is behaving this way. Any ideas?
BTW: I'm writing this code to be able to handle multiple channels on an Remote Control Rx receiver, just in case you're wondering. I'm being extremely picky on this code because I do not want any planes crashing due to wrong assumptions on my part. ![]()
Thanks,
Moderator edit:
</mark> <mark>[code]</mark> <mark>
</mark> <mark>[/code]</mark> <mark>
tags added.