Using Interrupts

Interrupts for the HelvePic32

Interrupts offer the possibility to execute code triggered by a state change of a pin. At the Arduino Uno, there are two interrupt pins (2 and 3) and in the code you specify which routine must be called if the pin changes its state.

This is the same with the ChipKit family and the HelvePic32 has 5 interrupt pins. These are the following pins:

Interrupt Pin Comment
int_0 RIGHT - 2
fixed
int_1
RIGHT - 4
PPS default
int_2
LEFT - 6
PPS default
int_3
RIGHT - 3
PPS default
int_4
RIGHT - 1 / LEFT - 1
PPS default


Where int_0 is fixed on the pin, the other interrupts can be moved to several other pins through PPS (=Peripheral Pin Select). This offers the possibility to shift an interrupt to a different pin if the default pin is used or blocked by something.

 

In this example we will use the default interrupts and come back to PPS in a later stage.

 

The following picture shows the interrupts and their alternative pins.

The Interrput Pinmap

What is it good for?

We can use the interrupts to pick up every move of the encoder. For that we hook up the encoder pin A to an interrupt pin (e.g. RIGHT-2).

 

Is the encoder turned, the pin changes its state and the interrupt routine is called, interrupting the execution of any code in the loop() routine. As the HelvePic32 has no built in pull-up or pull-down resistors, we need to pull-up the input pins. This should look like the following picture:

The code is straight forward. The variables used in the interrupt routines have to be declared as volatile so that the compiler makes them available to the interrupt routines

#include 
#include 

volatile int encoderPin1 = nP[RIGHT][4];        // pin connected to INT-1 by default
volatile int encoderPin2 = nP[RIGHT][5];
volatile int number = 0; 

int oldnumber = number;

void setup(){
        Serial.begin(9600);
        pinMode(encoderPin1, INPUT);
        pinMode(encoderPin2, INPUT);
        attachInterrupt(1, isr_A, FALLING);
        Serial.println("Starting Encoder");
}

void loop(){
        int val;
        for (int i=0; i<256; i++){
                delay(30);
                if (oldnumber != number){
                        Serial.print(number);
                        oldnumber = number;
                        Serial.println();
                }
        }
}

void isr_A(){
        delay(3);                                                               // Debounce time
        // Trade off bounce vs missed counts
        int LSB = digitalRead(encoderPin1);
        int MSB = digitalRead(encoderPin2);

        if(LSB == LOW){                                                 // A still LOW ?
                if(MSB == HIGH) number++;
                if(MSB == LOW)  number--;
        }
}

Using the Switch

In a similar way, we connect the Switch to the pin RIGHT-3 which is by default mapped to interrupt 3. It is a nice exercise to write the code for reading the switch by yourself. In the final code, you will see the solution I came up with.


The switch pin needs no pull-up resistor as the breakout already has a resistor connected. However, the breakout makes it a pull-down to ground, so the attachInterrupt routine must trigger on a RISING signal.