This is an old revision of the document!
Project 5: Digilent Pro MX7 and Interrupts
Process Speed Controls Using Interrupts
The purpose of this project is to explore detecting events using interrupts or by using preemption that implements a nested interrupt management scheme. Concepts concerning processor context are introduced, as well as interrupt prioritization. The functional requirement for Project 5 are essentially identical to those for Project 3. The biggest difference is that time and button action events are detected by interrupts rather than by software that polls processor flags and logic levels applied to input pins.
Prerequisites
- A working knowledge of MPLAB® IDE
- Understanding of finite state machines
- I/O pin control
- Use of a logic analyzer or an oscilloscope
Inventory
- 1 Stepper Motor (5V – 12V, 25 Ω, unipolar or bi-polar)
- 1 Logic analyzer or oscilloscope (Digilent Analog Discovery or Analog Discovery 2 recommended)
Interrupt Programming
“In computing, preemption is the act of temporarily interrupting a task being carried out by a computer system, without requiring its cooperation, and with the intention of resuming the task at a later time. It is normally carried out by a privileged task or part of the system that has the power to interrupt, and later resume, other tasks in the system.”¹ In software, a task is a basic unit of programming that has a constrained, defined purpose. For example, reading the state of the input pins to determine if buttons are pressed or not can be considered a task. Multitasking implies that more than one task is running at the same time. Single-core processors appear to be multitasking by time-sharing the processor resources. No time sharing is required in Projects 3 and 4, where each task in the program ran to its completion before the next task could begin. When multitasking with a single-core processor, some tasks are suspended so that higher priority tasks can be serviced (executed).
Pmod STEP Parts Layout
PIC32 Interrupts
Step 2: Building the Circuit
Having chosen our resistor and capacitor values, we can begin putting the circuit together. We will be using the same circuit we first used in Debouncing via Software. In that project, the button bounce caused “noise” that occasionally made the LED glow dimly instead of blinking. The addition of our RC filter remedies this problem. Refer to Fig. 1, which illustrates the individual steps for modifying the circuit.
Modifying the Circuit
- Connect the wire from pin 7 to the button's right side.
- NOTE: The right side of the button corresponds here to the “top” of the button. This means that the two button legs that are always electrically connected are oriented vertically so that they span the valley between the columns.
- Connect the 5V source to the button's current-limiting resistor.
- Connect a 10 µF capacitor and 10 kΩ resistor to the right side of the button.
- Connect the ground pin (GND) to the right side of the capacitor and resistor
Testing the Debouncing Properties of the RC Filter
Now that we have built the circuit, you can test the debouncing properties of the RC filter. Plug the USB cable into your chipKIT board and program it with code from Debouncing via Software:
const int btnPin = 7; // Number of the pushbutton pin
const int ledPin = 8; // Number of the LED pin
int currentLedState; // Current and previous states of output LED pin
int previousLedState;
int currentBtnState; // Current and previous states of input Button pin
int previousBtnState;
unsigned int count; // Rising edge count of LED state
unsigned int lastDebounceTime;
unsigned int debounceDelay; // Delay time
void setup() {
pinMode(btnPin, INPUT);
pinMode(ledPin, OUTPUT);
currentLedState = LOW;
previousLedState = LOW;
currentBtnState = LOW;
previousBtnState = LOW;
count = 0;
lastDebounceTime = 0;
debounceDelay = 50;
Serial.begin(9600);
}
void loop() {
currentBtnState = digitalRead(btnPin);
if (currentBtnState != previousBtnState) {
lastDebounceTime = millis();
// every time the button state changes, get the time of that change
}
if ((millis() - lastDebounceTime) > debounceDelay) {
/*
*if the difference between the last time the button changed is greater
*than the delay period, it is safe to say
*the button is in the final steady state, so set the LED state to
*button state.
*/
currentLedState = currentBtnState;
}
// ********************* start functional code **************************************
// verification code, and a button press counter
if ((previousLedState == LOW) && (currentLedState == HIGH)) {
//count rising edges
count++;
Serial.println(count);
}
// ********************* end functional code **************************************
// set current states to previous states
digitalWrite(ledPin, currentLedState);
previousBtnState = currentBtnState;
previousLedState = currentLedState;
}
Once your board is programmed, the external LED should start blinking.
Remove the capacitor from the circuit; it's okay to do this while the circuit has power. Since nothing can flow across this gap, more current will be diverted through the resistor that was in parallel with the capacitor. Similarly, once the capacitor has been charged in the circuit, it does not allow any current to flow through it. At this point, the capacitor will essentially act as a gap. After you have removed the capacitor, pressing the button enough times should eventually cause button bounce and make the LED glow dimly (instead of blinking). Tapping or flicking the button effectively accomplishes the same thing. Once you are able to reproduce the bounce consistently, try sticking the capacitor back in the circuit. Be sure you put the capacitor back exactly as shown in Fig. 1 (with the white stripe terminal on the capacitor connected to ground). If you reconnect the capacitor with the wrong polarity, it may damage your component. With the capacitor in place, you should not be able to get the button to bounce even if you flick it or tap it.
To see what the circuit is actually doing, check out Fig. 2. It shows what the button signal looks like with the capacitor absent from the RC filter. In Fig. 3, the same signal is shown magnified 100x, so that you can clearly see the noise caused by a button bounce. Finally, Fig. 4 depicts what the button signal looks like after the capacitor is replaced within the circuit.
As you can see, the capacitor dramatically limits the rate at which voltage can change, especially compared to the size of the bounce noise. Considering the effect the RC filter has, our capacitor is definitely too big for handling button noise alone. This is not surprising. The RC values we chose were specifically meant to reduce bounce noise and any other noise caused by a tap/flick. The circuit was designed this way because it is easier to see the effects of the filter. A smaller capacitor could be used to target the bounce noise specifically.





