Hi all,
This is my setup:
- Argon1 acting as BLE central, not connected to the cloud (don't care for now). DeviceOS 5.1.0
- Argon2 acting as BLE peripheral, not connected to the cloud (will never connect since there is no need in my scenario), sleeping in ULTRA_LOW_POWER mode. Tested DeviceOS 5.1.0 and 4.0.0.
Argon2 boots and waits for a BLE connection then goes to sleep for some time or can wake up via BLE (Argon1 will wake it up).
This is my problem:
when I use sleep config duration(x) and ble() at the same time, right before going to sleep, Argon2 crashes with SOS code 1: Hard fault.
Argon2 will go to sleep after it receives a BLE command from Argon1 to go to sleep.
My sleep config:
sleepConfig.mode(SystemSleepMode::ULTRA_LOW_POWER)
.ble()
.duration(120000);
If I only use one, either ble() or duration(x), all is good.
Argon 2 serial log:
Serial monitor opened successfully:
0000001912 [app] INFO: BLE Peripheral started
0000001912 [app] INFO: Waiting for incoming connections
0000001913 [app] INFO: Hint: you can now power on (or power cycle) the other device)
0000017908 [wiring.ble] TRACE: Connected by Central device.
0000017908 [app] INFO: ******** Connected to central device
0000017914 [system.ctrl.ble] TRACE: Connected
0000020879 [app] INFO: ====>>>> Received SLEEP command
0000020880 [app] INFO: About to go to sleep in 1 second
0000022014 [app] INFO: Going to sleep in 1 second
0000023015 [system.sleep] TRACE: Entering system_sleep_ext()
0000023015 [system.sleep] TRACE: Interface 4 is off already
<<-- DEVICE CRASHED HERE -->>
Serial connection closed. Attempting to reconnect...
Where are things going wrong?
Thanks!
Argon1 code:
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
SerialLogHandler logHandler(LOG_LEVEL_WARN, {
{"app", LOG_LEVEL_ALL},
{"system.ctrl.ble", LOG_LEVEL_ALL},
{"wiring.ble", LOG_LEVEL_ALL},
});
const BleUuid serviceUuid("a1d1daf4-aaa2-4d9d-9214-9df347db4287");
const BleUuid txUuid("a1d1daf4-aaa2-4d9d-9214-9df347db4288");
const BleUuid rxUuid("a1d1daf4-aaa2-4d9d-9214-9df347db4289");
#define BLE_SLEEP "sleep"
const BleScanResult *bleScanResult;
BleCharacteristic rxCharacteristic;
BleCharacteristic txCharacteristic;
BlePeerDevice peripheral;
void setup()
{
BLE.on();
BLE.setScanPhy(BlePhy::BLE_PHYS_1MBPS);
waitFor(Serial.isConnected, 15000);
delay(1000);
scan();
bleSend(BLE_SLEEP);
}
void loop()
{
}
bool bleSend(const char *message)
{
if (peripheral.connected())
{
Log.info("====>>>> Sending to peripheral: %s", message);
txCharacteristic.setValue(message);
return true;
}
else
{
Log.info("====>>>> Not sending to peripheral: %s", message);
return false;
}
}
void scan()
{
BleScanFilter filter;
filter.serviceUUID(serviceUuid);
Vector<BleScanResult> scanResults = BLE.scanWithFilter(filter);
Log.info("Found %u %s", scanResults.size(), scanResults.size() == 1 ? "device" : "devices");
// if there are more than 1 devices, connect to the one with the strongest signal
if (scanResults.size() > 1)
{
// find the scan result for the peripheral with the highest RSSI
int maxRSSI = -1000;
for (int i = 0; i < scanResults.size(); i++)
{
if (scanResults[i].rssi() > maxRSSI)
{
maxRSSI = scanResults[i].rssi();
bleScanResult = &scanResults[i];
}
}
}
else if (scanResults.size() == 1)
{
bleScanResult = &scanResults[0];
}
else
{
return;
}
peripheral = BLE.connect(bleScanResult->address());
if (peripheral.connected())
{
Log.info("Peripheral connected");
peripheral.getCharacteristicByUUID(rxCharacteristic, rxUuid);
peripheral.getCharacteristicByUUID(txCharacteristic, txUuid);
}
else
{
Log.info("Failed to connect to peripheral");
}
}
Argon2 code:
// system modes tested: MANUAL and AUTO (no difference)
SYSTEM_MODE(MANUAL);
// system thread enabled/disabled: no difference
SYSTEM_THREAD(ENABLED);
SerialLogHandler logHandler(LOG_LEVEL_TRACE, {
{"app", LOG_LEVEL_ALL},
{"system.ctrl.ble", LOG_LEVEL_ALL},
{"wiring.ble", LOG_LEVEL_ALL},
});
const char *serviceUuid = "a1d1daf4-aaa2-4d9d-9214-9df347db4287";
const char *rxUuid = "a1d1daf4-aaa2-4d9d-9214-9df347db4288";
const char *txUuid = "a1d1daf4-aaa2-4d9d-9214-9df347db4289";
BleCharacteristic txCharacteristic("tx", BleCharacteristicProperty::INDICATE, txUuid, serviceUuid);
BleCharacteristic rxCharacteristic("rx", BleCharacteristicProperty::WRITE, rxUuid, serviceUuid, onDataReceived, NULL);
bool goToSleepFlag = false;
SystemSleepConfiguration sleepConfig;
void setup()
{
sleepConfig.mode(SystemSleepMode::ULTRA_LOW_POWER)
.ble()
.duration(120000);
waitFor(Serial.isConnected, 15000);
delay(1000);
// we only need to do this in MANUAL mode
BLE.on();
BLE.setAdvertisingPhy(BlePhy::BLE_PHYS_1MBPS);
BLE.addCharacteristic(txCharacteristic);
BLE.addCharacteristic(rxCharacteristic);
BLE.onConnected(connectedCallback, NULL);
BleAdvertisingData data;
data.appendServiceUUID(serviceUuid);
BLE.advertise(&data);
Log.info("BLE Peripheral started");
Log.info("Waiting for incoming connections");
Log.info("Hint: you can now power on (or power cycle) the other device)");
}
void loop()
{
if (goToSleepFlag)
{
goToSleep();
goToSleepFlag = false;
}
}
void onDataReceived(const uint8_t *data, size_t len, const BlePeerDevice &peer, void *context)
{
if (strcmp((const char *)data, "sleep") == 0)
{
Log.info("====>>>> Received SLEEP command");
goToSleepFlag = true;
}
}
void goToSleep()
{
Log.info("About to go to sleep in 1 second");
BLE.disconnect();
// BLE.stopAdvertising();
// BLE.off();
delay(1000);
Log.info("Going to sleep in 1 second");
delay(1000);
System.sleep(sleepConfig);
waitFor(Serial.isConnected, 15000);
delay(1000);
Log.info("Back from sleep");
}
void connectedCallback(const BlePeerDevice &peer, void *context)
{
Log.info("******** Connected to central device");
}
Edit: seems to be similar to the issue reported here.
EDIT 2: issue was fixed on DeviceOS 4.1.0.