Het Meerdere Bluetooth Apps voorbeeld laat zien hoe u meerdere Bluetooth app-interfaces kunt combineren in één ESP32-project. Laat Monitor, Chat, Slider, Joystick, Temperature, Plotter, Table, Analog Gauge en Rotator tegelijkertijd draaien — toegankelijk via de DIYables Bluetooth STEM app. Ontworpen voor ESP32 boards met ondersteuning voor zowel BLE (Bluetooth Low Energy) als Classic Bluetooth verbindingen. Ideaal voor complexe projecten die meerdere besturings- en display-interfaces tegelijk nodig hebben.
Dit voorbeeld ondersteunt twee Bluetooth-modi:
ESP32 BLE (Bluetooth Low Energy): Werkt op zowel Android als iOS
ESP32 Classic Bluetooth: Werkt alleen op Android. iOS ondersteunt Classic Bluetooth niet. Gebruik BLE als u iOS-ondersteuning nodig hebt.
Volg deze instructies stap voor stap:
Verbind de ESP32 met uw computer via een USB-kabel.
Start de Arduino IDE op uw computer.
Selecteer het juiste ESP32 board en de COM-poort.
Ga naar het Libraries-icoon in de linkerzijbalk van Arduino IDE.
Zoek op "DIYables Bluetooth" en vind de DIYables Bluetooth bibliotheek van DIYables.
Klik op de Install-knop om de bibliotheek te installeren.
> Belangrijk: Omdat dit voorbeeld veel Bluetooth app-bibliotheken bevat, is het gecompileerde programma groter dan normaal. U moet het juiste partititie-schema selecteren (zie hieronder).
Kies een van de twee Bluetooth-modi afhankelijk van uw behoefte:
Opmerking: Classic Bluetooth wordt NIET ondersteund op iOS. Voor iOS-ondersteuning gebruikt u de BLE-code hieronder.
#include <DIYables_BluetoothServer.h>
#include <DIYables_BluetoothMonitor.h>
#include <DIYables_BluetoothChat.h>
#include <DIYables_BluetoothSlider.h>
#include <DIYables_BluetoothJoystick.h>
#include <DIYables_BluetoothTemperature.h>
#include <DIYables_BluetoothPlotter.h>
#include <DIYables_BluetoothTable.h>
#include <DIYables_BluetoothAnalogGauge.h>
#include <DIYables_BluetoothRotator.h>
#include <platforms/DIYables_Esp32Bluetooth.h>
DIYables_Esp32Bluetooth bluetooth("ESP32 Multi-App");
DIYables_BluetoothServer bluetoothServer(bluetooth);
DIYables_BluetoothMonitor bluetoothMonitor;
DIYables_BluetoothChat bluetoothChat;
DIYables_BluetoothSlider bluetoothSlider(0, 255, 1);
DIYables_BluetoothJoystick bluetoothJoystick(false, 5);
DIYables_BluetoothTemperature bluetoothTemperature(-10.0, 50.0, "°C");
DIYables_BluetoothPlotter bluetoothPlotter;
DIYables_BluetoothTable bluetoothTable;
DIYables_BluetoothAnalogGauge bluetoothGauge(0.0, 100.0, "%");
DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_CONTINUOUS);
const int LED_PIN = 2;
int currentSlider1 = 128;
int currentSlider2 = 64;
int currentJoystickX = 0;
int currentJoystickY = 0;
float currentTemperature = 25.0;
float currentGaugeValue = 50.0;
float currentRotatorAngle = 0.0;
int messageCount = 0;
unsigned long lastMonitorUpdate = 0;
unsigned long lastTempUpdate = 0;
unsigned long lastPlotUpdate = 0;
unsigned long lastTableUpdate = 0;
unsigned long lastGaugeUpdate = 0;
float plotPhase = 0;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("DIYables Bluetooth - ESP32 Multiple Apps Example");
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
bluetoothServer.begin();
bluetoothServer.addApp(&bluetoothMonitor);
bluetoothServer.addApp(&bluetoothChat);
bluetoothServer.addApp(&bluetoothSlider);
bluetoothServer.addApp(&bluetoothJoystick);
bluetoothServer.addApp(&bluetoothTemperature);
bluetoothServer.addApp(&bluetoothPlotter);
bluetoothServer.addApp(&bluetoothTable);
bluetoothServer.addApp(&bluetoothGauge);
bluetoothServer.addApp(&bluetoothRotator);
Serial.print("Registered apps: ");
Serial.println(bluetoothServer.getAppCount());
bluetoothPlotter.setPlotTitle("Sensor Data");
bluetoothPlotter.setAxisLabels("Time", "Value");
bluetoothPlotter.setYAxisRange(-1.5, 1.5);
bluetoothPlotter.setMaxSamples(100);
bluetoothPlotter.setLegendLabels("Sine", "Cosine", "Random");
bluetoothTable.addRow("Status");
bluetoothTable.addRow("Uptime");
bluetoothTable.addRow("Slider 1");
bluetoothTable.addRow("Slider 2");
bluetoothTable.addRow("Joystick X");
bluetoothTable.addRow("Joystick Y");
bluetoothTable.addRow("Temperature");
bluetoothTable.addRow("Gauge Value");
bluetoothTable.addRow("Rotator Angle");
bluetoothTable.addRow("Free Heap");
setupCallbacks();
Serial.println("Waiting for Bluetooth connection...");
}
void setupCallbacks() {
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
digitalWrite(LED_PIN, HIGH);
bluetoothMonitor.send("=== ESP32 Multi-App Connected ===");
bluetoothMonitor.send("All apps are ready!");
bluetoothChat.send("Hello! ESP32 Multi-App is connected.");
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
digitalWrite(LED_PIN, LOW);
});
bluetoothMonitor.onMonitorMessage([](const String& message) {
Serial.println("Monitor cmd: " + message);
if (message == "HELP") {
bluetoothMonitor.send("Commands: STATUS, HELP, LED_ON, LED_OFF, HEAP");
} else if (message == "STATUS") {
bluetoothMonitor.send("Slider1=" + String(currentSlider1) + " Slider2=" + String(currentSlider2));
bluetoothMonitor.send("Joystick X=" + String(currentJoystickX) + " Y=" + String(currentJoystickY));
bluetoothMonitor.send("Temp=" + String(currentTemperature, 1) + "°C");
bluetoothMonitor.send("Gauge=" + String(currentGaugeValue, 1) + "%");
bluetoothMonitor.send("Rotator=" + String(currentRotatorAngle, 0) + "°");
} else if (message == "LED_ON") {
digitalWrite(LED_PIN, HIGH);
bluetoothMonitor.send("LED turned ON");
} else if (message == "LED_OFF") {
digitalWrite(LED_PIN, LOW);
bluetoothMonitor.send("LED turned OFF");
} else if (message == "HEAP") {
bluetoothMonitor.send("Free Heap: " + String(ESP.getFreeHeap()) + " bytes");
} else {
bluetoothMonitor.send("Unknown: " + message + " (type HELP)");
}
});
bluetoothChat.onChatMessage([](const String& message) {
Serial.println("Chat: " + message);
bluetoothChat.send("Echo: " + message);
if (message.equalsIgnoreCase("ping")) {
bluetoothChat.send("pong!");
} else if (message.equalsIgnoreCase("status")) {
bluetoothChat.send("Uptime: " + String(millis() / 1000) + "s, Apps: " + String(bluetoothServer.getAppCount()));
} else if (message.equalsIgnoreCase("heap")) {
bluetoothChat.send("Free heap: " + String(ESP.getFreeHeap()) + " bytes");
}
});
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
Serial.print("Slider 1: "); Serial.print(slider1);
Serial.print(", Slider 2: "); Serial.println(slider2);
currentGaugeValue = map(slider1, 0, 255, 0, 100);
bluetoothGauge.send(currentGaugeValue);
bluetoothTable.sendValueUpdate("Slider 1", String(slider1));
bluetoothTable.sendValueUpdate("Slider 2", String(slider2));
bluetoothTable.sendValueUpdate("Gauge Value", String(currentGaugeValue, 1) + "%");
});
bluetoothSlider.onGetConfig([]() {
bluetoothSlider.send(currentSlider1, currentSlider2);
});
bluetoothJoystick.onJoystickValue([](int x, int y) {
currentJoystickX = x;
currentJoystickY = y;
Serial.print("Joystick X: "); Serial.print(x);
Serial.print(", Y: "); Serial.println(y);
bluetoothTable.sendValueUpdate("Joystick X", String(x));
bluetoothTable.sendValueUpdate("Joystick Y", String(y));
});
bluetoothJoystick.onGetConfig([]() {
bluetoothJoystick.send(currentJoystickX, currentJoystickY);
});
bluetoothTemperature.onTemperatureRequest([]() {
bluetoothTemperature.send(currentTemperature);
});
bluetoothPlotter.onDataRequest([]() {
Serial.println("Plotter data requested");
});
bluetoothTable.onDataRequest([]() {
Serial.println("Table data requested");
bluetoothTable.sendTableStructure();
updateAllTableValues();
});
bluetoothGauge.onValueRequest([]() {
bluetoothGauge.send(currentGaugeValue);
});
bluetoothRotator.onRotatorAngle([](float angle) {
currentRotatorAngle = angle;
Serial.print("Rotator: "); Serial.print(angle); Serial.println("°");
bluetoothTable.sendValueUpdate("Rotator Angle", String(angle, 0) + "°");
});
}
void updateAllTableValues() {
bluetoothTable.sendValueUpdate("Status", "Running");
unsigned long uptime = millis() / 1000;
String uptimeStr;
if (uptime >= 60) {
uptimeStr = String(uptime / 60) + "m " + String(uptime % 60) + "s";
} else {
uptimeStr = String(uptime) + "s";
}
bluetoothTable.sendValueUpdate("Uptime", uptimeStr);
bluetoothTable.sendValueUpdate("Slider 1", String(currentSlider1));
bluetoothTable.sendValueUpdate("Slider 2", String(currentSlider2));
bluetoothTable.sendValueUpdate("Joystick X", String(currentJoystickX));
bluetoothTable.sendValueUpdate("Joystick Y", String(currentJoystickY));
bluetoothTable.sendValueUpdate("Temperature", String(currentTemperature, 1) + " °C");
bluetoothTable.sendValueUpdate("Gauge Value", String(currentGaugeValue, 1) + "%");
bluetoothTable.sendValueUpdate("Rotator Angle", String(currentRotatorAngle, 0) + "°");
bluetoothTable.sendValueUpdate("Free Heap", String(ESP.getFreeHeap()) + " bytes");
}
void loop() {
bluetoothServer.loop();
if (!bluetooth.isConnected()) {
delay(10);
return;
}
if (millis() - lastMonitorUpdate >= 5000) {
lastMonitorUpdate = millis();
messageCount++;
bluetoothMonitor.send("[INFO] Heartbeat #" + String(messageCount) + " - Uptime: " + String(millis() / 1000) + "s");
}
if (millis() - lastTempUpdate >= 2000) {
lastTempUpdate = millis();
static float tempOffset = 0;
tempOffset += random(-10, 11) / 10.0;
if (tempOffset > 5.0) tempOffset = 5.0;
if (tempOffset < -5.0) tempOffset = -5.0;
currentTemperature = 25.0 + tempOffset;
bluetoothTemperature.send(currentTemperature);
bluetoothTable.sendValueUpdate("Temperature", String(currentTemperature, 1) + " °C");
}
if (millis() - lastPlotUpdate >= 100) {
lastPlotUpdate = millis();
float sine = sin(plotPhase);
float cosine = cos(plotPhase);
float noise = random(-50, 51) / 100.0;
bluetoothPlotter.send(sine, cosine, noise);
plotPhase += 0.1;
if (plotPhase > 2 * PI) plotPhase = 0;
}
if (millis() - lastTableUpdate >= 5000) {
lastTableUpdate = millis();
unsigned long uptime = millis() / 1000;
String uptimeStr;
if (uptime >= 60) {
uptimeStr = String(uptime / 60) + "m " + String(uptime % 60) + "s";
} else {
uptimeStr = String(uptime) + "s";
}
bluetoothTable.sendValueUpdate("Uptime", uptimeStr);
bluetoothTable.sendValueUpdate("Free Heap", String(ESP.getFreeHeap()) + " bytes");
}
if (millis() - lastGaugeUpdate >= 3000) {
lastGaugeUpdate = millis();
float sensorValue = 50.0 + 30.0 * sin(millis() / 10000.0);
currentGaugeValue = sensorValue;
bluetoothGauge.send(currentGaugeValue);
bluetoothTable.sendValueUpdate("Gauge Value", String(currentGaugeValue, 1) + "%");
}
delay(10);
}
Belangrijk: Ga naar Tools > Partition Scheme en selecteer "Huge APP (3MB No OTA/1MB SPIFFS)". Dit is verplicht omdat het meerdere apps voorbeeld aanzienlijk meer flashgeheugen nodig heeft.
Klik op de Upload-knop in Arduino IDE om de code naar ESP32 te uploaden
Open de Serial Monitor
Bekijk het resultaat in de Serial Monitor. Het ziet eruit als het volgende:
DIYables Bluetooth - ESP32 Multiple Apps Example
Waiting for Bluetooth connection...
#include <DIYables_BluetoothServer.h>
#include <DIYables_BluetoothMonitor.h>
#include <DIYables_BluetoothChat.h>
#include <DIYables_BluetoothSlider.h>
#include <DIYables_BluetoothJoystick.h>
#include <DIYables_BluetoothTemperature.h>
#include <DIYables_BluetoothPlotter.h>
#include <DIYables_BluetoothTable.h>
#include <DIYables_BluetoothAnalogGauge.h>
#include <DIYables_BluetoothRotator.h>
#include <platforms/DIYables_Esp32BLE.h>
const char* DEVICE_NAME = "ESP32BLE Multi-App";
const char* SERVICE_UUID = "19B10000-E8F2-537E-4F6C-D104768A1214";
const char* TX_UUID = "19B10001-E8F2-537E-4F6C-D104768A1214";
const char* RX_UUID = "19B10002-E8F2-537E-4F6C-D104768A1214";
DIYables_Esp32BLE bluetooth(DEVICE_NAME, SERVICE_UUID, TX_UUID, RX_UUID);
DIYables_BluetoothServer bluetoothServer(bluetooth);
DIYables_BluetoothMonitor bluetoothMonitor;
DIYables_BluetoothChat bluetoothChat;
DIYables_BluetoothSlider bluetoothSlider(0, 255, 1);
DIYables_BluetoothJoystick bluetoothJoystick(false, 5);
DIYables_BluetoothTemperature bluetoothTemperature(-10.0, 50.0, "°C");
DIYables_BluetoothPlotter bluetoothPlotter;
DIYables_BluetoothTable bluetoothTable;
DIYables_BluetoothAnalogGauge bluetoothGauge(0.0, 100.0, "%");
DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_CONTINUOUS);
int currentSlider1 = 128;
int currentSlider2 = 64;
int currentJoystickX = 0;
int currentJoystickY = 0;
float currentTemperature = 25.0;
float currentGaugeValue = 50.0;
float currentRotatorAngle = 0.0;
int messageCount = 0;
unsigned long lastMonitorUpdate = 0;
unsigned long lastTempUpdate = 0;
unsigned long lastPlotUpdate = 0;
unsigned long lastTableUpdate = 0;
unsigned long lastGaugeUpdate = 0;
float plotPhase = 0;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("DIYables Bluetooth - ESP32 BLE Multiple Apps Example");
pinMode(2, OUTPUT);
digitalWrite(2, LOW);
bluetoothServer.begin();
bluetoothServer.addApp(&bluetoothMonitor);
bluetoothServer.addApp(&bluetoothChat);
bluetoothServer.addApp(&bluetoothSlider);
bluetoothServer.addApp(&bluetoothJoystick);
bluetoothServer.addApp(&bluetoothTemperature);
bluetoothServer.addApp(&bluetoothPlotter);
bluetoothServer.addApp(&bluetoothTable);
bluetoothServer.addApp(&bluetoothGauge);
bluetoothServer.addApp(&bluetoothRotator);
Serial.print("Registered apps: ");
Serial.println(bluetoothServer.getAppCount());
bluetoothPlotter.setPlotTitle("Sensor Data");
bluetoothPlotter.setAxisLabels("Time", "Value");
bluetoothPlotter.setYAxisRange(-1.5, 1.5);
bluetoothPlotter.setMaxSamples(100);
bluetoothPlotter.setLegendLabels("Sine", "Cosine", "Random");
bluetoothTable.addRow("Status");
bluetoothTable.addRow("Uptime");
bluetoothTable.addRow("Slider 1");
bluetoothTable.addRow("Slider 2");
bluetoothTable.addRow("Joystick X");
bluetoothTable.addRow("Joystick Y");
bluetoothTable.addRow("Temperature");
bluetoothTable.addRow("Gauge Value");
bluetoothTable.addRow("Rotator Angle");
bluetoothTable.addRow("Messages");
setupCallbacks();
Serial.println("Waiting for Bluetooth connection...");
}
void setupCallbacks() {
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
digitalWrite(2, HIGH);
bluetoothMonitor.send("=== ESP32 BLE Multi-App Connected ===");
bluetoothMonitor.send("All apps are ready!");
bluetoothChat.send("Hello! ESP32 BLE Multi-App is connected.");
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
digitalWrite(2, LOW);
});
bluetoothMonitor.onMonitorMessage([](const String& message) {
Serial.println("Monitor cmd: " + message);
if (message == "HELP") {
bluetoothMonitor.send("Commands: STATUS, HELP, LED_ON, LED_OFF, HEAP");
} else if (message == "STATUS") {
bluetoothMonitor.send("Slider1=" + String(currentSlider1) + " Slider2=" + String(currentSlider2));
bluetoothMonitor.send("Joystick X=" + String(currentJoystickX) + " Y=" + String(currentJoystickY));
bluetoothMonitor.send("Temp=" + String(currentTemperature, 1) + "°C");
bluetoothMonitor.send("Gauge=" + String(currentGaugeValue, 1) + "%");
bluetoothMonitor.send("Rotator=" + String(currentRotatorAngle, 0) + "°");
} else if (message == "LED_ON") {
digitalWrite(2, HIGH);
bluetoothMonitor.send("LED turned ON");
} else if (message == "LED_OFF") {
digitalWrite(2, LOW);
bluetoothMonitor.send("LED turned OFF");
} else if (message == "HEAP") {
bluetoothMonitor.send("Free heap: " + String(ESP.getFreeHeap()) + " bytes");
} else {
bluetoothMonitor.send("Unknown: " + message + " (type HELP)");
}
});
bluetoothChat.onChatMessage([](const String& message) {
Serial.println("Chat: " + message);
bluetoothChat.send("Echo: " + message);
if (message.equalsIgnoreCase("ping")) {
bluetoothChat.send("pong!");
} else if (message.equalsIgnoreCase("status")) {
bluetoothChat.send("Uptime: " + String(millis() / 1000) + "s, Apps: " + String(bluetoothServer.getAppCount()));
}
});
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
Serial.print("Slider 1: "); Serial.print(slider1);
Serial.print(", Slider 2: "); Serial.println(slider2);
currentGaugeValue = map(slider1, 0, 255, 0, 100);
bluetoothGauge.send(currentGaugeValue);
bluetoothTable.sendValueUpdate("Slider 1", String(slider1));
bluetoothTable.sendValueUpdate("Slider 2", String(slider2));
bluetoothTable.sendValueUpdate("Gauge Value", String(currentGaugeValue, 1) + "%");
});
bluetoothSlider.onGetConfig([]() {
bluetoothSlider.send(currentSlider1, currentSlider2);
});
bluetoothJoystick.onJoystickValue([](int x, int y) {
currentJoystickX = x;
currentJoystickY = y;
Serial.print("Joystick X: "); Serial.print(x);
Serial.print(", Y: "); Serial.println(y);
bluetoothTable.sendValueUpdate("Joystick X", String(x));
bluetoothTable.sendValueUpdate("Joystick Y", String(y));
});
bluetoothJoystick.onGetConfig([]() {
bluetoothJoystick.send(currentJoystickX, currentJoystickY);
});
bluetoothTemperature.onTemperatureRequest([]() {
bluetoothTemperature.send(currentTemperature);
});
bluetoothPlotter.onDataRequest([]() {
Serial.println("Plotter data requested");
});
bluetoothTable.onDataRequest([]() {
Serial.println("Table data requested");
bluetoothTable.sendTableStructure();
updateAllTableValues();
});
bluetoothGauge.onValueRequest([]() {
bluetoothGauge.send(currentGaugeValue);
});
bluetoothRotator.onRotatorAngle([](float angle) {
currentRotatorAngle = angle;
Serial.print("Rotator: "); Serial.print(angle); Serial.println("°");
bluetoothTable.sendValueUpdate("Rotator Angle", String(angle, 0) + "°");
});
}
void updateAllTableValues() {
bluetoothTable.sendValueUpdate("Status", "Running");
unsigned long uptime = millis() / 1000;
String uptimeStr;
if (uptime >= 60) {
uptimeStr = String(uptime / 60) + "m " + String(uptime % 60) + "s";
} else {
uptimeStr = String(uptime) + "s";
}
bluetoothTable.sendValueUpdate("Uptime", uptimeStr);
bluetoothTable.sendValueUpdate("Slider 1", String(currentSlider1));
bluetoothTable.sendValueUpdate("Slider 2", String(currentSlider2));
bluetoothTable.sendValueUpdate("Joystick X", String(currentJoystickX));
bluetoothTable.sendValueUpdate("Joystick Y", String(currentJoystickY));
bluetoothTable.sendValueUpdate("Temperature", String(currentTemperature, 1) + " °C");
bluetoothTable.sendValueUpdate("Gauge Value", String(currentGaugeValue, 1) + "%");
bluetoothTable.sendValueUpdate("Rotator Angle", String(currentRotatorAngle, 0) + "°");
bluetoothTable.sendValueUpdate("Messages", String(messageCount));
}
void loop() {
bluetoothServer.loop();
if (!bluetooth.isConnected()) {
delay(10);
return;
}
if (millis() - lastMonitorUpdate >= 5000) {
lastMonitorUpdate = millis();
messageCount++;
bluetoothMonitor.send("[INFO] Heartbeat #" + String(messageCount) + " - Uptime: " + String(millis() / 1000) + "s");
}
if (millis() - lastTempUpdate >= 2000) {
lastTempUpdate = millis();
static float tempOffset = 0;
tempOffset += random(-10, 11) / 10.0;
if (tempOffset > 5.0) tempOffset = 5.0;
if (tempOffset < -5.0) tempOffset = -5.0;
currentTemperature = 25.0 + tempOffset;
bluetoothTemperature.send(currentTemperature);
bluetoothTable.sendValueUpdate("Temperature", String(currentTemperature, 1) + " °C");
}
if (millis() - lastPlotUpdate >= 100) {
lastPlotUpdate = millis();
float sine = sin(plotPhase);
float cosine = cos(plotPhase);
float noise = random(-50, 51) / 100.0;
bluetoothPlotter.send(sine, cosine, noise);
plotPhase += 0.1;
if (plotPhase > 2 * PI) plotPhase = 0;
}
if (millis() - lastTableUpdate >= 5000) {
lastTableUpdate = millis();
unsigned long uptime = millis() / 1000;
String uptimeStr;
if (uptime >= 60) {
uptimeStr = String(uptime / 60) + "m " + String(uptime % 60) + "s";
} else {
uptimeStr = String(uptime) + "s";
}
bluetoothTable.sendValueUpdate("Uptime", uptimeStr);
bluetoothTable.sendValueUpdate("Messages", String(messageCount));
}
if (millis() - lastGaugeUpdate >= 3000) {
lastGaugeUpdate = millis();
float sensorValue = 50.0 + 30.0 * sin(millis() / 10000.0);
currentGaugeValue = sensorValue;
bluetoothGauge.send(currentGaugeValue);
bluetoothTable.sendValueUpdate("Gauge Value", String(currentGaugeValue, 1) + "%");
}
delay(10);
}
Belangrijk: Ga naar Tools > Partition Scheme en selecteer "Huge APP (3MB No OTA/1MB SPIFFS)". Dit is verplicht omdat het meerdere apps voorbeeld aanzienlijk meer flashgeheugen nodig heeft.
Klik op de Upload-knop in Arduino IDE om de code naar ESP32 te uploaden
Open de Serial Monitor
Bekijk het resultaat in de Serial Monitor. Het ziet eruit als het volgende:
DIYables Bluetooth - ESP32 BLE Multiple Apps Example
Waiting for Bluetooth connection...
Installeer de DIYables Bluetooth App op uw smartphone:
Android |
iOS
Als u de ESP32 Classic Bluetooth code gebruikt, moet u de ESP32 eerst koppelen met uw Android-telefoon voordat u de app opent:
Ga naar Instellingen > Bluetooth op uw telefoon
Zorg dat Bluetooth ingeschakeld is
Uw telefoon zoekt nu naar beschikbare apparaten
Zoek en tik op "ESP32 Multi-App" in de lijst met beschikbare apparaten
Bevestig het koppelverzoek (geen PIN vereist)
Wacht totdat onder de apparaatnaam "Gepaired" wordt weergegeven
Als u de ESP32 BLE code gebruikt, is koppelen niet nodig. Ga direct door naar de volgende stap.
Open de DIYables Bluetooth App
Bij het eerste gebruik vraagt de app om toestemming. Verleen alstublieft:
Nearby Devices toestemming (Android 12+) / Bluetooth toestemming (iOS) - nodig om te scannen en verbinding te maken met Bluetooth-apparaten
Locatie toestemming (alleen Android 11 en lager) - vereist voor oudere Android-versies om naar BLE-apparaten te scannen
Zorg dat Bluetooth aan staat op uw telefoon
Tik op het startscherm op de Connect-knop. De app scant voor zowel BLE als Classic Bluetooth apparaten.

