如何将ESP32实体按键操作关联至React Native应用内的按钮功能?
Got it, let's walk through how to make your ESP32 button trigger the action in your React Native app. We'll split this into two clear parts: setting up the ESP32 to send BLE signals on button press, and configuring your React Native app to listen for those signals and fire the button action.
We'll use the ArduinoBLE library for this—super straightforward to set up. Here's the code with comments explaining each step:
#include <ArduinoBLE.h> // Define your button pin (using INPUT_PULLUP so we don't need external resistors) const int buttonPin = 2; bool lastButtonState = HIGH; bool currentButtonState; // Custom BLE service and characteristic UUIDs (make sure these match your React Native code!) BLEService buttonService("19B10000-E8F2-537E-4F6C-D104768A1214"); BLECharacteristic buttonCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLENotify, 1); void setup() { pinMode(buttonPin, INPUT_PULLUP); // Initialize BLE if (!BLE.begin()) { while (1); // Halt if BLE fails to start } // Set device name (your app will scan for this) BLE.setLocalName("ESP32-Button"); BLE.setAdvertisedService(buttonService); buttonService.addCharacteristic(buttonCharacteristic); BLE.addService(buttonService); // Initialize characteristic value buttonCharacteristic.writeValue(0); BLE.advertise(); } void loop() { BLEDevice central = BLE.central(); if (central) { // Check button state while connected to the app currentButtonState = digitalRead(buttonPin); // Detect button press (edge trigger) if (currentButtonState != lastButtonState) { if (currentButtonState == LOW) { // Button pressed (since we're using INPUT_PULLUP) // Send a "trigger" signal to the app buttonCharacteristic.writeValue(1); delay(100); // Debounce to prevent duplicate triggers buttonCharacteristic.writeValue(0); // Reset signal to avoid repeated actions } lastButtonState = currentButtonState; } } }
Key Notes for ESP32:
- The
INPUT_PULLUPmeans the pin reads HIGH by default, and LOW when the button is pressed (no external resistors needed). - We use a short delay to debounce the button—this stops accidental multiple triggers from a single press.
- The BLE UUIDs can be any valid UUIDs, just make sure they match exactly in your React Native code.
We'll use the react-native-ble-plx library (a popular, reliable option for BLE in React Native). Here's a complete component example:
import React, { useEffect, useState } from 'react'; import { Button, View, Text, StyleSheet } from 'react-native'; import { BleManager } from 'react-native-ble-plx'; const manager = new BleManager(); const App = () => { const [isConnected, setIsConnected] = useState(false); const [connectedDevice, setConnectedDevice] = useState(null); // Your existing app button action—this is what the ESP32 will trigger const triggerAppButtonAction = () => { console.log("ESP32 button pressed! Firing app action..."); // Replace this with your actual button logic: API calls, state updates, etc. }; // Scan and connect to the ESP32 device useEffect(() => { const scanForDevice = () => { manager.startDeviceScan(null, null, (error, device) => { if (error) { console.error("Scan error:", error); return; } // Match the device name we set in the ESP32 code if (device.name === "ESP32-Button") { manager.stopDeviceScan(); // Connect to the device device.connect() .then(device => { setConnectedDevice(device); setIsConnected(true); return device.discoverAllServicesAndCharacteristics(); }) .then(device => { // Monitor the BLE characteristic for changes device.monitorCharacteristicForService( "19B10000-E8F2-537E-4F6C-D104768A1214", // Service UUID "19B10001-E8F2-537E-4F6C-D104768A1214", // Characteristic UUID (error, characteristic) => { if (error) { console.error("Monitoring error:", error); return; } // Parse the value sent from ESP32 (we sent a 1-byte value) const triggerValue = characteristic.value?.[0]; if (triggerValue === 1) { triggerAppButtonAction(); } } ); }) .catch(error => { console.error("Connection failed:", error); setIsConnected(false); }); } }); }; scanForDevice(); // Clean up on component unmount return () => { if (connectedDevice) { connectedDevice.cancelConnection(); } manager.destroy(); }; }, []); return ( <View style={styles.container}> <Text style={styles.statusText}> {isConnected ? "Connected to ESP32" : "Scanning for ESP32..."} </Text> {/* Your original app button—both this and the ESP32 will trigger the same action */} <Button title="App Action Button" onPress={triggerAppButtonAction} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, statusText: { fontSize: 18, marginBottom: 20, }, }); export default App;
Key Notes for React Native:
- Permissions: Don't forget to add Bluetooth permissions to your project:
- For iOS: Add
NSBluetoothAlwaysUsageDescriptionandNSBluetoothPeripheralUsageDescriptionto yourInfo.plist. - For Android: Add
BLUETOOTH,BLUETOOTH_ADMIN, andACCESS_FINE_LOCATION(orACCESS_COARSE_LOCATIONfor older versions) to yourAndroidManifest.xml.
- For iOS: Add
- UUID Matching: Double-check that the service and characteristic UUIDs match exactly what you used in the ESP32 code (case-sensitive!).
- Connection Handling: The cleanup function ensures we disconnect from the device when the component unmounts, preventing memory leaks.
内容的提问来源于stack exchange,提问作者Linab
相关产品推荐
相关产品推荐

