I want to save 100KB to do the some new Tasks to improve the IoT UE.
- Connection Management, include auto reconnect/change connection channel.
- Save data into Flash due to the offline, bad network env.
- Micro Gateway/Edge that can parse the data according to the download config.
- Execute some micro rule engine script by above gateway parse engine.
- Auto timer script with above engine.
- Micro web service in AP/STA mode, that can let the user config the wifi ssid/password, and provide some pages to let the user view the device’s telemetry and attribute, without Bluetooth APP and MQTT Server side webpage.
here bellow attached is my code copied from Ameba Arduino examples with FreeRTOS task creation.
I found the memory usage like bellow:
- Bletooth with Ble.Init(), 150KB, global static + rtos heap;
- WiFi + MQTT, 200KB
- TLS, 50~60KB
Can you give me the main memory usage details?
#include "Ds1302.h"
Ds1302 rtc(PA14, PA12, PA13);
TaskHandle_t mqttTaskHandle = NULL;
#include "BLEDevice.h"
#define UART_SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
#define STRING_BUF_SIZE 100
BLEService UartService(UART_SERVICE_UUID);
BLECharacteristic Rx(CHARACTERISTIC_UUID_RX);
BLECharacteristic Tx(CHARACTERISTIC_UUID_TX);
BLEAdvertData advdata;
BLEAdvertData scndata;
bool notify = false;
void readCB (BLECharacteristic* chr, uint8_t connID) {
Serial.print("Characteristic ");
Serial.print(chr->getUUID().str());
Serial.print(" read by connection ");
Serial.println(connID);
}
void writeCB (BLECharacteristic* chr, uint8_t connID) {
Serial.print("Characteristic ");
Serial.print(chr->getUUID().str());
Serial.print(" write by connection ");
Serial.println(connID);
if (chr->getDataLen() > 0) {
Serial.print("Received string: ");
Serial.print(chr->readString());
Serial.println();
}
}
void notifCB(BLECharacteristic* chr, uint8_t connID, uint16_t cccd) {
if (cccd & GATT_CLIENT_CHAR_CONFIG_NOTIFY) {
//printf("Notifications enabled on Characteristic %s for connection %d \n", chr->getUUID().str(), connID);
Serial.print("Notifications enabled on Characteristic");
notify = true;
} else {
//printf("Notifications disabled on Characteristic %s for connection %d \n", chr->getUUID().str(), connID);
Serial.print("Notifications disabled on Characteristic");
notify = false;
}
Serial.print(chr->getUUID().str());
Serial.print(" for connection");
Serial.println(connID);
}
void connectBluetooth(){
advdata.addFlags(); //GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED
//advdata.addData((const uint8_t*)"020106080948554C4B4D414E12FFFFFF20208011F6C4487F4E0244DD010000", sizeof("020106080948554C4B4D414E12FFFFFF20208011F6C4487F4E0244DD010000"));
advdata.addCompleteName("BrandName");
scndata.addCompleteServices(BLEUUID(UART_SERVICE_UUID));
Rx.setWriteProperty(true);
Rx.setWritePermissions(GATT_PERM_WRITE);
Rx.setWriteCallback(writeCB);
Rx.setBufferLen(STRING_BUF_SIZE);
Tx.setReadProperty(true);
Tx.setReadPermissions(GATT_PERM_READ);
Tx.setReadCallback(readCB);
Tx.setNotifyProperty(true);
Tx.setCCCDCallback(notifCB);
Tx.setBufferLen(STRING_BUF_SIZE);
UartService.addCharacteristic(Rx);
UartService.addCharacteristic(Tx);
BLE.init();
//BLE.setDeviceName("Brand");
//BLE.configAdvert()->stopAdv();
BLE.configAdvert()->setAdvData(advdata);
BLE.configAdvert()->setScanRspData(scndata);
BLE.setDeviceName("BrandName222222");
//BLE.configAdvert()->startAdv();
BLE.configServer(1);
BLE.addService(UartService);
BLE.beginPeripheral();
}
#include <WiFi.h>
char ssid[] = "Office_NETGEAR";
char password[] = "1234567890";
TaskHandle_t TaskHandle_WiFiConnect;
void wifi_connect_task(void *pvParameters){
Serial.println("WiFi Connect Task Started");
WiFi.begin(ssid, password);
for (int i = 0; i < 30; ++i) { // 30 attempts, ~3-10 seconds
if (WiFi.status() == WL_CONNECTED) {
Serial.println("Connected to WiFi!");
break;
}
vTaskDelay(pdMS_TO_TICKS(1000)); // Wait for 1 second
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Failed to connect to WiFi. Please check your settings.");
}
vTaskDelete(NULL); // Delete this task if it's no longer needed
}
void asyncConnectWiFi(){
Serial.println("asyncConnectWiFi 1111111111111");
xTaskCreate(
wifi_connect_task, /* Task function */
"WiFi Connect", /* Name of task */
2048, /* Stack size */
NULL, /* Task input parameter */
1, /* Priority of the task */
&TaskHandle_WiFiConnect); /* Task handle */
Serial.println("asyncConnectWiFi 22222222222222");
}
void setup() {
Serial.begin(115200);
Serial1.begin(115200);
//rtc.init();
asyncConnectWiFi();
asyncConnectBluetooth();
//createHugeArray();
}
const int array_length1 = 10 * 1024;
unsigned char myArray1[array_length1];
void createHugeArray() {
int array_length = 1 * 1024;
unsigned char* myArray = (unsigned char*)pvPortMalloc(array_length);
if (myArray != NULL) {
vTaskDelay(pdMS_TO_TICKS(100));
Serial.print("First address: ");
Serial.println((unsigned long)&myArray[0], HEX);
vTaskDelay(pdMS_TO_TICKS(50));
Serial.print("Final address: ");
Serial.println((unsigned long)&myArray[array_length - 1], HEX);
Serial.print("First address: ");
Serial.println((unsigned long)&myArray1[0], HEX);
Serial.print("Final address: ");
Serial.println((unsigned long)&myArray1[array_length1 - 1], HEX);
vPortFree(myArray);
} else {
vTaskDelay(pdMS_TO_TICKS(50));
Serial.println("Memory allocation failed!");
}
}
void loop() {
//printTime();
serial1Update();
//check_wifi(); // Check WiFi connection status
print_task(); // Monitor and log task status
if (WiFi.status() != WL_CONNECTED && mqttTaskHandle != NULL) {
Serial.println("Network is down, stopping MQTT task.");
vTaskDelete(mqttTaskHandle);
mqttTaskHandle = NULL;
} else if (WiFi.status() == WL_CONNECTED && mqttTaskHandle == NULL) {
Serial.println("Network is up, starting MQTT task.");
xTaskCreate(connect_mqtt_task, "MQTT Task", 2048, NULL, 1, &mqttTaskHandle);
}
if (BLE.connected(0)) { // Assuming 0 is the connection ID for the BLE connection
asyncSendBluetoothData(); // Send data over Bluetooth if connected
}
//if (mqttClient.connected()) {
// asyncSendMQTTData(); // Send data over MQTT if connected
// }
delay(100); // Delay to prevent flooding; adjust as necessary
}
void serial1Update(){
if (Serial1.available()) {
byte inByte = Serial1.read();
Serial.println(inByte);
}
delay(100);
}
void printTime(){
Ds1302::DateTime now;
rtc.getDateTime(&now);
Serial.print("Current Date/Time: ");
Serial.print(now.year); Serial.print("-");
Serial.print(now.month); Serial.print("-");
Serial.print(now.day); Serial.print(" ");
Serial.print(now.hour); Serial.print(":");
Serial.print(now.minute); Serial.print(":");
Serial.println(now.second);
delay(1000);
}
void asyncSendBluetoothData(){}
void asyncSendMQTTData(){}
void check_wifi(){
if (WiFi.status() == WL_CONNECTED) {
Serial.println("connected wifi 44444444444444");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP()); // Print the IP address
delay(1000); // Example: Check every 10 seconds instead of as fast as possible
} else {
Serial.println("not connected the wifi 33333333333333333333");
//WiFi.begin(ssid, password); // Attempt to reconnect
delay(1000); // Wait a bit before the next check
}
}
void print_task() {
Serial.println("===== Task Monitor =====");
// Total and used heap memory
uint32_t totalHeap = configTOTAL_HEAP_SIZE;
uint32_t usedHeap = totalHeap - xPortGetFreeHeapSize();
uint32_t freeHeap = xPortGetFreeHeapSize();
Serial.print("Total Heap Size: ");
Serial.println(totalHeap);
Serial.print("Used Heap Size: ");
Serial.println(usedHeap);
Serial.print("Free Heap Size: ");
Serial.println(freeHeap);
displayFreeRam();
// Task Info
UBaseType_t uxArraySize = uxTaskGetNumberOfTasks();
TaskStatus_t *pxTaskStatusArray;
volatile UBaseType_t uxArraySizeRequired;
// Allocate array to hold the task info
pxTaskStatusArray = (TaskStatus_t *)pvPortMalloc(uxArraySize * sizeof(TaskStatus_t));
if (pxTaskStatusArray != NULL) {
// Generate raw status information about each task
uxArraySizeRequired = uxTaskGetSystemState(pxTaskStatusArray, uxArraySize, NULL);
Serial.println("Tasks Info:");
for (int i = 0; i < uxArraySizeRequired; i++) {
Serial.print("Task ");
Serial.print(i + 1);
Serial.print(" [Name: ");
Serial.print(pxTaskStatusArray[i].pcTaskName);
Serial.print(", ID: ");
Serial.print((unsigned long)pxTaskStatusArray[i].xTaskNumber);
Serial.print(", State: ");
Serial.print(pxTaskStatusArray[i].eCurrentState);
Serial.print(", Stack High Water Mark: ");
Serial.print(pxTaskStatusArray[i].usStackHighWaterMark);
Serial.println("]");
}
// Free the allocated array
vPortFree(pxTaskStatusArray);
} else {
Serial.println("Failed to allocate memory for task info.");
}
Serial.println("=========================");
delay(5000);
}
extern "C" char* sbrk(int incr);
int freeRam() {
char stackDummy = 0;
return &stackDummy - reinterpret_cast<char*>(sbrk(0));
}
void displayFreeRam() {
Serial.print(F("- SRAM left: "));
Serial.println(freeRam());
}
void bluetooth_connect_task(void *pvParameters) {
connectBluetooth(); // Call your existing function to set up the BLE service and start advertising
vTaskDelete(NULL); // Delete this task if it's no longer needed
}
TaskHandle_t TaskHandle_BluetoothConnect;
void asyncConnectBluetooth() {
xTaskCreate(
bluetooth_connect_task, /* Task function */
"Bluetooth Connect", /* Name of task */
2048, /* Stack size */
NULL, /* Task input parameter */
1, /* Priority of the task */
&TaskHandle_BluetoothConnect); /* Task handle */
}
#include <WiFiSSLClient.h>
#include <PubSubClient.h>
//WiFiClient wifiClient;
WiFiSSLClient wifiClient;
PubSubClient mqttClient(wifiClient);
char* rootCABuff =\
"-----BEGIN CERTIFICATE-----\n"\
//........
"MrY=\n"\
"-----END CERTIFICATE-----\n";
char* httpsRootCABuff = "-----BEGIN CERTIFICATE-----\n" \
//..........
"-----END CERTIFICATE-----\n";
char mqttServer[] = "iot.xxxxxxxxxxx.com";
int mqttPort = 8883;
char clientId[] = "new ID";
char clientUser[] = "YYYYYYYYYYYYYYYY";
char clientPass[] = "";
char publishTopic[] = "v1/devices/me/telemetry";
char publishPayload[] = "hello world";
char subscribeTopic[] = "v1/devices/me/rpc/request/+";
char subscribeTopic1[] = "Upgrade1";
char gwConnectTopic[] = "v1/gateway/connect";
char gwDisConnectTopic[] = "v1/gateway/disconnect";
char gwAttributeTopic[] = "v1/gateway/attributes";
char gwAttributeRequest[] = "v1/gateway/attributes/request";
char gwAttributeResponse[] = "v1/gateway/attributes/response";
char gwTelemetryTopic[] = "v1/gateway/telemetry";
char gwRPCTopic[] = "v1/gateway/rpc";
char gwClaimTopic[] = "v1/gateway/claim";
void connect_mqtt_task(void *pvParameters) {
wifiClient.setRootCA((unsigned char*)rootCABuff);
mqttClient.setServer(mqttServer, mqttPort);
for (;;) {
if (!mqttClient.connected()) {
Serial.println("Attempting MQTT connection...");
if (mqttClient.connect(clientId, clientUser, clientPass)) {
Serial.print("Connected to MQTT broker: ");
Serial.println(mqttServer);
// Subscribe to topics
mqttClient.subscribe(subscribeTopic);
mqttClient.subscribe(subscribeTopic1);
} else {
Serial.print("MQTT connection failed, rc=");
Serial.println(mqttClient.state());
// Wait 5 seconds before retrying
vTaskDelay(pdMS_TO_TICKS(5000));
continue;
}
}else{
const int temperature = random(35,42);
String payload = "{\"temperature\":" + String(temperature) + "}";
mqttClient.publish(publishTopic, payload.c_str());
Serial.println(payload);
vTaskDelay(1000);
}
// MQTT client loop processing
mqttClient.loop();
vTaskDelay(pdMS_TO_TICKS(10));
}
// Clean up and delete task if we ever break out of the loop
vTaskDelete(NULL);
}
TaskHandle_t TaskHandle_ConnectToMqtt;
void asyncInitMQTTClient(){
Serial.println("asyncInitMQTTClient 1111111111111");
xTaskCreate(
connect_mqtt_task, /* Task function */
"mqtt", /* Name of task */
2048, /* Stack size */
NULL, /* Task input parameter */
1, /* Priority of the task */
&TaskHandle_ConnectToMqtt); /* Task handle */
Serial.println("asyncInitMQTTClient 22222222222222");
}