BLE在ESP32和iPhone之间传输的字符串

huangapple go评论102阅读模式
英文:

BLE sent String between ESP32 and Iphone

问题

我需要从iPhone通过BLE将文本发送到ESP32。
手机应用程序连接到ESP32并成功保持连接。但是当我按发送按钮时,控制台显示发送成功。但是在ESP32的串行监视器上没有显示任何内容。
使用BLE扫描器应用程序一切正常。

这是ESP32的代码:

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

#define SERVICE_UUID        "8c2a81f7-f8b8-4b31-89b4-6b5d98a822db"
#define CHARACTERISTIC_UUID "e8bd8c82-2506-4fae-b5f2-9bbbf4ab5b0e"

BLECharacteristic *characteristic;

class MyServerCallbacks : public BLEServerCallbacks {
    void onConnect(BLEServer *pServer) {
        // Connection established
    }

    void onDisconnect(BLEServer *pServer) {
        // Connection disconnected
    }
};

class MyCallbacks : public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
        std::string value = pCharacteristic->getValue();
        if (value.length() > 0) {
            Serial.println("Received Data:");
            Serial.println(value.c_str());
        }
    }
};

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

    BLEDevice::init("ESP32");
    BLEServer *pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());

    BLEService *pService = pServer->createService(SERVICE_UUID);
    characteristic = pService->createCharacteristic(
        CHARACTERISTIC_UUID,
        BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
    );
    characteristic->setCallbacks(new MyCallbacks());
    pService->start();

    BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(SERVICE_UUID);
    pAdvertising->setScanResponse(false);
    pAdvertising->setMinPreferred(0x06);
    pAdvertising->setMinPreferred(0x12);
    BLEDevice::startAdvertising();
}

void loop() {
    // Additional background actions can be performed here
}

这是应用程序的部分代码:

import SwiftUI
import CoreBluetooth

class BluetoothManager: NSObject, CBCentralManagerDelegate, ObservableObject {
    let esp32ServiceUUID = CBUUID(string: "8c2a81f7-f8b8-4b31-89b4-6b5d98a822db")
    let esp32CharacteristicUUID = CBUUID(string: "e8bd8c82-2506-4fae-b5f2-9bbbf4ab5b0e")
    let centralManager: CBCentralManager
    var peripheral: CBPeripheral?
    var characteristic: CBCharacteristic?
    
    @Published var isConnected = false
    
    override init() {
        centralManager = CBCentralManager(delegate: nil, queue: nil)
        super.init()
        centralManager.delegate = self
    }
    
    func startScanning() {
        centralManager.scanForPeripherals(withServices: [esp32ServiceUUID])
        print("Started scanning for peripherals")
    }
    
    func sendNumberToESP32(text: String) {
        guard let peripheral = peripheral, let characteristic = characteristic else { return }
        
        guard let data = text.data(using: .utf8) else { return }
        peripheral.writeValue(data, for: characteristic, type: .withoutResponse)
        print("Sent data to ESP32: \(text)")
    }
    
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            startScanning()
        } else {
            // Bluetooth is not powered on or available
            print("Bluetooth not powered on or unavailable")
        }
    }
    
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
                        advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if peripheral.name == "ESP32" {
            centralManager.stopScan()
            self.peripheral = peripheral
            self.peripheral?.delegate = self
            centralManager.connect(peripheral)
            print("Discovered ESP32 peripheral")
        }
    }
    
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        isConnected = true
        print("Connected to peripheral")
        peripheral.discoverServices([esp32ServiceUUID])
    }
    
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        isConnected = false
        print("Disconnected from peripheral")
        centralManager.scanForPeripherals(withServices: [esp32ServiceUUID])
        print("Started scanning for peripherals again")
    }
}

extension BluetoothManager: CBPeripheralDelegate {
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        if let service = peripheral.services?.first(where: { $0.uuid == esp32ServiceUUID }) {
            peripheral.discoverCharacteristics([esp32CharacteristicUUID], for: service)
        }
    }
    
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        if let characteristic = service.characteristics?.first(where: { $0.uuid == esp32CharacteristicUUID }) {
            self.characteristic = characteristic
        }
    }
}

struct ContentView: View {
    @State private var text: String = ""
    @StateObject private var bluetoothManager = BluetoothManager()
    
    var body: some View {
        VStack {
            Text(bluetoothManager.isConnected ? "Connected" : "Disconnected")
                .padding()
            
            TextField("Enter number",text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            
            Button(action: {
                bluetoothManager.sendNumberToESP32(text: text)
            }) {
                Text("Send")
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
        .onAppear {
            bluetoothManager.startScanning()
        }
        .onChange(of: bluetoothManager.isConnected) { isConnected in
            print("Connection status changed: \(isConnected)")
        }
    }
}

感谢您的帮助。

英文:

I need to send text from an Iphone via BLE to an ESP32.
The phone App connects to the ESP32 and stays connected successfully. But when I press send the console says the sending was successful. But on der Serial Monitor of the ESP32 appeares nothing.
With an BLE scanner App all works fine.

Here is the code for the ESP32:

#include &lt;BLEDevice.h&gt;
#include &lt;BLEServer.h&gt;
#include &lt;BLEUtils.h&gt;
#include &lt;BLE2902.h&gt;

#define SERVICE_UUID        &quot;8c2a81f7-f8b8-4b31-89b4-6b5d98a822db&quot;
#define CHARACTERISTIC_UUID &quot;e8bd8c82-2506-4fae-b5f2-9bbbf4ab5b0e&quot;

BLECharacteristic *characteristic;

class MyServerCallbacks : public BLEServerCallbacks {
    void onConnect(BLEServer *pServer) {
        // Verbindung hergestellt
    }

    void onDisconnect(BLEServer *pServer) {
        // Verbindung getrennt
    }
};

class MyCallbacks : public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
        std::string value = pCharacteristic-&gt;getValue();
        if (value.length() &gt; 0) {
            Serial.println(&quot;Empfangene Daten:&quot;);
            Serial.println(value.c_str());
        }
    }
};

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

