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

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

BLE sent String between ESP32 and Iphone

问题

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

这是ESP32的代码:

  1. #include <BLEDevice.h>
  2. #include <BLEServer.h>
  3. #include <BLEUtils.h>
  4. #include <BLE2902.h>
  5. #define SERVICE_UUID "8c2a81f7-f8b8-4b31-89b4-6b5d98a822db"
  6. #define CHARACTERISTIC_UUID "e8bd8c82-2506-4fae-b5f2-9bbbf4ab5b0e"
  7. BLECharacteristic *characteristic;
  8. class MyServerCallbacks : public BLEServerCallbacks {
  9. void onConnect(BLEServer *pServer) {
  10. // Connection established
  11. }
  12. void onDisconnect(BLEServer *pServer) {
  13. // Connection disconnected
  14. }
  15. };
  16. class MyCallbacks : public BLECharacteristicCallbacks {
  17. void onWrite(BLECharacteristic *pCharacteristic) {
  18. std::string value = pCharacteristic->getValue();
  19. if (value.length() > 0) {
  20. Serial.println("Received Data:");
  21. Serial.println(value.c_str());
  22. }
  23. }
  24. };
  25. void setup() {
  26. Serial.begin(115200);
  27. BLEDevice::init("ESP32");
  28. BLEServer *pServer = BLEDevice::createServer();
  29. pServer->setCallbacks(new MyServerCallbacks());
  30. BLEService *pService = pServer->createService(SERVICE_UUID);
  31. characteristic = pService->createCharacteristic(
  32. CHARACTERISTIC_UUID,
  33. BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
  34. );
  35. characteristic->setCallbacks(new MyCallbacks());
  36. pService->start();
  37. BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  38. pAdvertising->addServiceUUID(SERVICE_UUID);
  39. pAdvertising->setScanResponse(false);
  40. pAdvertising->setMinPreferred(0x06);
  41. pAdvertising->setMinPreferred(0x12);
  42. BLEDevice::startAdvertising();
  43. }
  44. void loop() {
  45. // Additional background actions can be performed here
  46. }

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

  1. import SwiftUI
  2. import CoreBluetooth
  3. class BluetoothManager: NSObject, CBCentralManagerDelegate, ObservableObject {
  4. let esp32ServiceUUID = CBUUID(string: "8c2a81f7-f8b8-4b31-89b4-6b5d98a822db")
  5. let esp32CharacteristicUUID = CBUUID(string: "e8bd8c82-2506-4fae-b5f2-9bbbf4ab5b0e")
  6. let centralManager: CBCentralManager
  7. var peripheral: CBPeripheral?
  8. var characteristic: CBCharacteristic?
  9. @Published var isConnected = false
  10. override init() {
  11. centralManager = CBCentralManager(delegate: nil, queue: nil)
  12. super.init()
  13. centralManager.delegate = self
  14. }
  15. func startScanning() {
  16. centralManager.scanForPeripherals(withServices: [esp32ServiceUUID])
  17. print("Started scanning for peripherals")
  18. }
  19. func sendNumberToESP32(text: String) {
  20. guard let peripheral = peripheral, let characteristic = characteristic else { return }
  21. guard let data = text.data(using: .utf8) else { return }
  22. peripheral.writeValue(data, for: characteristic, type: .withoutResponse)
  23. print("Sent data to ESP32: \(text)")
  24. }
  25. func centralManagerDidUpdateState(_ central: CBCentralManager) {
  26. if central.state == .poweredOn {
  27. startScanning()
  28. } else {
  29. // Bluetooth is not powered on or available
  30. print("Bluetooth not powered on or unavailable")
  31. }
  32. }
  33. func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
  34. advertisementData: [String : Any], rssi RSSI: NSNumber) {
  35. if peripheral.name == "ESP32" {
  36. centralManager.stopScan()
  37. self.peripheral = peripheral
  38. self.peripheral?.delegate = self
  39. centralManager.connect(peripheral)
  40. print("Discovered ESP32 peripheral")
  41. }
  42. }
  43. func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
  44. isConnected = true
  45. print("Connected to peripheral")
  46. peripheral.discoverServices([esp32ServiceUUID])
  47. }
  48. func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
  49. isConnected = false
  50. print("Disconnected from peripheral")
  51. centralManager.scanForPeripherals(withServices: [esp32ServiceUUID])
  52. print("Started scanning for peripherals again")
  53. }
  54. }
  55. extension BluetoothManager: CBPeripheralDelegate {
  56. func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
  57. if let service = peripheral.services?.first(where: { $0.uuid == esp32ServiceUUID }) {
  58. peripheral.discoverCharacteristics([esp32CharacteristicUUID], for: service)
  59. }
  60. }
  61. func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
  62. if let characteristic = service.characteristics?.first(where: { $0.uuid == esp32CharacteristicUUID }) {
  63. self.characteristic = characteristic
  64. }
  65. }
  66. }
  67. struct ContentView: View {
  68. @State private var text: String = ""
  69. @StateObject private var bluetoothManager = BluetoothManager()
  70. var body: some View {
  71. VStack {
  72. Text(bluetoothManager.isConnected ? "Connected" : "Disconnected")
  73. .padding()
  74. TextField("Enter number",text: $text)
  75. .textFieldStyle(RoundedBorderTextFieldStyle())
  76. .padding()
  77. Button(action: {
  78. bluetoothManager.sendNumberToESP32(text: text)
  79. }) {
  80. Text("Send")
  81. .padding()
  82. .background(Color.blue)
  83. .foregroundColor(.white)
  84. .cornerRadius(10)
  85. }
  86. }
  87. .onAppear {
  88. bluetoothManager.startScanning()
  89. }
  90. .onChange(of: bluetoothManager.isConnected) { isConnected in
  91. print("Connection status changed: \(isConnected)")
  92. }
  93. }
  94. }

