Best mode to send BLE data to the cloud

Hi,
i’m looking for the best mode to send data to Particle Cloud with Argon/Boron in Central Mode.

Example:

void loop()
{
  BLE.setScanTimeout(75);
  int count = BLE.scan(scanResults, SCAN_RESULT_MAX);
  for (int ii = 0; ii < count; ii++) {
    scanResults[ii].advertisingData.get(
      BleAdvertisingDataType::MANUFACTURER_SPECIFIC_DATA, 
      buf, BLE_MAX_ADV_DATA_LEN);  //some code
  }
  Particle.publish("data",dataResults,PRIVATE);
  delay(2000);
}

I’ve seen that this mode is instable and sometimes cause a block in the firmware. Is there a better mode ?

It is difficult to tell which mode you are talking about without including all you code!

Recommended approach is to use SYSTEM_THREAD(ENABLED); and I typically use SYSTEM_MODE(SEMI_AUTOMATIC); but then you need to turn on modems and connect. Selecting and using external antennas is also a good idea.

Also, it is advisable to use a send buffer such as PublishQueueAsyncRK library that will buffer in retained RAM the cloud publishes and that way enables the loop to keep up a good cadence. I would be tempted to replace use of delay(2000); with a timer check if (millis() - lastCheck > 2000) { lastCheck = millis(); your scan code}

You would also not set BLE.setScanTimeout() repeatedly.
The local device should remembers the setting :wink:

And since the scan results are allocated dynamically chances are that you are seeing some issue with heap fragmentation.
But to have a better “guess” knowing what you consider “instable” and “block in the firmware” would be helpful.
What is the common timeframe for the “instability” to occure?
What does the device do when it is “blocking”?

Ok, apologies for partial code. This is the entire loop code:

void loop() {
    BLE.setScanTimeout(75);
     int count = BLE.scan(scanResults, SCAN_RESULT_MAX);
     String risultato="";
     String risultatoLoop="";
   
    for (int ii = 0; ii < count; ii++) {
          uint8_t buf[BLE_MAX_ADV_DATA_LEN];
        
        String mac=String::format("%02X",scanResults[ii].address[0])
           +String::format("%02X",scanResults[ii].address[1])
           +String::format("%02X",scanResults[ii].address[2])
           +String::format("%02X",scanResults[ii].address[3])
           +String::format("%02X",scanResults[ii].address[4])
           +String::format("%02X",scanResults[ii].address[5]);
         
       scanResults[ii].advertisingData.get(BleAdvertisingDataType::MANUFACTURER_SPECIFIC_DATA , buf, BLE_MAX_ADV_DATA_LEN);
       String stato="N.D";
       risultatoLoop="";
     
       if(buf[2]==2 && buf[3]==21)
       {
           if(scanResults[ii].rssi>-45)
            stato="PROSSIMO";
            
           if(scanResults[ii].rssi>=-65 && scanResults[ii].rssi<-45)
            stato="VICINO";
           
           if(scanResults[ii].rssi>-85 && scanResults[ii].rssi<-65)
            stato="LONTANO";
           
           if(scanResults[ii].rssi>-100 && scanResults[ii].rssi<=-85)
            stato="ASSENTE";                        
            risultatoLoop=(String)scanResults[ii].rssi+"*"+mac+"*"+System.deviceID()+"*"+stato+"|";
            risultato.concat(risultatoLoop);                    
       }      
    }  
    delay(2000);
    Particle.publish("dataResults",risultato,PRIVATE);    
}

What i mean with blocking is that after 5-10 seconds dataResults become null and moreover the device begin to disconnect from network (blinking green)…
I think that the problem is related, as you rightly stated ,with the fragmentation of the heap…

When I said this

I was not aware of your abundant (maybe even excessive :wink: ) use of String objects - these are contributing to heap fragmentation even more.
Try to avoid them entirely and rather use ol'-school C strings (aka char arrays).

1 Like