You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用WiFi的情况下实现多ESP32从节点向主节点传输小数据?

Lightweight BLE Solution for ESP32 Master-Slave Small Data Transfer

Great call switching to BLE for this setup—since you're already scanning BLE beacons, reusing the BLE stack will cut down on flash usage dramatically compared to dragging in the entire WiFi library. Below are minimal, tested code examples for both your master and slave ESP32 nodes, optimized for 10-byte payloads and short-range (3m) communication.

Master Node (BLE Server - Receives Data)

This code sets up the ESP32 as a BLE server with a writable characteristic that your slave nodes can send their 10-byte payloads to.

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

// Custom UUIDs (generate your own unique ones for your project)
#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();

      if (value.length() == 10) { // Ensure we get exactly 10 bytes
        Serial.print("Received payload: ");
        for (int i = 0; i < value.length(); i++) {
          Serial.print(value[i]);
        }
        Serial.println();
      } else {
        Serial.println("Received invalid payload length");
      }
    }
};

void setup() {
  Serial.begin(115200);

  // Initialize BLE
  BLEDevice::init("ESP32-Master");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pService->start();
  // Start advertising so slaves can find us
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // Helps with iPhone connection compatibility
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("Master BLE server started, waiting for slaves...");
}

void loop() {
  // No active logic needed here—callbacks handle incoming data
  delay(100);
}

Slave Node (BLE Client - Sends 10-Byte Data)

This code connects to the master's BLE service and sends a 10-byte payload. It’s designed to run alongside your existing BLE beacon scanning code without excessive memory overhead.

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEClient.h>
#include <BLEAddress.h>
#include <BLEAdvertisedDevice.h>

// Match the UUIDs from the master node
#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

BLEClient* pClient = nullptr;
bool connected = false;

// Callback to handle discovered BLE devices
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      if (advertisedDevice.getName() == "ESP32-Master" && !connected) {
        Serial.print("Found master: ");
        Serial.println(advertisedDevice.getAddress().toString().c_str());
        advertisedDevice.getScan()->stop();
        pClient = BLEDevice::createClient();
        if (pClient->connect(advertisedDevice)) {
          connected = true;
          Serial.println("Connected to master");
        } else {
          Serial.println("Failed to connect");
        }
      }
    }
};

void setup() {
  Serial.begin(115200);
  BLEDevice::init("ESP32-Slave");
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); // Active scan finds devices faster (uses slightly more power)
  pBLEScan->start(5); // Initial scan for 5 seconds
}

void loop() {
  if (connected) {
    // Access the master's service and characteristic
    BLERemoteService* pRemoteService = pClient->getService(SERVICE_UUID);
    if (pRemoteService) {
      BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(CHARACTERISTIC_UUID);
      if (pRemoteCharacteristic) {
        // Replace this with your actual 10-byte data
        uint8_t payload[10] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A};
        pRemoteCharacteristic->writeValue(payload, 10);
        Serial.println("Sent 10-byte payload");
      }
    }
    delay(1000); // Adjust send interval to match your needs
  } else {
    // Re-scan for master if disconnected
    BLEScan* pBLEScan = BLEDevice::getScan();
    pBLEScan->start(2, false); // Passive scan to save power
    delay(1000);
  }

  // Insert your existing BLE beacon scanning/RSSI code here
  // Example placeholder:
  // scanBeaconsAndLogRSSI();
}

Key Optimization & Stability Tips

  • Unique UUIDs: Generate custom UUIDs for your project (use any online UUID generator tool) to avoid conflicts with other BLE devices.
  • Memory Efficiency: This setup uses only core BLE libraries, which are far lighter than WiFi + HTTP. You’ll see a significant drop in flash usage compared to your previous implementation.
  • Power Savings: For battery-powered slaves, switch to passive scanning (setActiveScan(false)) and increase send intervals to minimize power draw.
  • Payload Validation: The master checks for exactly 10 bytes—adjust this logic if your data length varies, but keep it tight for efficiency.
  • Combining with Beacon Scanning: Since both the data transfer and beacon scanning use the same BLE stack, they’ll run side-by-side without extra memory overhead.

内容的提问来源于stack exchange,提问作者Mr. Blond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:51:53