Arduino ESP32 как назначить объект BLEUUID в строку - PullRequest
0 голосов
/ 08 июля 2019

В настоящее время мы разрабатываем приложение для Android, которое может рекламировать себя с устройств с BLE(bluetooth low energy) до ESP32.ESP32 собирает MAC address, device 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 () возвращает объект 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

Ответы [ 2 ]

1 голос
/ 08 июля 2019

В вашем коде:

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 и строками C. Обычно, если вы видите метод toString(), это класс Arduino String. Чтение документации должно прояснить, что метод возвращает String; если это так, вы должны присвоить возвращаемое значение String.

С строками С гораздо сложнее работать. Вы напрямую манипулируете указателями на память и ее содержимое. Для их нулевого символа завершения всегда требуется на один байт больше, чем указывает их длина. Вы должны убедиться, что для них выделена память, прежде чем копировать в них.

0 голосов
/ 11 июля 2019

Обновление на этом.

dev_uuid = device.getServiceUUID().toString().c_str(); Это правильный метод.

При получении результатов сканирования, если на устройстве рекламодателя не задан UUID, dev_uuid возвращает ноль и не может печатать или что-либо еще. Вы можете добавить метод .haveServiceUUID для возврата значения bool, и если оно истинно, вы можете получить UUID без проблем. В противном случае, если на устройстве рекламодателя не установлен UUID, возникает проблема, которая приводит к Guru Meditation Error: Core

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

...