Zoek uw apparaat in de scanresultaten en tik om te verbinden:
Na verbinden gaat de app automatisch terug naar het startscherm. Het startscherm toont alle beschikbare apps. De 9 apps die in de Arduino-code zijn geïnitialiseerd reageren en werken — andere apps worden getoond maar functioneren niet met deze sketch.
Opmerking: U kunt op het instellingen-icoon op het startscherm tikken om apps te verbergen/tonen. Zie de DIYables Bluetooth App Gebruikershandleiding voor meer details.
Tik op een van de volgende apps om open te gaan en te communiceren met de ESP32: Monitor, Chat, Slider, Joystick, Temperature, Plotter, Table, Analog Gauge, Rotator
Wissel vrij tussen apps — ze delen allemaal dezelfde Bluetooth-verbinding
Kijk nu terug naar de Serial Monitor in Arduino IDE. U ziet:
Bluetooth connected!
Monitor: Uptime: 5s | Free heap: 245780 bytes
Temperature: 25.3°C
Plotter values sent
Table values updated
Gauge value: 50.0
Elke app wordt gemaakt als een afzonderlijk object en geregistreerd bij dezelfde Bluetooth-server. Ze delen de enkele Bluetooth-verbinding maar werken onafhankelijk:
#include <DIYables_BluetoothMonitor.h>
#include <DIYables_BluetoothChat.h>
#include <DIYables_BluetoothSlider.h>
#include <DIYables_BluetoothJoystick.h>
#include <DIYables_BluetoothTemperature.h>
#include <DIYables_BluetoothPlotter.h>
#include <DIYables_BluetoothTable.h>
#include <DIYables_BluetoothAnalogGauge.h>
#include <DIYables_BluetoothRotator.h>
DIYables_BluetoothMonitor bluetoothMonitor;
DIYables_BluetoothChat bluetoothChat;
DIYables_BluetoothSlider bluetoothSlider(0, 100, 1);
DIYables_BluetoothJoystick bluetoothJoystick;
DIYables_BluetoothTemperature bluetoothTemperature(-10.0, 50.0, "°C");
DIYables_BluetoothPlotter bluetoothPlotter;
DIYables_BluetoothTable bluetoothTable;
DIYables_BluetoothAnalogGauge bluetoothGauge(0.0, 100.0, "km/h");
DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_LIMITED, 0, 180);
bluetoothServer.addApp(bluetoothMonitor);
bluetoothServer.addApp(bluetoothChat);
bluetoothServer.addApp(bluetoothSlider);
bluetoothServer.addApp(bluetoothJoystick);
bluetoothServer.addApp(bluetoothTemperature);
bluetoothServer.addApp(bluetoothPlotter);
bluetoothServer.addApp(bluetoothTable);
bluetoothServer.addApp(bluetoothGauge);
bluetoothServer.addApp(bluetoothRotator);
Elke app heeft eigen event handlers:
void setup() {
bluetoothMonitor.onMonitorMessage([](String message) {
Serial.println("Monitor received: " + message);
});
bluetoothChat.onChatMessage([](String message) {
Serial.println("Chat: " + message);
bluetoothChat.send("Echo: " + message);
});
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
Serial.println("Slider: " + String(slider1));
});
bluetoothJoystick.onJoystickValue([](int x, int y) {
Serial.println("Joystick: X=" + String(x) + " Y=" + String(y));
});
bluetoothRotator.onRotatorAngle([](float angle) {
Serial.println("Rotator: " + String(angle) + "°");
});
}
Elke app kan zijn eigen update-timing hebben:
void loop() {
bluetoothServer.loop();
unsigned long now = millis();
static unsigned long lastMonitor = 0;
if (now - lastMonitor >= 5000) {
lastMonitor = now;
bluetoothMonitor.send("Uptime: " + String(now / 1000) + "s");
}
static unsigned long lastTemp = 0;
if (now - lastTemp >= 2000) {
lastTemp = now;
bluetoothTemperature.send(readTemperature());
}
static unsigned long lastPlotter = 0;
if (now - lastPlotter >= 100) {
lastPlotter = now;
bluetoothPlotter.send(readSensorValue());
}
static unsigned long lastTable = 0;
if (now - lastTable >= 5000) {
lastTable = now;
updateTableValues();
}
static unsigned long lastGauge = 0;
if (now - lastGauge >= 3000) {
lastGauge = now;
bluetoothGauge.send(readGaugeValue());
}
delay(10);
}
U hoeft niet alle 9 apps te gebruiken. Kies alleen degene die u nodig heeft:
#include <DIYables_BluetoothMonitor.h>
#include <DIYables_BluetoothSlider.h>
#include <DIYables_BluetoothTemperature.h>
DIYables_BluetoothMonitor bluetoothMonitor;
DIYables_BluetoothSlider bluetoothSlider(0, 100, 1);
DIYables_BluetoothTemperature bluetoothTemperature(-10.0, 50.0, "°C");
void setup() {
bluetoothServer.addApp(bluetoothMonitor);
bluetoothServer.addApp(bluetoothSlider);
bluetoothServer.addApp(bluetoothTemperature);
}
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
bluetoothTemperature.send(currentTemperature);
bluetoothGauge.send(currentGaugeValue);
bluetoothRotator.send(currentAngle);
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
});
In de DIYables Bluetooth App:
Op het startscherm ziet u alle geregistreerde apps als knoppen
Tik op een app om deze te openen
Gebruik de terugknop of home-knop om terug te keren en een andere app te kiezen
Alle apps blijven draaien op de ESP32, ongeacht welke app zichtbaar is
Input Apps (Slider, Joystick, Rotator, Chat): Sturen data van telefoon naar ESP32
Output Apps (Monitor, Temperature, Plotter, Table, Gauge): Sturen data van ESP32 naar telefoon
Bidirectionele Apps (Chat, Monitor): Kunnen data versturen en ontvangen
DIYables_BluetoothTemperature bluetoothTemperature(-10.0, 50.0, "°C");
DIYables_BluetoothTable bluetoothTable;
DIYables_BluetoothPlotter bluetoothPlotter;
DIYables_BluetoothMonitor bluetoothMonitor;
void setup() {
bluetoothTable.addRow("Temperature");
bluetoothTable.addRow("Humidity");
bluetoothTable.addRow("Pressure");
bluetoothTable.addRow("Wind Speed");
bluetoothTable.addRow("Rain");
bluetoothPlotter.setPlotTitle("Weather Trends");
bluetoothPlotter.setLegendLabels("Temp", "Humidity", "Pressure");
}
void loop() {
bluetoothServer.loop();
static unsigned long lastUpdate = 0;
if (millis() - lastUpdate >= 2000) {
lastUpdate = millis();
float temp = readTemperature();
float hum = readHumidity();
float press = readPressure();
bluetoothTemperature.send(temp);
bluetoothTable.sendValueUpdate("Temperature", String(temp, 1) + " °C");
bluetoothTable.sendValueUpdate("Humidity", String(hum, 0) + "%");
bluetoothTable.sendValueUpdate("Pressure", String(press, 0) + " hPa");
bluetoothPlotter.send(temp, hum, press / 10.0);
bluetoothMonitor.send("Weather update: " + String(temp, 1) + "°C, " + String(hum, 0) + "%, " + String(press, 0) + "hPa");
}
delay(10);
}
DIYables_BluetoothJoystick bluetoothJoystick;
DIYables_BluetoothSlider bluetoothSlider(0, 100, 5);
DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_LIMITED, 0, 180);
DIYables_BluetoothMonitor bluetoothMonitor;
DIYables_BluetoothAnalogGauge bluetoothGauge(0.0, 100.0, "%");
int maxSpeed = 50;
void setup() {
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
maxSpeed = slider1;
bluetoothMonitor.send("Max speed set to: " + String(maxSpeed) + "%");
});
bluetoothJoystick.onJoystickValue([](int x, int y) {
int leftMotor = constrain(y + x, -maxSpeed, maxSpeed);
int rightMotor = constrain(y - x, -maxSpeed, maxSpeed);
setMotors(leftMotor, rightMotor);
bluetoothMonitor.send("Motors: L=" + String(leftMotor) + " R=" + String(rightMotor));
});
bluetoothRotator.onRotatorAngle([](float angle) {
setArmAngle((int)angle);
bluetoothMonitor.send("Arm angle: " + String((int)angle) + "°");
});
}
void loop() {
bluetoothServer.loop();
static unsigned long lastBattery = 0;
if (millis() - lastBattery >= 10000) {
lastBattery = millis();
float battery = readBatteryLevel();
bluetoothGauge.send(battery);
}
delay(10);
}
DIYables_BluetoothChat bluetoothChat;
DIYables_BluetoothSlider bluetoothSlider(0, 100, 1);
DIYables_BluetoothTable bluetoothTable;
DIYables_BluetoothTemperature bluetoothTemperature(10.0, 40.0, "°C");
DIYables_BluetoothMonitor bluetoothMonitor;
void setup() {
bluetoothTable.addRow("Living Room Light");
bluetoothTable.addRow("Bedroom Light");
bluetoothTable.addRow("AC Status");
bluetoothTable.addRow("Door Lock");
bluetoothTable.addRow("Security");
bluetoothChat.onChatMessage([](String message) {
message.toLowerCase();
if (message == "lights on") {
setLights(true);
bluetoothChat.send("Lights turned ON");
bluetoothTable.sendValueUpdate("Living Room Light", "ON ✓");
} else if (message == "lights off") {
setLights(false);
bluetoothChat.send("Lights turned OFF");
bluetoothTable.sendValueUpdate("Living Room Light", "OFF ✗");
} else if (message == "status") {
bluetoothChat.send("Temp: " + String(readTemperature(), 1) + "°C");
bluetoothChat.send("All systems normal");
}
bluetoothMonitor.send("[CMD] " + message);
});
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
setDimmer(slider1);
bluetoothMonitor.send("[DIMMER] Set to " + String(slider1) + "%");
});
}
Gebruik data van de ene app om een andere bij te werken:
float posX = 0, posY = 0;
bluetoothJoystick.onJoystickValue([](int x, int y) {
posX += x * 0.1;
posY += y * 0.1;
bluetoothPlotter.send(posX, posY);
bluetoothTable.sendValueUpdate("Position X", String(posX, 1));
bluetoothTable.sendValueUpdate("Position Y", String(posY, 1));
bluetoothMonitor.send("Pos: (" + String(posX, 1) + ", " + String(posY, 1) + ")");
});
Bij weinig geheugen, variabelen delen tussen apps:
struct SensorData {
float temperature;
float humidity;
float pressure;
unsigned long lastUpdate;
} sensorData;
void readAllSensors() {
sensorData.temperature = readTemperature();
sensorData.humidity = readHumidity();
sensorData.pressure = readPressure();
sensorData.lastUpdate = millis();
}
void updateAllApps() {
readAllSensors();
bluetoothTemperature.send(sensorData.temperature);
bluetoothTable.sendValueUpdate("Temperature", String(sensorData.temperature, 1) + " °C");
bluetoothTable.sendValueUpdate("Humidity", String(sensorData.humidity, 0) + "%");
bluetoothPlotter.send(sensorData.temperature, sensorData.humidity);
bluetoothGauge.send(sensorData.pressure);
bluetoothMonitor.send("Sensors updated at " + String(sensorData.lastUpdate / 1000) + "s");
}
| Feature | BLE (Esp32BLE_MultipleApps) | Classic Bluetooth (Esp32Bluetooth_MultipleApps) |
| iOS Ondersteuning | ? Ja | ? Nee |
| Android Ondersteuning | ? Ja | ? Ja |
| Energieverbruik | Laag | Hoger |
| Bereik | ~30-100m | ~10-100m |
| Data Snelheid | Lager | Hoger |
| Koppeling Nodig | Nee (auto-connect) | Ja (handmatig) |
| Beste Voor | Batterijgevoede, cross-platform | Hoge doorvoer, Android-only |
> Opmerking voor Meerdere Apps: Omdat meerdere apps gelijktijdig data verzenden, kan Classic Bluetooth met zijn hogere datasnelheid nuttig zijn als u veel snel update apps hebt (bijvoorbeeld plotter op 100 ms). Voor batterijgevoede projecten wordt BLE aangeraden.
1. Apparaat niet zichtbaar in de app
Controleer of ESP32 aan staat en de sketch is geüpload
Voor BLE: Zorg dat Bluetooth en Locatie op uw telefoon aanstaan
Voor Classic Bluetooth: Koppel het apparaat eerst in de Bluetooth-instellingen van uw telefoon
Controleer of het juiste partititie-schema is geselecteerd (Huge APP) — dit is kritiek voor multi-app voorbeelden
2. Sketch is te groot / niet genoeg ruimte
In Arduino IDE, ga naar Tools > Partition Scheme en selecteer "Huge APP (3MB No OTA/1MB SPIFFS)" of "No OTA (Large APP)"
Het standaard partititie-schema geeft maar ~1,2MB voor app-code, wat niet genoeg is voor de multi-app voorbeeld
Deze instelling vergroot de beschikbare ruimte naar ~3MB ten koste van de OTA (over-the-air) update-partitie
Als het nog steeds te groot is, verwijder dan ongebruikte apps
3. Sommige apps verschijnen niet in de mobiele app
Zorg dat elke app is geregistreerd met bluetoothServer.addApp()
Controleer of de include-headers overeenkomen met de aangemaakte app-objecten
Zorg dat alle apps geregistreerd zijn vóór bluetoothServer.begin()
4. Dataveranderingen zijn traag of vertraagd
Verminder het aantal apps dat tegelijk data verzendt
Verhoog update-intervallen voor minder kritieke apps
BLE heeft beperkte bandbreedte — spreid updates in de tijd
5. ESP32 crasht of herstart
Controleer vrije heap geheugen met ESP.getFreeHeap()
Verminder het aantal tabelrijen of plotter-monsters
Zorg voor goede voeding (USB 3.0 of externe voeding)
6. Verbinding valt vaak weg
Kom dichter bij de ESP32 (verminder afstand)
Verminder de hoeveelheid data die verzonden wordt
Verspreid update-intervallen zodat apps niet tegelijk zenden
Houd geheugen en prestaties in de gaten:
void debugMultiApp() {
Serial.println("=== Multi-App Debug ===");
Serial.println("Free Heap: " + String(ESP.getFreeHeap()) + " bytes");
Serial.println("Min Free Heap: " + String(ESP.getMinFreeHeap()) + " bytes");
Serial.println("Uptime: " + String(millis() / 1000) + "s");
Serial.println("=======================");
}
static unsigned long lastDebug = 0;
if (millis() - lastDebug >= 30000) {
lastDebug = millis();
debugMultiApp();
}
Nu u meerdere Bluetooth apps combineert, hebt u alle tools om complexe ESP32-projecten te maken met rijke mobiele interfaces. Verken elk individueel app-tutorial voor diepere API-kennis:
Bluetooth Monitor - Tekstgebaseerde seriële monitor
Bluetooth Chat - Tweerichtingsberichtgeving
Bluetooth Slider - Waardebediening met schuifregelaars
Bluetooth Joystick - 2D richtingsinvoer
Bluetooth Temperature - Temperatuurmeter display
Bluetooth Plotter - Real-time datavisualisatie
Bluetooth Table - Gestructureerde dataweergave
Bluetooth Analog Gauge - Analoog meter display
Bluetooth Rotator - Draaibare knopbesturing