感谢您的帮助。

英文:

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:

  1. #include &lt;BLEDevice.h&gt;
  2. #include &lt;BLEServer.h&gt;
  3. #include &lt;BLEUtils.h&gt;
  4. #include &lt;BLE2902.h&gt;
  5. #define SERVICE_UUID &quot;8c2a81f7-f8b8-4b31-89b4-6b5d98a822db&quot;
  6. #define CHARACTERISTIC_UUID &quot;e8bd8c82-2506-4fae-b5f2-9bbbf4ab5b0e&quot;
  7. BLECharacteristic *characteristic;
  8. class MyServerCallbacks : public BLEServerCallbacks {
  9. void onConnect(BLEServer *pServer) {
  10. // Verbindung hergestellt
  11. }
  12. void onDisconnect(BLEServer *pServer) {
  13. // Verbindung getrennt
  14. }
  15. };
  16. class MyCallbacks : public BLECharacteristicCallbacks {
  17. void onWrite(BLECharacteristic *pCharacteristic) {
  18. std::string value = pCharacteristic-&gt;getValue();
  19. if (value.length() &gt; 0) {
  20. Serial.println(&quot;Empfangene Daten:&quot;);
  21. Serial.println(value.c_str());
  22. }
  23. }
  24. };
  25. void setup() {
  26. Serial.begin(115200);
  27. BLEDevice::init(&quot;ESP32&quot;);
  28. BLEServer *pServer = BLEDevice::createServer();
  29. pServer-&gt;setCallbacks(new MyServerCallbacks());
  30. BLEService *pService = pServer-&gt;createService(SERVICE_UUID);
  31. characteristic = pService-&gt;createCharacteristic(
  32. CHARACTERISTIC_UUID,
  33. BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
  34. );
  35. characteristic-&gt;setCallbacks(new MyCallbacks());
  36. pService-&gt;start();
  37. BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  38. pAdvertising-&gt;addServiceUUID(SERVICE_UUID);
  39. pAdvertising-&gt;setScanResponse(false);
  40. pAdvertising-&gt;setMinPreferred(0x06);
  41. pAdvertising-&gt;setMinPreferred(0x12);
  42. BLEDevice::startAdvertising();
  43. }
  44. void loop() {
  45. // Hier k&#246;nnen weitere Aktionen im Hintergrund durchgef&#252;hrt werden
  46. }

