Das Multiple Bluetooth Apps Beispiel zeigt, wie Sie mehrere Bluetooth App-Oberflächen in einem einzigen ESP32-Projekt kombinieren können. Führen Sie Monitor, Chat, Slider, Joystick, Temperature, Plotter, Table, Analog Gauge und Rotator alle gleichzeitig aus — zugänglich über die DIYables Bluetooth STEM App. Entwickelt für ESP32 Boards mit Unterstützung für sowohl BLE (Bluetooth Low Energy) als auch Classic Bluetooth Verbindungen. Dies ist ideal für komplexe Projekte, die mehrere Steuerungs- und Anzeige-Oberflächen gleichzeitig benötigen.
Dieses Beispiel unterstützt zwei Bluetooth Modi:
ESP32 BLE (Bluetooth Low Energy): Funktioniert sowohl auf Android als auch iOS
ESP32 Classic Bluetooth: Funktioniert nur auf Android. iOS unterstützt kein Classic Bluetooth. Verwenden Sie BLE, wenn Sie iOS-Unterstützung benötigen.
Folgen Sie diesen Anweisungen Schritt für Schritt:
Verbinden Sie das ESP32 Board mit Ihrem Computer über ein USB-Kabel.
Starten Sie die Arduino IDE auf Ihrem Computer.
Wählen Sie das entsprechende ESP32 Board und COM Port.
Navigieren Sie zum Libraries Icon in der linken Leiste der Arduino IDE.
Suchen Sie "DIYables Bluetooth", finden Sie dann die DIYables Bluetooth Bibliothek von DIYables
Klicken Sie den Install Button, um die Bibliothek zu installieren.
Sie werden gefragt, einige andere Bibliotheks-Abhängigkeiten zu installieren
Klicken Sie den Install All Button, um alle Bibliotheks-Abhängigkeiten zu installieren.
> Wichtig: Da dieses Beispiel viele Bluetooth App-Bibliotheken enthält, ist der kompilierte Sketch größer als gewöhnlich. Sie müssen das korrekte Partition Scheme auswählen (siehe unten).
Wählen Sie einen der beiden Bluetooth Modi unten, je nach Ihren Bedürfnissen:
Hinweis: Classic Bluetooth wird auf iOS NICHT unterstützt. Wenn Sie iOS-Unterstützung benötigen, verwenden Sie den BLE Code unten.
#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);
}
Wichtig: Gehen Sie zu Tools > Partition Scheme und wählen Sie "Huge APP (3MB No OTA/1MB SPIFFS)". Dies ist erforderlich, da das Multiple Apps Beispiel deutlich mehr Flash-Speicher verwendet.
Klicken Sie den Upload Button in der Arduino IDE, um den Code auf den ESP32 hochzuladen
Öffnen Sie den Serial Monitor
Überprüfen Sie das Ergebnis im Serial Monitor. Es sieht etwa so aus:
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);
}
Wichtig: Gehen Sie zu Tools > Partition Scheme und wählen Sie "Huge APP (3MB No OTA/1MB SPIFFS)". Dies ist erforderlich, da das Multiple Apps Beispiel deutlich mehr Flash-Speicher verwendet.
Klicken Sie den Upload Button in der Arduino IDE, um den Code auf den ESP32 hochzuladen
Öffnen Sie den Serial Monitor
Überprüfen Sie das Ergebnis im Serial Monitor. Es sieht etwa so aus:
DIYables Bluetooth - ESP32 BLE Multiple Apps Example
Waiting for Bluetooth connection...
Installieren Sie die DIYables Bluetooth App auf Ihrem Smartphone:
Android |
iOS
Falls Sie den ESP32 Classic Bluetooth Code verwenden, müssen Sie den ESP32 mit Ihrem Android-Telefon vor dem Öffnen der App koppeln:
Gehen Sie zu den Einstellungen > Bluetooth Ihres Telefons
Stellen Sie sicher, dass Bluetooth eingeschaltet ist
Ihr Telefon scannt nach verfügbaren Geräten
Finden und tippen Sie "ESP32 Multi-App" in der Liste verfügbarer Geräte
Bestätigen Sie die Kopplungsanfrage (keine PIN erforderlich)
Warten Sie, bis "Gekoppelt" unter dem Gerätenamen angezeigt wird
Falls Sie den ESP32 BLE Code verwenden, ist keine Kopplung erforderlich. Fahren Sie einfach mit dem nächsten Schritt fort.
Öffnen Sie die DIYables Bluetooth App
Beim ersten Öffnen der App wird sie nach Berechtigungen fragen. Bitte gewähren Sie folgende:
Geräte in der Nähe Berechtigung (Android 12+) / Bluetooth Berechtigung (iOS) - erforderlich zum Scannen und Verbinden mit Bluetooth-Geräten
Standort Berechtigung (nur Android 11 und früher) - von älteren Android-Versionen zum Scannen nach BLE-Geräten benötigt
Stellen Sie sicher, dass Bluetooth eingeschaltet ist auf Ihrem Telefon
Auf dem Startbildschirm tippen Sie den Connect Button. Die App scannt nach BLE und Classic Bluetooth Geräten.

