基于XBee与attachInterrupt()实现Nano按键无线控制Uno LED(模拟继电器)
Hey there! Let's break down how to get your XBee-enabled Arduino setup working with the interrupt-triggered LED/relay. You've already got a solid foundation—Uno reading a light sensor and sending data, Nano with a button, and XBee Series 1 modules paired up. Let's tackle the interrupt part and get that LED triggering wirelessly!
Before diving into code, make sure your two XBee Series 1 modules are properly paired for bidirectional communication. Use a tool like X-CTU to set these key parameters on both modules:
- Set the same
ID(PAN ID, e.g.,0x1234) so they're on the same network - Match the
BD(baud rate) value—9600is a safe default (corresponds to0x3) - Assign unique
MY(source address) values: e.g., Uno's XBee =0x0001, Nano's XBee =0x0002 - Set
DL(destination address) on each module to the other'sMYvalue: Nano's XBee points to0x0001, Uno's XBee points to0x0002
Critical Note: XBees run on 3.3V only—never connect them to 5V pins, or you'll fry the modules! Use the 3.3V output on your Arduinos and share a common ground between all devices.
We'll use attachInterrupt() to detect button presses without blocking the main loop. The Nano has two external interrupt pins: D2 (INT0) and D3 (INT1)—we'll use D2 for this example.
We'll add software debouncing to avoid false triggers from button bounce, and keep interrupt logic minimal (best practice: avoid heavy operations like serial writes directly in interrupts).
#include <SoftwareSerial.h> // XBee connected to Nano's D5 (RX) and D4 (TX) SoftwareSerial xbeeSerial(5, 4); const int buttonPin = 2; // Interrupt pin INT0 unsigned long lastInterruptTime = 0; const unsigned long debounceDelay = 200; // 200ms debounce to avoid false presses bool shouldTriggerLED = false; // Flag to trigger XBee send in main loop void setup() { Serial.begin(9600); xbeeSerial.begin(9600); pinMode(buttonPin, INPUT_PULLUP); // Use internal pullup resistor for button // Attach interrupt: trigger on falling edge (button press = high → low) attachInterrupt(digitalPinToInterrupt(buttonPin), buttonPressed, FALLING); } void loop() { // Handle XBee send in main loop (safer than doing it in interrupt) if (shouldTriggerLED) { xbeeSerial.println("TRIG_LED"); // Send unique command to Uno shouldTriggerLED = false; Serial.println("Button pressed: sent trigger signal to Uno"); } } // Interrupt service routine (ISR) void buttonPressed() { unsigned long currentTime = millis(); // Ignore if interrupt fires too soon after last trigger (debounce) if (currentTime - lastInterruptTime > debounceDelay) { shouldTriggerLED = true; lastInterruptTime = currentTime; } }
The Uno needs to handle two tasks simultaneously: read the light sensor and send data to your PC, plus listen for the XBee trigger command to toggle the LED (simulated relay). We'll use hardware serial for the PC and software serial for the XBee to avoid conflicts.
#include <SoftwareSerial.h> // XBee connected to Uno's D2 (RX) and D3 (TX) SoftwareSerial xbeeSerial(2, 3); const int lightSensorPin = A0; const int ledPin = 9; bool ledState = LOW; void setup() { Serial.begin(9600); // Connect to PC xbeeSerial.begin(9600); // Connect to XBee pinMode(ledPin, OUTPUT); digitalWrite(ledPin, ledState); } void loop() { // Read and send light intensity to PC int lightValue = analogRead(lightSensorPin); Serial.print("Light Intensity: "); Serial.println(lightValue); delay(1000); // Send data once per second // Listen for XBee commands while (xbeeSerial.available() > 0) { String incomingCommand = xbeeSerial.readStringUntil('\n'); incomingCommand.trim(); // Remove extra whitespace/newlines if (incomingCommand == "TRIG_LED") { ledState = !ledState; digitalWrite(ledPin, ledState); Serial.print("LED toggled to: "); Serial.println(ledState ? "ON" : "OFF"); } } }
- Avoid Serial Writes in Interrupts: Interrupts should be as fast as possible. Using a flag (
shouldTriggerLED) to move the serial send to the main loop prevents conflicts with Arduino's serial interrupt system. - Hardware Debounce (Optional): For extra reliability, add a 100nF capacitor across your button pins (between button and ground) to reduce electrical bounce.
- Test Communication First: Before adding the interrupt, verify that the XBees can send simple messages between Uno and Nano (e.g., send a test string from Nano and have Uno print it to the Serial Monitor).
内容的提问来源于stack exchange,提问作者galaxy_twirl

