I wanted to program with lesser code size but when WiFi / BLE / OTA / MQTT / WebSerial features are added the code is very large with default esp32 setting unable to program tried with minimal spiffs with 1.9MB program with OTA, it works but when updating need to do several time just to update Please help in reducing code and improving mqtt and OTA update easy
Did you forget to post your code ?
Please post your sketch, using code tags when you do
In my experience the easiest way to tidy up the code and add the code tags is as follows
Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.
The easier solution wil be to find an ESP32-Board with 16MB flash
https://de.aliexpress.com/item/32883116057.html
Do you think that there is a secret technique which reduced the size of the every code to factor two or three by including a couple commands in the sketch? ![]()
No, there is no such thing.
In any case, code optimization is a complex and painstaking work and it is primarily up to you, as the author, to do it. And of course, it is impossible to even advise anything on this topic without seeing the code itself
#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE 0
#else
#define ARDUINO_RUNNING_CORE 1
#endif
#include <WiFi.h>
#include <WiFiClient.h>
#include <ArduinoMqttClient.h>
#include <ArduinoJson.h>
#include <WebSerial.h>
#include <Preferences.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <BLEDevice.h>
#include <BLEAdvertising.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <ElegantOTA.h>
#define MAX_DEVICES 10
#define SCAN_DURATION_MS 5
#define MIN_RSSI_THRESHOLD -100 // Adjust this threshold as needed
String ssid;
String password;
String hostname;
Preferences preferences;
BLEAdvertising *pAdvertising;
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
struct DeviceInfo {
String hostnameFounded;
int rssi;
};
String hostnameFounded1;
int blerssivalue;
int wifirssivalue;
DeviceInfo devices[MAX_DEVICES];
int numDevices = 0;
WiFiClient client;
char ts_char[50] = {0};
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
DynamicJsonDocument doc(128);
const char* broker = "192.168.0.101";
const int port = 1883;
const char* topic="device";
const char* username="admin";
const char* pwd="instar";
uint8_t rstcount = 0;
uint8_t rcnctcount = 0;
unsigned long previousMillis = 0;
unsigned long interval = 30000;
const int scanDurationMs = 500;
unsigned long previousScanMillis = 0;
unsigned long previousOTAMillis = 0;
const long sinterval = 5000;
unsigned long ota_progress_millis = 0;
unsigned long OTA_INTERVAL = 10000;
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
void TaskBLEScan( void *pvParameters );
void TaskOTAUpdate( void *pvParameters );
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
AwsFrameInfo *info = (AwsFrameInfo*)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
data[len] = 0;
}
}
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
void *arg, uint8_t *data, size_t len) {
switch (type) {
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
break;
case WS_EVT_DATA:
handleWebSocketMessage(arg, data, len);
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
}
}
void initWebSocket() {
ws.onEvent(onEvent);
server.addHandler(&ws);
}
void onOTAStart() {
// Log when OTA has started
Serial.println("OTA update started!");
// <Add your own code here>
}
void onOTAProgress(size_t current, size_t final) {
// Log every 1 second
if (millis() - ota_progress_millis > 1000) {
ota_progress_millis = millis();
Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
}
}
void onOTAEnd(bool success) {
// Log when OTA has finished
if (success) {
Serial.println("OTA update finished successfully!");
} else {
Serial.println("There was an error during OTA update!");
}
// <Add your own code here>
}
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice)
{
String deviceName = advertisedDevice.getName().c_str();
if (deviceName.startsWith("JiPlus")) {
// Check if device already exists
bool found = false;
for (int i = 0; i < numDevices; i++) {
if (devices[i].hostnameFounded == deviceName) {
found = true;
break;
}
}
// Add device if not found
if (!found && numDevices < MAX_DEVICES) {
devices[numDevices].hostnameFounded = deviceName;
devices[numDevices].rssi = advertisedDevice.getRSSI();
numDevices++;
}
}
}
};
uint8_t attemptReconnect(){
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
}
return mqttClient.connectError(); // return status
}
/* Message callback of WebSerial */
void recvMsg(uint8_t *data, size_t len){
WebSerial.println("Received Data...");
String d = "";
for(uint8_t i=0; i < len; i++){
d += char(data[i]);
}
WebSerial.println(d);
}
void setup() {
Serial.begin(115200);
preferences.begin("credentials", false);
ssid = preferences.getString("ssid", "");
password = preferences.getString("password", "");
hostname = preferences.getString("hostname", "");
if (ssid == "" || password == "" || hostname == "")
{
Serial.println("No values saved for ssid or password or hostname");
}
else
{
WiFi.mode(WIFI_STA);
WiFi.enableSTA(true);
WiFi.begin(ssid.c_str(), password.c_str());
WiFi.setHostname(hostname.c_str());
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
if (rstcount >= 5)
{
ESP.restart();
}
rstcount++;
}
// Print ESP Local IP Address
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("UID is:");
Serial.print(hostname.c_str());
}
BLEDevice::init(hostname.c_str());
BLEDevice::setPower(ESP_PWR_LVL_N12);
BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
pAdvertising->setScanResponse(true); // Optional: Set scan response data
pAdvertising->start();
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
initWebSocket();
xTaskCreatePinnedToCore(
TaskBLEScan
, "AnalogBLEScan"
, 2048 // Stack size
, NULL
, configMAX_PRIORITIES - 1 // Priority
, NULL
, ARDUINO_RUNNING_CORE);
xTaskCreatePinnedToCore(
TaskOTAUpdate
, "AnalogBLEScan"
, 2048 // Stack size
, NULL
, configMAX_PRIORITIES - 2 // Priority
, NULL
, ARDUINO_RUNNING_CORE);
server.begin();
// Start WebSerial
WebSerial.begin(&server);
// Attach Message Callback
WebSerial.msgCallback(recvMsg);
// Start ElegantOTA
ElegantOTA.begin(&server); // Start ElegantOTA
// ElegantOTA callbacks
ElegantOTA.onStart(onOTAStart);
ElegantOTA.onProgress(onOTAProgress);
ElegantOTA.onEnd(onOTAEnd);
Serial.print("Attempting to connect to the MQTT broker: ");
// Serial.println(broker);
mqttClient.setId(hostname);
mqttClient.setUsernamePassword(username, pwd);
if (!mqttClient.connect(broker, port))
{
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1){
delay(1000);
}
}
Serial.println("You're connected to the MQTT broker!");
}
void loop() {
delay(5000);
// Empty. Things are done in Tasks.
ws.cleanupClients();
mqttClient.poll();
WebSerial.println("NFC Communication ON" );
WebSerial.println("IP address: ");
WebSerial.println(WiFi.localIP());
WebSerial.println("My Device ID:");
WebSerial.print(hostname.c_str());
if(!mqttClient.connected())
{
if(!attemptReconnect()){}
}
unsigned long currentMillis = millis();
// if WiFi is down, try reconnecting every CHECK_WIFI_TIME seconds
if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval))
{
// Serial.print(millis());
// Serial.println("Reconnecting to WiFi...");
WiFi.disconnect();
WiFi.reconnect();
previousMillis = currentMillis;
rcnctcount = rcnctcount + 1;
}
if (rcnctcount > 5)
{
ESP.restart();
}
if (currentMillis - previousMillis >= sinterval)
{
// save the last time a message was sent
previousMillis = currentMillis;
// Add data to the JSON document
doc["UniqueId"] = hostname;
doc["NEARBYDEVICE"] = hostnameFounded1;
doc["RSSIWIFI"] = wifirssivalue;
doc["RSSIBLE"] = blerssivalue;
// Serialize the JSON document to a string
String datamqtt;
serializeJson(doc, datamqtt);
mqttClient.beginMessage(topic);
mqttClient.print(datamqtt);
mqttClient.endMessage();
}
}
void TaskBLEScan(void *pvParameters) // This is a task.
{
(void) pvParameters;
unsigned long currentMillis = millis();
for (;;) // A Task shall never return or exit.
{
if (currentMillis - previousScanMillis >= scanDurationMs){
BLEScanResults foundDevices = pBLEScan->start(SCAN_DURATION_MS); // Adjust scan time as needed
// Process detected devices
int maxRssiIndex = -1;
int maxRssi = INT_MIN; // Initialize with minimum possible value
for (int i = 0; i < numDevices; i++) {
if (devices[i].rssi > MIN_RSSI_THRESHOLD && devices[i].rssi > maxRssi){
maxRssi = devices[i].rssi;
maxRssiIndex = i;
}
}
if (maxRssiIndex != -1) {
Serial.print("Device Nearby: ");
hostnameFounded1 = devices[maxRssiIndex].hostnameFounded;
Serial.println(hostnameFounded1);
Serial.print("RSSI: ");
blerssivalue = devices[maxRssiIndex].rssi;
Serial.println(blerssivalue);
WebSerial.println("The Device ID Founded:");
WebSerial.print(hostnameFounded1);
WebSerial.println("Device Founded BLE RSSI: ");
WebSerial.print(blerssivalue);
}
wifirssivalue = WiFi.RSSI();
WebSerial.println("My WiFi RSSI is:");
WebSerial.print(wifirssivalue);
pBLEScan->stop();
vTaskDelay(100);
}
numDevices = 0; // Clear detected devices for next scan
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
vTaskDelay(scanDurationMs);
}
}
void TaskOTAUpdate(void *pvParameters) // This is a task.
{
(void) pvParameters;
previousOTAMillis = millis();
for (;;) // A Task shall never return or exit.
{
if (millis() - previousScanMillis >= OTA_INTERVAL)
{
ElegantOTA.loop();
previousOTAMillis = millis();
}
vTaskDelay(1000);
}
}
Hi, Sorry for posting the code delayed, This code get compiled and working, but the problem arises only when required OTA update or viewing data in webserial, the webserver gets hanged and device gets restarted. Unable to do OTA update the time delays are not working as expected. Please give your suggestion to make OTA and WebSerial working smoothly without the interference of BLE Advertising and Scanning Thanks
I have tried with ESP32 board with 8MB flash, the rebooting of device is happening, OTA or Webserial web server not accessible during the attempting OTA or WebSerial the devices reboots showing Guru Mediation panicked, Still not finding best method such all the WiFi / MQTT / BLE scan and advertise / OTA / WebSerial all working smoothly, Note with 8MB flash the program Sketch uses 1505798 bytes (45%) of program storage space. Maximum is 3342336 bytes.
Global variables use 52168 bytes (15%) of dynamic memory, leaving 275512 bytes for local variables. Maximum is 327680 bytes. Please give me your suggestion to handle the tasks efficiently
@qaunta_ai Are you the same person as @aimmass ? Why did you changed the nickname?
Yes yes it same person, I changed it to my email ID name so that I can track with my mail too
My understanding is that ESP32 has one radio. You can run WiFi or you can run Blue Tooth, but not both simultaneously. Is that understanding incorrect?
No, I have posted a code, it works perfect with Wi-Fi connected and BLE signal strength can be viewed too using WebSerial but when it comes to OTA or even WebSerial sometimes the device gets restarted, as the device acts both as BLE advertise and scan the RF module has interference otherwise only with BLE advertiser or Scan there is no issue in handling BLE and Wi-Fi and it coexists
That is until you try to do something that's data-intensive (like OTA or a streaming web page). A thread that is probably worth reading:
https://www.esp32.com/viewtopic.php?f=13&t=6707
Recalling someone having 'informed me' that it's not "either or".
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.