Hi,
This is a somewhat common BLE Scanning sketch on an ESP32 Devkit to monitor TPMS. I've added FreeRTOS to have this processed on Core 0. I've noticed a memory issue, but am unable to deduce the cause. Would greatly appreciate if someone could put some fresh eyes on this and see what I'm doing wrong?
Also. This same issue occurred regardless of using FreeRTOS or not.
I'm including both the Sketch and copy of the Serial Terminal to show the memory loss. Unfortunately, the Arduino-ESP32 only offers four functions for getting Heap Memory Info.
These calls do not provide a 'fragmentation' (unlike the ESP-IDF), but it does show how the "FREE" memory is slowly declining over time.
Thank you ahead of time for any assistance that could be lent!
#include <Streaming.h> // http://arduiniana.org/libraries/streaming/
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
//Assignments
BLEScan* pBLEScan;
static BLEAddress *pServerAddress;
// Variables
int BLEscantime = 0;
int CF = 0;
bool boot = 0;
int pFTime_interval = 1000; //Checks HEAP every interval
unsigned long pFTime,cTime;
int getFreeHeap_prev;
////////////////////////////////For GUISlice
char TPMS_Pres[6], TPMS_Temp[6], TPMS_Battery[6], TPMS_Signal[6];
// TPMS BLE SENSORS known addresses
String knownAddresses[] = {
"80:ea:ca:12:1d:10", //FRONT
"81:ea:ca:22:19:43", //BACK
"80:ea:ca:12:8b:2c", //LEFT
"81:ea:ca:22:8c:85" //RIGHT
};
// TPMS active data
int TPMSNew [4][5] = { //pres,temp,bat,sig,alarm
{999,999,99,99,0},
{999,999,99,99,0},
{999,999,99,99,0},
{999,999,99,99,0},
};
int TPMSPrev [4][5] = { //pres,temp,bat,sig,alarm
{999,999,99,99,0},
{999,999,99,99,0},
{999,999,99,99,0},
{999,999,99,99,0},
};
/////////////////////////// FreeRTOS
TaskHandle_t BLETPMS;
void Task1code( void * parameter ){
Serial << "BLE_TPMS Scanning is running on core " << xPortGetCoreID() << endl;
for(;;){
BLEScanResults scanResults = pBLEScan->start(BLEscantime, false);
}
}
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);
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
// int i;
void onResult(BLEAdvertisedDevice Device){
pServerAddress = new BLEAddress(Device.getAddress());
bool known = false;
bool Master = false;
String ManufData = Device.toString().c_str();
for (int i = 0; i < 4; i++) {
if (strcmp(pServerAddress->toString().c_str(), knownAddresses[i].c_str()) == 0) {
known = true;
delete pServerAddress;
if (known) {
String instring=retmanData(ManufData, 0);
if (CF == 0) { //METRIC
TPMSNew[i][0] = round(returnData(instring, 8) / 1000.0); //Pres in Kpa
TPMSNew[i][1] = round(returnData(instring, 12) / 100.0); //Temp in C°
} else { //IMPERIAL
TPMSNew[i][0] = round((returnData(instring, 8) / 1000.0) / 6.89475729); //Pres in PSI
TPMSNew[i][1] = round(((returnData(instring, 12) / 100.0) * 1.8) + 32); //Temp in F°
}
TPMSNew[i][2] = round(returnBatt(instring)); //Battery
TPMSNew[i][3] = round(Device.getRSSI()); //Signal
if (returnAlarm(instring)) { //1=ALARM, 0=NOALARM
TPMSNew[i][4] = 1;
} else {
TPMSNew[i][4] = 0;
}
if (!boot) { //startup boot: Copies New to Prev
for (int ti = 0; ti < 5; ti++) {
TPMSPrev[i][ti] = TPMSNew[i][ti]; //copy New to Prev
}
UpdateALLTPMS(); //Displays TPMS on first boot
} else {
for (int ti = 0; ti < 5; ti++) { //Routine ops: comparison
if (TPMSPrev[i][ti] != TPMSNew[i][ti]) {
TPMSPrev[i][ti] = TPMSNew[i][ti]; //copy New to Prev (for next comparison)
// newprint = 1; //Sets New Printing Flag
}
}
}
// PrintNEWTPMSReading(); //TESTING
sprintf(TPMS_Pres, "%d", TPMSPrev[i][0]); //Pres
sprintf(TPMS_Temp, "%d", TPMSPrev[i][1]); //Temp
sprintf(TPMS_Battery, "%d", TPMSPrev[i][2]); //Battery in %
sprintf(TPMS_Signal, "%d", TPMSPrev[i][3]); //Signal in dB
//SERIAL TEST PRINT TPMS DATA
// String instring=retmanData(ManufData, 0);
// Serial << instring << endl << "Device found: " << Device.getRSSI() << endl;
// Tire Temperature in C°
// Serial << "Temperature: " << (returnData(instring,12)/100.0) << "C°" << endl;
// Tire pressure in Kpa
// Serial << "Pressure Kpa: " << (returnData(instring,8)/1000.0) << "Kpa" << endl;
// // Tire pressure in Bar
// Serial << "Pressure Bar: " << (returnData(instring,8)/100000.0) << "bar" << endl;
// // Battery percentage
// Serial << "Battery: " << (returnBatt(instring)) << "%" << endl;
// if (returnAlarm(instring)) {Serial << "ALARM!" << endl;}
// Device->getScan()->stop();
// delay(500);
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
}//if known loop
}//if loop - checks TMPS Address ID
}//for loop
}//onResult loop
};//class
void setup() {
Serial.begin(115200);
delay(500);
// BLE Init
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
Serial << "BLE Ready to SCAN for TPMS" << endl;
//FreeRTOS: using Core 0 for BLE Scanning
xTaskCreatePinnedToCore(Task1code,"BLETPMS",20000,NULL,1,&BLETPMS,0);
//HEAP Monitoring
Serial << endl << "Total\tLargest\tSmall\tFREE\tUsed%" << endl; //prints titles
}
void loop() {
FragPrint(); //Measures HEAP
if (!boot) {boot = 1;}
}
void FragPrint() {
cTime = millis();
if (cTime - pFTime > pFTime_interval) { //interval check
pFTime = cTime;
double Used = 100 - (ESP.getMaxAllocHeap() * 100 / ESP.getHeapSize());
if (ESP.getFreeHeap() != getFreeHeap_prev) { //HEAP comparison
getFreeHeap_prev = ESP.getFreeHeap();
// Serial << endl << "Total\tLargest\tSmall\tFREE\tUsed%" << endl;
Serial << ESP.getHeapSize() << "\t" << ESP.getMaxAllocHeap() << "\t" << ESP.getMinFreeHeap() << "\t" << getFreeHeap_prev << "\t" << Used << endl;
}
}
}
void UpdateALLTPMS() { ////////////////////////////////////// ACTUAL DISPLAY PRINTING
int i,ti;
for (i=0; i<4; i++) {
for (ti=0; ti<5; ti++) { //copy New to Prev
TPMSPrev[i][ti] = TPMSNew[i][ti];
}
sprintf(TPMS_Pres, "%u", TPMSPrev[i][0]); //Pres
sprintf(TPMS_Temp, "%u", TPMSPrev[i][1]); //Temp
sprintf(TPMS_Battery, "%u", TPMSPrev[i][2]); //Battery in %
sprintf(TPMS_Signal, "%d", TPMSPrev[i][3]); //Signal in dB
}
}
void PrintNEWTPMSReading() { //Live Readings
Serial << endl << "PRINTNG NEW TPMS Sensor VALUES" << endl;
for (int pi = 0; pi < 4; pi++) { //TEST change "pi < 4" to 1
switch (pi) {
case 0:
Serial << " Front" << endl;
break;
case 1:
Serial << " Back" << endl;
break;
case 2:
Serial << " Left" << endl;
break;
case 3:
Serial << " Right" << endl;
break;
}
Serial << "Pres \t" << TPMSNew[pi][0] << endl
<< "Temp \t" << TPMSNew[pi][1] << endl
<< "Battery\t" << TPMSNew[pi][2] << endl
<< "Signal \t" << TPMSNew[pi][3] << endl
<< "Alarm \t" << TPMSNew[pi][4] << endl;
}
}
//BLE Scanning Routines
String retmanData(String txt, int shift) {
// Return only manufacturer data string
int start=txt.indexOf("data: ")+6+shift;
return txt.substring(start,start+(36-shift));
}
byte retByte(String Data,int start) {
// Return a single byte from string
int sp=(start)*2;
char *ptr;
return strtoul(Data.substring(sp,sp+2).c_str(),&ptr, 16);
}
long returnData(String Data,int start) {
// Return a long value with little endian conversion
return retByte(Data,start)|retByte(Data,start+1)<<8|retByte(Data,start+2)<<16|retByte(Data,start+3)<<24;
}
int returnBatt(String Data) {
// Return battery percentage
return retByte(Data,16);
}
int returnAlarm(String Data) {
// Return battery percentage
return retByte(Data,17);
}
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13924
ho 0 tail 12 room 4
load:0x40080400,len:3600
entry 0x400805f0
BLE Ready to SCAN for TPMS
BLE_TPMS Scanning is running on core 0
Total Largest Small FREE Used%
270280 90100 143816 145276 67.00
269592 90100 141948 142528 67.00
269512 90100 141576 142196 67.00
269480 90100 141576 142032 67.00
269512 90100 141576 142196 67.00
269432 90100 141312 141896 67.00
269416 90100 141312 141768 67.00
269432 90100 141312 141896 67.00
269576 90100 140872 142836 67.00
269496 90100 140872 142532 67.00
269416 90100 140872 142200 67.00
269384 90100 140872 141868 67.00
269416 90100 140872 142200 67.00
269256 90100 140872 141564 67.00
269176 90100 140680 141264 67.00
269128 90100 140680 140988 67.00
269176 90100 140680 141264 67.00
269096 90100 140432 140936 67.00
269064 90100 140432 140656 67.00
269096 90100 140432 140936 67.00
269032 90100 140180 140660 67.00
268984 90100 140180 140368 67.00
269032 90100 140180 140660 67.00
269016 90100 140180 140532 67.00
269032 90100 140180 140660 67.00
269000 90100 140180 140496 67.00
269032 90100 140180 140660 67.00
268984 90100 140180 140368 67.00
269032 90100 140180 140660 67.00
269016 90100 140180 140532 67.00
269032 90100 140180 140660 67.00
269016 90100 140180 140532 67.00
269032 90100 140180 140660 67.00
268984 90100 140180 140276 67.00
269032 90100 140180 140660 67.00
268968 90100 140180 140240 67.00
269032 90100 140180 140660 67.00
269000 90100 140180 140328 67.00
269032 90100 140180 140660 67.00
269000 90100 140180 140404 67.00
269032 90100 140180 140660 67.00
269016 90100 140180 140532 67.00
269032 90100 140180 140660 67.00
269016 90100 140180 140532 67.00
269032 90100 140180 140660 67.00
268952 90100 139824 140336 67.00
268872 90100 139512 140024 67.00
268840 90100 139512 139860 67.00
268872 90100 139512 140024 67.00
268840 90100 139512 139744 67.00
268872 90100 139512 140024 67.00
268792 90100 139068 139708 67.00
268712 90100 138872 139396 67.00
268696 90100 138872 139268 67.00
268712 90100 138872 139396 67.00
268632 90100 138580 139072 67.00
268600 90100 138580 138904 67.00
268632 90100 138580 139072 67.00
268616 90100 138580 138944 67.00
268632 90100 138580 139072 67.00
268616 90100 138580 138944 67.00
268632 90100 138580 139072 67.00
268552 90100 138376 138760 67.00
268536 90100 138276 138632 67.00
268552 90100 138276 138760 67.00
268536 90100 138276 138632 67.00
268552 90100 138276 138760 67.00
268520 90100 138164 138504 67.00
268552 90100 138164 138760 67.00
268520 90100 138164 138504 67.00
268552 90100 138164 138760 67.00
268536 90100 138164 138684 67.00
268552 90100 138164 138760 67.00
268520 90100 138164 138588 67.00
268552 90100 138164 138760 67.00
268408 90100 137552 138204 67.00
268424 90100 137552 138332 67.00
268392 90100 137552 138056 67.00
268424 90100 137552 138332 67.00