Arduino ESP32 如何将 BLEUUID 对象分配给字符串

Arduino ESP32 how to assign BLEUUID object into string

目前我们正在开发一个 android 应用程序,它可以在 BLE(bluetooth low energy)ESP32 设备上宣传自己。 ESP32 收集 MAC addressdevice name 和服务 UUID 并将数据发送到 MySQL server。到目前为止,ESP32 可以发送设备名称和 MAC 地址,但不知何故,我们无法发送 UUID 数据。

http://www.neilkolban.com/esp32/docs/cpp_utils/html/class_b_l_e_advertised_device.html

BLEadvertisedDevice 库中,可以找到一些有用的信息。 据我所知,getServiceUUID () returns 一个 BlEUUID(http://www.neilkolban.com/esp32/docs/cpp_utils/html/class_b_l_e_u_u_i_d.html) 对象,它有一个 toString 方法,它接受 void 参数(不是 BLEadvertisedDevice 对象,而是 BLEUUID 对象)。我的第一个问题是为什么 BLEadvertisedDevice 不接受任何参数,但 BLEUUID 将 void 作为 toString 方法的参数。我试图将对象分配给字符串,但我没有机会尝试这些,下面给出了完整的代码。

const char *dev_uuid;
dev_uuid = device.getServiceUUID().toString().c_str(); 

strcpy(dev_uuid, device.getServiceUUID().toString().c_str());

dev_uuid = device.getServiceUUID().toString();

strcpy(dev_uuid, device.getServiceUUID().toString();

错误日志如下

这是完整的代码

#include <WiFi.h>
#include <BLEDevice.h>
#include <BLEAdvertisedDevice.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

/*
  INSERT CREDENTIALS
*/

char ssid[] = "";    // your SSID
char pass[] = "";       // your SSID Password

IPAddress server_addr(192, 168, 1, xx); // IP of the MySQL *server* here
char user[] = "";              // MySQL user login username
char password[] = "";        // MySQL user login password

IPAddress local_IP(192, 168, 1, xx); // ESP 32 IP
IPAddress gateway(192, 168, 1, xx); // GATEWAY
IPAddress subnet(255, 255, 255, 0); // SUBNET
IPAddress primaryDNS(192, 168, 1, xx); // DNS

WiFiClient client;
MySQL_Connection conn((Client *)&client);

int LED_BUILTIN = 2;
int scanTime = 10;
int RSSI_data;
int device_count = 0;
char MAC_data[17];
char query[128];
const char *dev_name;
const char *uuid_string;

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
    }
};

char INSERT_DATA[] = "INSERT INTO yoklama.esp3_table (rssi, mac_address, device_name, dev_uuid) VALUES (%d,'%s','%s','%s')";

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

  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS)) {
    Serial.println("STA Failed to configure");
  }

  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("ESP Mac Address: ");
  Serial.println(WiFi.macAddress());
  Serial.print("Subnet Mask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway IP: ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("DNS: ");
  Serial.println(WiFi.dnsIP());
}

void loop()
{

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    WiFi.begin(ssid, pass);
    Serial.print("Trying to Connect");
  }

  if (conn.connect(server_addr, 3306, user, password)) {
    Serial.println("Connected to database!");
    delay(10000);
  }
  else
    Serial.println("Connection failed.");
  //conn.close();
  Serial.println("Scanning ...\n");
  BLEDevice::init("");
  BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
  BLEScanResults foundDevices = pBLEScan->start(scanTime);
  digitalWrite(LED_BUILTIN, LOW);
  device_count = foundDevices.getCount();
  Serial.printf("Cihaz sayısı: %d\n", device_count);

  Serial.print("Devices found: \n");  // THIS IS THE PART THE DATA IS SENT TO MYSQL
  for (uint32_t i = 0; i < device_count; i++)
  {
    digitalWrite(LED_BUILTIN, HIGH);
    BLEAdvertisedDevice device = foundDevices.getDevice(i);
    RSSI_data = device.getRSSI(); // CAN GET THE RSSI WITHOUT PROBLEM
    dev_name = device.getName().c_str(); // CAN GET THE DEV NAME WITHOUT PROBLEM
    strcpy( MAC_data, device.getAddress().toString().c_str()); // CAN GET THE MAC WITHOUT PROBLEM

    /* I NEED HELP TO GET THE UUID DATA SO FAR I TRIED THESE METHODS.

      dev_uuid = device.getServiceUUID().toString().c_str();
      strcpy(dev_uuid, device.getServiceUUID().toString().c_str());
      dev_uuid = device.getServiceUUID().toString();
      strcpy(dev_uuid, device.getServiceUUID().toString();

    */

    Serial.printf("MAC adres = %s --- ", MAC_data);
    Serial.printf("Device Name = '%s' --- ", dev_name);
    Serial.printf("RSSI =  %d --- ", RSSI_data);
    //Serial.printf("UUID %d\n", dev_uuid);


    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);

    sprintf(query, INSERT_DATA, RSSI_data, MAC_data, dev_name, dev_uuid);

    cur_mem->execute(query);
    delete cur_mem;
    delay(2000);

  }
  pBLEScan->clearResults();
  delay(300);

}

