Overview
The interrupt node handles hardware interrupts for time-critical GPIO events.
Unlike polling-based gpio-in, interrupts respond immediately to signal changes, making them ideal for
encoders, pulse counting, and precise timing applications.
Interrupt vs Polling
Interrupt (This Node)
- • Instant response (<10 microseconds)
- • No missed events at high frequencies
- • Zero CPU overhead when idle
- • Precise timing information
- • Best for: encoders, counters, flow meters
Polling (gpio-in)
- • Response depends on poll rate
- • Can miss fast events
- • Uses CPU cycles continuously
- • Simpler for slow signals
- • Best for: buttons, switches, door sensors
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
| pin | number | Yes | - | GPIO pin number (BCM numbering) |
| edge | string | No | "rising" | "rising", "falling", or "both" |
| resistor | string | No | "none" | "pullup", "pulldown", or "none" |
| glitchFilter | number | No | 0 | Ignore edges closer than N microseconds |
| timestamp | boolean | No | true | Include microsecond timestamp |
Inputs
Optional commands to control interrupt behavior.
"reset" Reset counter to 0 "pause" Pause interrupt handling "resume" Resume interrupt handling Outputs
{
"payload": 1,
"pin": 17,
"edge": "rising",
"timestamp": 1640000000123456,
"count": 42,
"frequency": 125.5,
"_interrupt": {
"delta": 7968
}
} Common Use Cases
Rotary Encoder
Track rotation direction and position
Use 2 interrupt pins for A/B channels
Edge: both (for quadrature decoding)
Glitch filter: 50µs
Flow Meter
Count pulses for liquid/gas flow
Count pulses per second
Edge: rising (pulse counting)
Multiply by calibration factor
RPM Counter
Measure motor or wheel speed
Calculate time between pulses
RPM = 60 / (delta_µs × pulses_per_rev)
Edge: rising
Anemometer
Wind speed measurement
Pulse frequency = wind speed
Edge: rising
Use frequency output directly
Example: Rotary Encoder with Direction
Track position and direction of a quadrature rotary encoder.
// Function node for quadrature decoding
// Connect Channel A to GPIO 17 (interrupt node)
// Connect Channel B to GPIO 27 (read in function)
var pinB = 27; // Hardcode for this example
var lastA = context.get('lastA') || 0;
var position = context.get('position') || 0;
// Read current state of both channels
var stateA = msg.payload;
var stateB = global.get('gpio_' + pinB) || 0;
// Determine direction based on B when A changes
if (msg.edge === 'rising') {
if (stateB === 0) {
position++; // Clockwise
} else {
position--; // Counter-clockwise
}
} else if (msg.edge === 'falling') {
if (stateB === 1) {
position++; // Clockwise
} else {
position--; // Counter-clockwise
}
}
context.set('position', position);
msg.payload = {
position: position,
direction: (position > context.get('lastPos')) ? 'CW' : 'CCW'
};
context.set('lastPos', position);
return msg; Example: Flow Meter
Calculate water flow rate from Hall effect sensor pulses.
// Function node: Calculate flow rate
// YF-S201 flow sensor: 7.5 pulses per liter
const PULSES_PER_LITER = 7.5;
// Use the frequency from interrupt node
var frequency = msg.frequency || 0;
// Calculate flow rate
var litersPerMinute = (frequency / PULSES_PER_LITER) * 60;
msg.payload = {
flowRate: litersPerMinute.toFixed(2),
unit: "L/min",
totalPulses: msg.count,
totalLiters: (msg.count / PULSES_PER_LITER).toFixed(2)
};
return msg; Troubleshooting
Spurious interrupts / double counting
- Increase glitchFilter value (try 50-100µs)
- Add hardware debouncing capacitor (0.1µF)
- Enable pull-up or pull-down resistor
- Use only "rising" or "falling" edge, not "both"
Missing pulses at high speed
- Disable glitch filter or reduce filter time
- Check signal quality with oscilloscope
- Reduce downstream processing complexity
- Use batch mode to reduce message overhead
Inconsistent timing measurements
- Use hardware timestamp from node, not Node.js Date
- Disable CPU throttling:
cpufreq-set -g performance - Avoid WiFi interrupts (use Ethernet if possible)
- For critical timing, consider dedicated microcontroller