I have some example BLE code for collecting data from a BLE temperature probe that I'm using with a Core2 (Visual Studio + PlatformIO). All of this BLE code works for my testing purposes. If I restart/reboot the unit, it works perfectly fine, but if I power-cycle the Core2 the serial connection no longer works. In that PlatformIO no longer shows the serial output. That said, the unit boots-up perfectly fine and carries on with it's scanning and printing data to the screen. Just no serial monitoring?
When this happens, if I just unplug and re-plug in the serial/usb cable, then restart the serial monitoring (in PlatformIO), everything is fine. I've tried on two different Core2 units and the both do the same thing. It appears that there is something in this code that's causing it?
Can anyone help with this? Any ideas on whether this is a coding issue or a possibly module issue causing the serial to fail? I really can't see what could be causing this?
#include <Arduino.h>
#include <M5Core2.h>
*/
/**
* A BLE client example that is rich in capabilities.
* There is a lot new capabilities implemented.
* author unknown
* updated by chegewara
*/
#include "BLEDevice.h"
//#include "BLEScan.h"
// The remote service we wish to connect to.
static BLEUUID serviceUUID("a75cc7fc-c956-488f-ac2a-2dbc08b63a04");
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("7edda774-045e-4bbf-909b-45d1991a2876");
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic *pRemoteCharacteristic;
static BLEAdvertisedDevice *myDevice;
static void notifyCallback(
BLERemoteCharacteristic *pBLERemoteCharacteristic,
uint8_t *pData,
size_t length,
bool isNotify)
{
Serial.print("Notify callback for characteristic ");
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
/*
* meat_raw, ambient_raw, offset, whatever = struct.unpack('<hhhh', value)
meat = meat_raw / 16
# 6,33 ist ein anhand mehrerer Wertepaare üer Excel ermittelter Faktor, k.A. wo dieser herkommt....
ambient = (meat_raw + max(0, (ambient_raw - offset)) * 6.33) / 16
*/
int meat_raw = ((pData[1] << 8) + (pData[0]));
float temp_int = float(meat_raw) / 16;
int ambient_raw = ((pData[3] << 8) + (pData[2]));
int offset = ((pData[5] << 8) + (pData[4]));
float ambient = float(meat_raw + max(0, (ambient_raw - offset)) * 6.33) / 16;
M5.Lcd.clearDisplay();
M5.Lcd.setCursor(0, 10);
M5.Lcd.print("temp int: ");
M5.Lcd.println(temp_int);
M5.Lcd.print("ambient int: ");
M5.Lcd.println(ambient);
Serial.print("data: ");
Serial.println((char *)pData);
Serial.print("temp int: ");
Serial.println(temp_int);
Serial.print("ambient: ");
Serial.println(ambient);
}
class MyClientCallback : public BLEClientCallbacks
{
void onConnect(BLEClient *pclient)
{
}
void onDisconnect(BLEClient *pclient)
{
connected = false;
Serial.println("onDisconnect");
}
};
bool connectToServer()
{
Serial.print("Forming a connection to ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEClient *pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// 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);
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);
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())
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
{
/**
* Called for each advertising BLE server.
*/
void onResult(BLEAdvertisedDevice advertisedDevice)
{
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);
doConnect = true;
doScan = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup()
{
/*
It seems we have a M5Core2 problem. All of this BLE code works, but if I power off the unit and then on again, the serial connection no longer works.
If I restart/reboot the unit, it works perfectly fine... The unit boots-up perfectly fine and carries on with it's scanning and printing of data. In that
PlatformIO no longer shows the serial output.
When this happens, if I just unplug and re-plug in again the serial/usb cable, then restart the serial monitoring, everything is fine.
I've tried on two different Core2 units and the both do the same thing. It appears that there is something in this code that's causing it?
*/
// kMBusModeOutput, powered by USB or Battery
// kMBusModeInput, powered by outside input
M5.begin(true, true, true, true, kMBusModeOutput);
// M5.begin(true,true,true,true,kMBusModeInput);
M5.Axp.SetLed(true); // Lets just turn this on so we know we're up and running
M5.Lcd.println("Boot(ing)");
// Loop while no serial: yet this never reports their is a problem?
while (!Serial)
{
M5.Lcd.clearDisplay();
M5.Lcd.setCursor(0, 0);
M5.Lcd.println("No serial");
Serial.begin(115200);
delay(1000);
}
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.
BLEScan *pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
} // End of setup.
// This is the Arduino main loop function.
void loop()
{
// 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 (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;
}
// If we are connected to a peer BLE Server, update the characteristic each time we are reached
// with the current time since boot.
if (connected)
{
String newValue = "Time since boot: " + String(millis() / 1000);
Serial.println("Setting new characteristic value to \"" + newValue + "\"");
// Set the characteristic's value to be the array of bytes that is actually a string.
pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
}
else if (doScan)
{
BLEDevice::getScan()->start(0); // this is just sample to start scan after disconnect, most likely there is better way to do it in arduino
}
delay(1000); // Delay a second between loops.
} // End of loop
'''