    BLEDevice::init(&quot;ESP32&quot;);
    BLEServer *pServer = BLEDevice::createServer();
    pServer-&gt;setCallbacks(new MyServerCallbacks());

    BLEService *pService = pServer-&gt;createService(SERVICE_UUID);
    characteristic = pService-&gt;createCharacteristic(
        CHARACTERISTIC_UUID,
        BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
    );
    characteristic-&gt;setCallbacks(new MyCallbacks());
    pService-&gt;start();

    BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
    pAdvertising-&gt;addServiceUUID(SERVICE_UUID);
    pAdvertising-&gt;setScanResponse(false);
    pAdvertising-&gt;setMinPreferred(0x06);
    pAdvertising-&gt;setMinPreferred(0x12);
    BLEDevice::startAdvertising();
}

void loop() {
    // Hier k&#246;nnen weitere Aktionen im Hintergrund durchgef&#252;hrt werden
}

And here from the App:

import SwiftUI
import CoreBluetooth

class BluetoothManager: NSObject, CBCentralManagerDelegate, ObservableObject {
    let esp32ServiceUUID = CBUUID(string: &quot;8c2a81f7-f8b8-4b31-89b4-6b5d98a822db&quot;)
    let esp32CharacteristicUUID = CBUUID(string: &quot;e8bd8c82-2506-4fae-b5f2-9bbbf4ab5b0e&quot;)
    let centralManager: CBCentralManager
    var peripheral: CBPeripheral?
    var characteristic: CBCharacteristic?
    
    @Published var isConnected = false
    
    override init() {
        centralManager = CBCentralManager(delegate: nil, queue: nil)
        super.init()
        centralManager.delegate = self
    }
    
    func startScanning() {
        centralManager.scanForPeripherals(withServices: [esp32ServiceUUID])
        print(&quot;Started scanning for peripherals&quot;)
    }
    
    func sendNumberToESP32(text: String) {
        guard let peripheral = peripheral, let characteristic = characteristic else { return }
        
        guard let data = text.data(using: .utf8) else { return }
        peripheral.writeValue(data, for: characteristic, type: .withoutResponse)
        print(&quot;Sent data to ESP32: \(text)&quot;)
    }
    
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            startScanning()
        } else {
            // Bluetooth ist nicht aktiviert oder nicht verf&#252;gbar
            print(&quot;Bluetooth not powered on or unavailable&quot;)
        }
    }
    
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
                        advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if peripheral.name == &quot;ESP32&quot; {
            centralManager.stopScan()
            self.peripheral = peripheral
            self.peripheral?.delegate = self
            centralManager.connect(peripheral)
            print(&quot;Discovered ESP32 peripheral&quot;)
        }
    }
    
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        isConnected = true
        print(&quot;Connected to peripheral&quot;)
        peripheral.discoverServices([esp32ServiceUUID])
    }
    
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        isConnected = false
        print(&quot;Disconnected from peripheral&quot;)
        centralManager.scanForPeripherals(withServices: [esp32ServiceUUID])
        print(&quot;Started scanning for peripherals again&quot;)
    }
}

extension BluetoothManager: CBPeripheralDelegate {
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        if let service = peripheral.services?.first(where: { $0.uuid == esp32ServiceUUID }) {
            peripheral.discoverCharacteristics([esp32CharacteristicUUID], for: service)
        }
    }
    
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        if let characteristic = service.characteristics?.first(where: { $0.uuid == esp32CharacteristicUUID }) {
            self.characteristic = characteristic
        }
    }
}

struct ContentView: View {
    @State private var text: String = &quot;&quot;
    @StateObject private var bluetoothManager = BluetoothManager()
    
    var body: some View {
        VStack {
            Text(bluetoothManager.isConnected ? &quot;Verbunden&quot; : &quot;Getrennt&quot;)
                .padding()
            
            TextField(&quot;Zahl eingeben&quot;,text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            
            Button(action: {
                bluetoothManager.sendNumberToESP32(text: text)
            }) {
                Text(&quot;Senden&quot;)
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
        .onAppear {
            bluetoothManager.startScanning()
        }
        .onChange(of: bluetoothManager.isConnected) { isConnected in
            print(&quot;Verbindungsstatus ge&#228;ndert: \(isConnected)&quot;)
        }
    }
}


Thanks for helping

I´ve asked ChatGPT but it has no idea, and I searched in the internet

答案1

得分: 2

你没有在这里检查错误,所以很难确定发生了什么。通常你应该实现 peripheral(_:didWriteValueFor:error:) 来查看值是否实际写入。我认为问题出在这里:

peripheral.writeValue(data, for: characteristic, type: .withoutResponse)

你没有配置特征以允许无响应写入(PROPERTY_WRITE_NR)。一般情况下,你不希望这样做。你应该在这里使用 .withResponse

英文:

You're not checking for errors here, so it's hard to be certain what's happening. Typically you should implement peripheral(_:didWriteValueFor:error:) to see that the value was actually written. I expect the problem is here:

    peripheral.writeValue(data, for: characteristic, type: .withoutResponse)

You didn't configure the characteristic to allow writing without response (PROPERTY_WRITE_NR). You generally don't want that in any case. You should be using .withResponse here.

huangapple
  • 本文由 发表于 2023年7月6日 22:40:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76629994.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定