I want to intercept interrupts on pin A8 & A9 (arduino mega).
The following code give me :
Interrupt on pin A8 : 10 or 11 as result
Interrupt on pin A9 : 1 or 11 as result
I don't understand why results oscillate between 2 numbers ???
Thanks for helping.
Thierry
volatile byte pcint1_pins = B00000000; // variable for current port K bits
volatile byte pcint1_pinsLast = B00000000; // variable for previous port K bits
volatile boolean print_flag1 = false; // PCINT2 flag
void setup()
{
Serial.begin(115200);
Serial.println("test interrupt change pin A8-A9");
InitialiseIO();
InitialiseInterrupt();
}
void InitialiseIO(){
pinMode(A8, INPUT); // Pin A8 is input to which a switch is connected
digitalWrite(A8, HIGH); // Configure internal pull-up resistor
pinMode(A9, INPUT); // Pin A9 is input to which a switch is connected
digitalWrite(A9, HIGH); // Configure internal pull-up resistor
}
void InitialiseInterrupt(){
cli(); // switch interrupts off while messing with their settings
PCICR |= (1 << PCIE2); // enable PCINT2
PCMSK2 |= (1 << PCINT16); // mask for bit0 of port K (A8)
PCMSK2 |= (1 << PCINT17); // mask for bit1 of port K (A9)
sei(); // turn interrupts back on
}
ISR(PCINT2_vect) { // Interrupt service routine
byte saveSREG = SREG;
noInterrupts();
pcint1_pins ^= ((PINK & B00000011) ^ (pcint1_pinsLast & B00000011));
pcint1_pinsLast = pcint1_pins;
print_flag1 = true;
SREG = saveSREG;
interrupts();
}
void loop()
{
if (print_flag1 == true) { // interrupt detection
noInterrupts();
byte pci1 = pcint1_pins;
interrupts();
Serial.print("PCINT1 = ");
Serial.println(pci1, BIN);
print_flag1 = false;
}
}
I know but for testing I use just one interrupt at a time.
Sensor connect to A8 & nothing to A9 : results give 10 or 11
Sensor connect to A9 & nothing to A8 : results gives 01 or 11
The result gives status of both pins regardless of which triggered the interrupt.
The numbers you show are Binary. Binary 1 is Decimal 1 and Binary 10 is Decimal 2.
Nothing connected, if that is unterminated pin then what it reads "floats". The circuit needs to be connected or pulled up or down depending on the circuit or you need to change the IRQ to only read the connected pin.
Ok, I will try to connect 2 sensors for testing.
Also I configure internal pull-up resistor, so it doesn't care if something connec ou not. I'm wrong ?
Here is what i use to configure internal pull-up resistor, is it correct ?
void InitialiseIO(){
pinMode(A8, INPUT); // Pin A8 is input to which a switch is connected
digitalWrite(A8, HIGH); // Configure internal pull-up resistor
pinMode(A9, INPUT); // Pin A9 is input to which a switch is connected
digitalWrite(A9, HIGH); // Configure internal pull-up resistor
}
I was used to doing it that way before changing from IDE 0022 to IDE 1.03
As of Arduino 1.0.1, it is possible to enable the internal pullup resistors with the mode INPUT_PULLUP.
Additionally, the INPUT mode explicitly disables the internal pullups.
I think that the digitalWrite to HIGH enables those pullups.
With pullup enabled the pin will read LOW on a button press to ground, opposite to 5V to button to INPUT pin.
If it is a human finger on a button making the change then just the touch will take a very long time in Arduino cycles.
But the button itself will present another problem if it is not hardware debounced. The contact is not clean. Arduino with good code will see maybe dozens or more press and release events (the bounce) for every touch. The interrupt will catch them all, for all the good it will do.
If it is not a human and/or button but rather something very fast or fleeting, interrupt is justified. But for humans and sloppy inputs the first question I think is "why?".
Code execution will be more interesting then, just because of the speed/timing.
I am pretty sure that Pin Change interrupts all use 1 IRQ. And this example is pretty good.
If you save the previous read then you can XOR that with the current read in the IRQ, result will be the change.
Note that it will be possible for both pins to change in the same short time it takes to read, but unlikely.