And here from the App:

  1. import SwiftUI
  2. import CoreBluetooth
  3. class BluetoothManager: NSObject, CBCentralManagerDelegate, ObservableObject {
  4. let esp32ServiceUUID = CBUUID(string: &quot;8c2a81f7-f8b8-4b31-89b4-6b5d98a822db&quot;)
  5. let esp32CharacteristicUUID = CBUUID(string: &quot;e8bd8c82-2506-4fae-b5f2-9bbbf4ab5b0e&quot;)
  6. let centralManager: CBCentralManager
  7. var peripheral: CBPeripheral?
  8. var characteristic: CBCharacteristic?
  9. @Published var isConnected = false
  10. override init() {
  11. centralManager = CBCentralManager(delegate: nil, queue: nil)
  12. super.init()
  13. centralManager.delegate = self
  14. }
  15. func startScanning() {
  16. centralManager.scanForPeripherals(withServices: [esp32ServiceUUID])
  17. print(&quot;Started scanning for peripherals&quot;)
  18. }
  19. func sendNumberToESP32(text: String) {
  20. guard let peripheral = peripheral, let characteristic = characteristic else { return }
  21. guard let data = text.data(using: .utf8) else { return }
  22. peripheral.writeValue(data, for: characteristic, type: .withoutResponse)
  23. print(&quot;Sent data to ESP32: \(text)&quot;)
  24. }
  25. func centralManagerDidUpdateState(_ central: CBCentralManager) {
  26. if central.state == .poweredOn {
  27. startScanning()
  28. } else {
  29. // Bluetooth ist nicht aktiviert oder nicht verf&#252;gbar
  30. print(&quot;Bluetooth not powered on or unavailable&quot;)
  31. }
  32. }
  33. func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
  34. advertisementData: [String : Any], rssi RSSI: NSNumber) {
  35. if peripheral.name == &quot;ESP32&quot; {
  36. centralManager.stopScan()
  37. self.peripheral = peripheral
  38. self.peripheral?.delegate = self
  39. centralManager.connect(peripheral)
  40. print(&quot;Discovered ESP32 peripheral&quot;)
  41. }
  42. }
  43. func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
  44. isConnected = true
  45. print(&quot;Connected to peripheral&quot;)
  46. peripheral.discoverServices([esp32ServiceUUID])
  47. }
  48. func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
  49. isConnected = false
  50. print(&quot;Disconnected from peripheral&quot;)
  51. centralManager.scanForPeripherals(withServices: [esp32ServiceUUID])
  52. print(&quot;Started scanning for peripherals again&quot;)
  53. }
  54. }
  55. extension BluetoothManager: CBPeripheralDelegate {
  56. func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
  57. if let service = peripheral.services?.first(where: { $0.uuid == esp32ServiceUUID }) {
  58. peripheral.discoverCharacteristics([esp32CharacteristicUUID], for: service)
  59. }
  60. }
  61. func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
  62. if let characteristic = service.characteristics?.first(where: { $0.uuid == esp32CharacteristicUUID }) {
  63. self.characteristic = characteristic
  64. }
  65. }
  66. }
  67. struct ContentView: View {
  68. @State private var text: String = &quot;&quot;
  69. @StateObject private var bluetoothManager = BluetoothManager()
  70. var body: some View {
  71. VStack {
  72. Text(bluetoothManager.isConnected ? &quot;Verbunden&quot; : &quot;Getrennt&quot;)
  73. .padding()
  74. TextField(&quot;Zahl eingeben&quot;,text: $text)
  75. .textFieldStyle(RoundedBorderTextFieldStyle())
  76. .padding()
  77. Button(action: {
  78. bluetoothManager.sendNumberToESP32(text: text)
  79. }) {
  80. Text(&quot;Senden&quot;)
  81. .padding()
  82. .background(Color.blue)
  83. .foregroundColor(.white)
  84. .cornerRadius(10)
  85. }
  86. }
  87. .onAppear {
  88. bluetoothManager.startScanning()
  89. }
  90. .onChange(of: bluetoothManager.isConnected) { isConnected in
  91. print(&quot;Verbindungsstatus ge&#228;ndert: \(isConnected)&quot;)
  92. }
  93. }
  94. }

Thanks for helping

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

答案1

得分: 2

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

  1. 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:

  1. 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:

确定