首页 > 解决方案 > ESP32 使用 BLE 和 WiFi API 调用给出错误代码 -1

问题描述

我有一个程序试图连接到蓝牙设备,然后通过服务器发送确认(服务器是私有的,所以我只使用了一些假名)。设置时的第一个 ACK​​,通过 204 http 返回代码,这很好,然后它搜索一个设备,无论找到与否,它都会给出一个错误代码 -1,然后它也会给出 204。这是我拥有的代码:(我有另一个项目,所以这只是剥离版本尝试的东西)。这也很大程度上基于 esp32 上的蓝牙客户端连接示例。

代码:

    #include "BLEDevice.h"
    #include "esp_bt.h"
    #include "WiFi.h"
    #include <HTTPClient.h>
    #include <ArduinoJson.h>
    #include <Arduino_JSON.h>
    
    //WiFi variables
    //HTTPClient http;
    
    const char* ssid = "SSID";
    const char* password = "Password";
    
    char* serverName = "ServerName";
    char* serverQR = "ServerName1";
    String serverPath;
    String httpRequestData;
    
    bool wifiOn = 0;
    bool wifiAck = 0;
    int Connection = 0;
    int httpResponseCode;
    
    String Data = "";
    String externalID = "";
    bool answer = "false";
    String payload = "{}";
    
    
    BLEScan* pBLEScan;
    
    // The remote service we wish to connect to.
    static BLEUUID serviceUUID("0000fff0-0000-1000-8000-00805f9b34fb");
    // The characteristic of the remote service we are interested in.
    static BLEUUID    charUUID("0000fff1-0000-1000-8000-00805f9b34fb");
    
    static boolean doConnect = false; //should esp connect to ble device
    static boolean connected = false; // is esp connected to a ble device
    static boolean doScan = false; //should esp scan for ble devices
    static BLERemoteCharacteristic* pRemoteCharacteristic; //init remote characterestic
    static BLEAdvertisedDevice* myDevice;  //init device found
    
    static void notifyCallback( //beginning of functions, parameters follow
      BLERemoteCharacteristic* pBLERemoteCharacteristic, //this is the device characterisitc value
      uint8_t* pData, //data it received
      size_t length,//length of data received
      bool isNotify) {
      Serial.print("Notify callback for characteristic ");
      Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
      Serial.print(" of data length ");
      Serial.println(length);
      Serial.print("data: ");
      Serial.println((char*)pData);
      esp_bt_controller_deinit();
      esp_bt_controller_disable();
    }
    
    class MyClientCallback : public BLEClientCallbacks {
        void onConnect(BLEClient* pclient) {//when connecting
          connected = true;
          Serial.println("onConnect");
        }
    
        void onDisconnect(BLEClient* pclient) {//when disconnecting
          connected = false;
          Serial.println("onDisconnect");
        }
    };
    
    bool connectToServer() {//connect to ble device
      Serial.print("Forming a connection to ");
      Serial.println(myDevice->getAddress().toString().c_str());
    
      BLEClient*  pClient  = BLEDevice::createClient();//create esp as a client
      Serial.println(" - Created client");
    
      pClient->setClientCallbacks(new MyClientCallback());//set the function of client callbacks
    
      // Connect to the remove BLE server.
      pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be 
      recognized type of peer device address (public or private)
      Serial.println(" - Connected to server");
    
      // Obtain a reference to the service we are after in the remote BLE server.
      BLERemoteService* pRemoteService = pClient->getService(serviceUUID);//can we connect to ble device
      if (pRemoteService == nullptr) {
        Serial.print("Failed to find our service UUID: ");
        Serial.println(serviceUUID.toString().c_str());
        pClient->disconnect();
        return false;
      }
      Serial.println(" - Found our service");
    
    
      // Obtain a reference to the characteristic in the service of the remote BLE server.
      pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);//does the ble device have the 
      characteristic function we want?
      if (pRemoteCharacteristic == nullptr) {
        Serial.print("Failed to find our characteristic UUID: ");
        Serial.println(charUUID.toString().c_str());
        pClient->disconnect();
        return false;
      }
      Serial.println(" - Found our characteristic");
    
      // Read the value of the characteristic.
      if (pRemoteCharacteristic->canRead()) {
        std::string value = pRemoteCharacteristic->readValue();
        Serial.print("The characteristic value was: ");
        Serial.println(value.c_str());
      }
    
      if (pRemoteCharacteristic->canNotify()) //if ble server transmits data do a callback
        pRemoteCharacteristic->registerForNotify(notifyCallback);
    
      connected = true;
      return true;
    }
    /**
       Scan for BLE servers and find the first one that advertises the service we are looking for.
    */
    class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {//When a scan is activated
        /**
            Called for each advertising BLE server.
        */
        void onResult(BLEAdvertisedDevice advertisedDevice) {//when a ble device is found
          Serial.print("BLE Advertised Device found: ");
          Serial.println(advertisedDevice.toString().c_str());
    
          // We have found a device, let us now see if it contains the service we are looking for.
          if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
    
            BLEDevice::getScan()->stop();
            myDevice = new BLEAdvertisedDevice(advertisedDevice);//ble server connected
            doConnect = true;//has to connect
            doScan = true;//has to scan
    
          } // Found our server
        } // onResult
    }; // MyAdvertisedDeviceCallbacks
    
    
    void setup() {
      Serial.begin(115200);
      Serial.println("Starting Arduino BLE Client application...");
      BLEDevice::init("");
    
      // Retrieve a Scanner and set the callback we want to use to be informed when we
      // have detected a new device.  Specify that we want active scanning and start the
      // scan to run for 5 seconds.
      pBLEScan = BLEDevice::getScan();
      pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
      pBLEScan->setActiveScan(true);
      //WiFi setup
      Serial.println();
      Serial.printf("Connecting to %s\n", ssid);
      WiFi.begin(ssid, password);
    
      while (WiFi.status() != WL_CONNECTED)
      {
        Serial.println("Connecting to WiFi...");
        delay(1000);
      }//end while
    
      Serial.print("Connected, IP address: ");
      Serial.println(WiFi.localIP());
      HTTPClient http;
    
      serverPath = serverName;
      if (WiFi.status() == WL_CONNECTED) {
        // Your Domain name with URL path or IP address with path
        http.begin(serverPath.c_str());
    
        // Data to send with HTTP POST
        JSONVar json_test;
        json_test["id"] = WiFi.macAddress();
        httpRequestData = JSON.stringify(json_test);
    
        // If you need an HTTP request with a content type: application/json, use the following:
        http.addHeader("Content-Type", "application/json");
        httpResponseCode = http.POST(httpRequestData);
        payload = " {}";
    
        if (httpResponseCode > 0) {
          Serial.print("HTTP Response code: ");
          Serial.println(httpResponseCode);
          Serial.println("This is the response code");
        }
        else {
          Serial.print("Error code: ");
          Serial.println(httpResponseCode);
        }
        // Free resources
        http.end();
        WiFi.disconnect(true);
        delay(1); // disable WIFI altogether
        WiFi.mode(WIFI_OFF);
        delay(1);
      } else
      {
        Serial.println("WiFi disconnected");
      }
    
    } // End of setup.
    
    // This is the Arduino main loop function.
    void loop() {
      esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
      esp_bt_controller_init(&bt_cfg);
      esp_bt_controller_enable(ESP_BT_MODE_BLE);
    
      if (!connected)
      {
        Serial.println("Initialising");
        pBLEScan = BLEDevice::getScan();
        pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
        pBLEScan->setActiveScan(true);
        Serial.println("Scan starting");
        pBLEScan->start(30, false);
        Serial.println("Scan ended");
      }
      // If the flag "doConnect" is true then we have scanned for and found the desired
      // BLE Server with which we wish to connect.  Now we connect to it.  Once we are
      // connected we set the connected flag to be true.
      if (doConnect == true) {//if ble server was found connect to it
        if (connectToServer()) {
          Serial.println("We are now connected to the BLE Server.");
        } else {
          Serial.println("We have failed to connect to the server; there is nothin more we will do.");
        }
        doConnect = false;
    
      }
      esp_bt_controller_deinit();
      esp_bt_controller_disable();
      
      //WiFi setup
      Serial.println();
      Serial.printf("Connecting to %s\n", ssid);
      WiFi.begin(ssid, password);
      //WiFi.config(staticIP, gateway, subnet);
    
      while (WiFi.status() != WL_CONNECTED)
      {
        Serial.println("Connecting to WiFi...");
        delay(1000);
      }//end while
    
      Serial.print("Connected, IP address: ");
      Serial.println(WiFi.localIP());
      HTTPClient http;
    
      serverPath = serverName;
      if (WiFi.status() == WL_CONNECTED) {
        // Your Domain name with URL path or IP address with path
        http.begin(serverPath.c_str());
    
        // Data to send with HTTP POST
        JSONVar json_test;
        json_test["id"] = WiFi.macAddress();
        httpRequestData = JSON.stringify(json_test);
    
        // If you need an HTTP request with a content type: application/json, use the following:
        http.addHeader("Content-Type", "application/json");
        httpResponseCode = http.POST(httpRequestData);
    
        if (httpResponseCode > 0) {
          Serial.print("HTTP Response code: ");
          Serial.println(httpResponseCode);
          Serial.println("This is the loop");
        }
        else {
          Serial.print("Error code: ");
          Serial.println(httpResponseCode);
          Serial.println("This is the loop");
        }
        // Free resources
        http.end();
        WiFi.disconnect(true);
        delay(1); // disable WIFI altogether
        WiFi.mode(WIFI_OFF);
        delay(1);
      } else
      {
        Serial.println("WiFi disconnected");
      }
    
      delay(1000); // Delay a second between loops.
    } // End of loop