Finden und tippen Sie Ihr Gerät in den Scan-Ergebnissen, um sich zu verbinden:
Sobald verbunden, geht die App automatisch zurück zum Startbildschirm. Der Startbildschirm zeigt alle verfügbaren Apps. Die 9 Apps, die im Arduino-Code initialisiert wurden, werden reagieren und funktionieren — andere Apps auf dem Startbildschirm werden erscheinen, aber nicht mit diesem Sketch funktionieren.
Hinweis: Sie können das Einstellungssymbol auf dem Startbildschirm tippen, um Apps auf dem Startbildschirm zu verstecken/anzeigen. Für weitere Details siehe das DIYables Bluetooth App Benutzerhandbuch.
Tippen Sie einige der folgenden Apps, um sie zu öffnen und mit dem ESP32 zu interagieren: Monitor, Chat, Slider, Joystick, Temperature, Plotter, Table, Analog Gauge, Rotator
Wechseln Sie frei zwischen Apps — sie teilen alle dieselbe Bluetooth-Verbindung
Schauen Sie nun zurück zum Serial Monitor in der Arduino IDE. Sie werden sehen:
Bluetooth connected!
Monitor: Uptime: 5s | Free heap: 245780 bytes
Temperature: 25.3°C
Plotter values sent
Table values updated
Gauge value: 50.0
Jede App wird als separates Objekt erstellt und beim selben Bluetooth-Server registriert. Sie teilen die einzige Bluetooth-Verbindung, arbeiten aber unabhängig:
#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);
Jede App hat ihre eigenen Event-Handler:
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) + "°");
});
}
Jede App kann ihr eigenes Update-Timing haben:
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);
}
Sie müssen nicht alle 9 Apps einbeziehen. Wählen Sie nur die, die Sie benötigen:
#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 der DIYables Bluetooth App:
Der Startbildschirm zeigt alle registrierten Apps als Buttons
Tippen Sie jede App, um sie zu öffnen
Verwenden Sie den Zurück-Button oder Home-Button, um zurückzukehren und zu einer anderen App zu wechseln
Alle Apps laufen weiter auf dem ESP32, unabhängig davon, welche App angezeigt wird
Input Apps (Slider, Joystick, Rotator, Chat): Senden Daten vom Telefon zum ESP32
Output Apps (Monitor, Temperature, Plotter, Table, Gauge): Senden Daten vom ESP32 zum Telefon
Bidirektionale Apps (Chat, Monitor): Können Daten senden und empfangen
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) + "%");
});
}
Verwenden Sie Daten von einer App, um eine andere zu aktualisieren:
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) + ")");
});
Wenn der Speicher knapp ist, teilen Sie Variablen zwischen 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");
}
| Funktion | BLE (Esp32BLE_MultipleApps) | Classic Bluetooth (Esp32Bluetooth_MultipleApps) |
| iOS Unterstützung | ? Ja | ? Nein |
| Android Unterstützung | ? Ja | ? Ja |
| Stromverbrauch | Niedrig | Höher |
| Reichweite | ~30-100m | ~10-100m |
| Datenrate | Niedriger | Höher |
| Kopplung erforderlich | Nein (auto-connect) | Ja (manuelle Kopplung) |
| Am besten für | Batterie-betrieben, plattformübergreifend | Hoher Durchsatz, nur Android |
> Hinweis für Multiple Apps: Da mehrere Apps gleichzeitig Daten senden, kann die höhere Datenrate von Classic Bluetooth vorteilhaft sein, wenn Sie viele schnell aktualisierenden Apps haben (z.B. Plotter bei 100ms). Für batteriebetriebene Projekte wird BLE dennoch empfohlen.
1. Kann das Gerät in der App nicht finden
Stellen Sie sicher, dass der ESP32 eingeschaltet ist und der Sketch hochgeladen wurde
Für BLE: Stellen Sie sicher, dass Bluetooth und Standort Ihres Telefons aktiviert sind
Für Classic Bluetooth: Koppeln Sie das Gerät zuerst in den Bluetooth-Einstellungen des Telefons
Überprüfen Sie, dass das korrekte Partition Scheme ausgewählt ist (Huge APP) — dies ist kritisch für Multi-App-Beispiele
2. Sketch zu groß / nicht genügend Speicher
In der Arduino IDE, gehen Sie zu Tools > Partition Scheme und wählen Sie "Huge APP (3MB No OTA/1MB SPIFFS)" oder "No OTA (Large APP)"
Das Standard Partition Scheme bietet nur ~1,2MB für App-Code, was für das Multi-App-Beispiel nicht ausreicht
Diese Einstellung gibt ~3MB durch Aufgabe der OTA (Over-the-Air Update) Partition
Falls immer noch zu groß, entfernen Sie Apps, die Sie nicht benötigen
3. Einige Apps erscheinen nicht in der mobilen App
Stellen Sie sicher, dass jede App mit bluetoothServer.addApp() registriert ist
Überprüfen Sie, dass die Include-Header den erstellten App-Objekten entsprechen
Verifizieren Sie, dass alle Apps vor bluetoothServer.begin() registriert sind
4. Daten-Updates sind langsam oder verzögert
Reduzieren Sie die Anzahl der Apps, die gleichzeitig Daten senden
Erhöhen Sie Update-Intervalle für weniger kritische Apps
BLE hat begrenzte Bandbreite — staffeln Sie Updates über die Zeit
5. ESP32 stürzt ab oder startet neu