Currently we are developing an android app that can advertise itself from the BLE(bluetooth low energy)
to ESP32
devices. ESP32 collects the MAC address
, device name
, and service UUID
and send the data to MySQL server
. So far ESP32 can send the device name and MAC address but somehow, we have not able to send UUID data.
http://www.neilkolban.com/esp32/docs/cpp_utils/html/class_b_l_e_advertised_device.html
From the BLEadvertisedDevice
library, some usefull information can be found.
As far as I understand, getServiceUUID () returns a BlEUUID(http://www.neilkolban.com/esp32/docs/cpp_utils/html/class_b_l_e_u_u_i_d.html) object, and it has a toString method that takes the void argument(not the BLEadvertisedDevice object but BLEUUID object). My first question is why BLEadvertisedDevice does not take any arguments but BLEUUID takes void as a argument for the toString method. I tried to assign the object to string but no chance I tried these, whole code given below.
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();
Error logs are given below
This is the whole code
#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);
}
Error for the: dev_uuid = device.getServiceUUID().toString().c_str(); It compiles but from the serial monitor :
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
Error for the: 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));
Error for the: strcpy(dev_uuid,device.getServiceUUID().toString());
invalid conversion from 'const char*' to 'char*' [-fpermissive]
Error for the: dev_uuid = device.getServiceUUID().toString());
cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' to 'const char*' in assignment
Update on this.
dev_uuid = device.getServiceUUID().toString().c_str();
This is the correct method.
While getting the scan results if the advertiser device does not have an UUID set dev_uuid
returns null and cannot print or anything. You can add .haveServiceUUID method to return a bool value and if it is true then you can get the UUID without problem. Otherwise if the advertiser device does not have an UUID set you get a problem which results in Guru Meditation Error: Core
if (advertisedDevice.haveServiceUUID ())
dev_uuid = advertisedDevice.toString().c_str();
In your code:
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();
Your strcpy()
attempts cannot possibly work the way you wrote them. You have an uninitialized pointer (dev_uuid
) and you're copying data into... wherever it happens to point to. This is why you're getting panics.
Use a String
object, not a C string, instead:
String dev_uuid;
dev_uuid = device.getServiceUUID().toString();
There's a huge difference between the Arduino String
class and C strings. Generally if you see a toString()
method, it's the Arduino String class. Reading the documentation should make it clear that a method returns a String
; if it does, you should assign the return value to a String
.
C strings are much more difficult to work with. You're directly manipulating pointers to memory and the contents of memory. They always need one byte more for their null termination character than their length indicates. You need to make sure that there's memory allocated for them before you copy into them.
User contributions licensed under CC BY-SA 3.0