代码的输出是:

Starting Arduino BLE Client application...

Connecting to SSID Connecting to WiFi... Connected, IP address: IP HTTP Response code: 204 This is the response code IS this done? Initialising Scan starting BLE Advertised Device found: Name: , Address: address, manufacturer data:random stuff Scan ended Forming a connection to addresss
- Created client onConnect
- Connected to server
- Found our service
- Found our characteristic We are now connected to the BLE Server.

Connecting to SSID Connecting to WiFi... Connected, IP address: IP Error code: -1 This is the loop

Connecting to SSID Connecting to WiFi... Connected, IP address: IP HTTP Response code: 204 This is the loop

Connecting to SSID Connecting to WiFi... Connected, IP address: IP HTTP Response code: 204 This is the loop

我的问题基本上是,如果-1 是,有谁知道 erro0 rcode 是什么?在我的主要项目中,即使我禁用了控制器,我也无法在扫描 ble 设备后发送获取请求。

标签: c++arduinobluetooth-lowenergyesp32

解决方案


要回答有关错误代码 -1 的问题:这意味着根据HTTPClient 存储库中的此示例连接不成功。

您的日志显示您能够连接到您的服务器,然后再连接到您的 BLE 外围设备。但似乎您永远不会断开与外围设备的连接并继续阻止其他 wifi 连接。看看这个以获得关于一起使用 BLE 和 WiFi 的更多想法。


推荐阅读