错误:dev_uuid = device.getServiceUUID().toString().c_str(); 它编译但来自串行监视器:

08:58:59.404 -> entry 0x400806a8
08:58:59.914 -> Connecting to 
08:59:00.421 -> .
08:59:00.421 -> WiFi connected!
08:59:00.421 -> IP address: 192.168.1.
08:59:00.421 -> ESP Mac Address: 80:7D:3A:99:82:D4
08:59:00.421 -> Subnet Mask: 255.255.255.0
08:59:00.421 -> Gateway IP: 192.168.1
08:59:00.421 -> DNS: 192.168.1
08:59:00.454 -> Connected to database!
08:59:10.459 -> Scanning...
08:59:10.459 -> 
08:59:21.115 -> Cihaz sayısı: 8
08:59:21.115 -> Devices found: 
08:59:21.115 -> Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
08:59:21.115 -> Core 1 register dump:
08:59:21.115 -> PC      : 0x4000c2e0  PS      : 0x00060430  A0      : 0x800d3160  A1      : 0x3ffcecb0  
08:59:21.115 -> A2      : 0x3ffced30  A3      : 0x00000000  A4      : 0x00000013  A5      : 0x3ffced30  
08:59:21.150 -> A6      : 0x00000000  A7      : 0x00000001  A8      : 0x00000000  A9      : 0x3ffcec70  
08:59:21.150 -> A10     : 0x00000000  A11     : 0x3ffced7c  A12     : 0x3ffced7c  A13     : 0x00000000  
08:59:21.150 -> A14     : 0x00000000  A15     : 0x5b0a0a20  SAR     : 0x0000001e  EXCCAUSE: 0x0000001c  
08:59:21.150 -> EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  
08:59:21.185 -> 
08:59:21.185 -> Backtrace: 0x4000c2e0:0x3ffcecb0 0x400d315d:0x3ffcecc0 0x400d188a:0x3ffcece0 0x400d821d:0x3ffcee00 0x4008e095:0x3ffcee20
08:59:21.185 -> 
08:59:21.185 -> Rebooting...
08:59:21.185 -> ets Jun  8 2016 00:22:57

错误:strcpy(dev_uuid,device.getServiceUUID().toString().c_str());

C:\Users\...\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/newlib/string.h:30:15: note:   initializing argument 1 of 'char* strcpy(char*, const char*)'

 char  *_EXFUN(strcpy,(char *__restrict, const char *__restrict));

错误:strcpy(dev_uuid,device.getServiceUUID().toString());

invalid conversion from 'const char*' to 'char*' [-fpermissive]

错误:dev_uuid = device.getServiceUUID().toString());

cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' to 'const char*' in assignment

在您的代码中:

const char *dev_uuid;
dev_uuid = device.getServiceUUID().toString().c_str(); 

strcpy(dev_uuid, device.getServiceUUID().toString().c_str());

dev_uuid = device.getServiceUUID().toString();

strcpy(dev_uuid, device.getServiceUUID().toString();

您的 strcpy() 尝试不可能像您写的那样奏效。您有一个未初始化的指针 (dev_uuid),并且您正在将数据复制到……它恰好指向的任何地方。这就是你感到恐慌的原因。

使用 String 对象,而不是 C 字符串:

String dev_uuid;

dev_uuid = device.getServiceUUID().toString();

Arduino String class 和 C 字符串之间存在巨大差异。一般来说,如果你看到 toString() 方法,它就是 Arduino 字符串 class。阅读文档应该清楚一个方法 returns a String;如果是,您应该将 return 值分配给 String.

C 字符串更难处理。您正在直接操纵指向内存和内存内容的指针。它们的空终止字符总是比它们的长度指示的多一个字节。在复制到它们之前,您需要确保为它们分配了内存。

对此进行更新。

dev_uuid = device.getServiceUUID().toString().c_str();这是正确的方法。

如果广告商设备未设置 UUID,则获取扫描结果时 dev_uuid returns 为 null,无法打印或任何内容。您可以将 .haveServiceUUID 方法添加到 return 布尔值,如果它为真,那么您可以毫无问题地获取 UUID。否则,如果广告商设备未设置 UUID,则会出现导致 Guru Meditation Error: Core

的问题

if (advertisedDevice.haveServiceUUID ()) dev_uuid = advertisedDevice.toString().c_str();