Praxis

 

Praxis 14: Erstellen eines BLE-Servers mit dimmbarer LED

 

Benötigtes Material:

  • ESP32 Dev Modul mit USB-Kabel
  • Breadboard
  • zwei Kabelstück (männlich↔männlich)
  • drei Kabelstücke (weiblich↔männlich)
  • je eine LED in grün und rot
  • zwei Widerstände 220 Ω

 

 

 

Diese Übung nutzt den Aufbau von der Übung mit der gedimmten LED am ESP32. Allerdings wurde dieser durch eine zweite (grüne) LED an Pin 0 ergänzt. Der Sketch ist eine Erweiterung des Beacons, dieser lässt es zu dem ESP32 Werte über Bluetooth zuzusenden, auf die der ESP mit entsprechender Leuchtstärkenanpassung der LED reagiert.

Die LED an Pin 2 kann durch die Kommandos „20“, „40“, „60“, „80“, „100“ und „aus“ auf verschiedene „Leuchtstufen gebracht werden. Dies geschieht dadurch, dass sowohl der Bluetooth-Server als auch die „Empfangs¬charakteristik“ eine sogenannte Callback-Routine hinterlegt hat, kann die Loop hier ebenfalls wieder leer bleiben. Die grüne LED dient als Kontrollanzeige. Leuchtet sie ist ein Client mit dem BLE-Server verbunden.

#include <Arduino.h>
/* -------------------------------------
    Praxis 14
    BLE-Server mit dem ESP32
    LED dimmbar
  -----------------------------------*/

#include "BLEDevice.h"
#include "BLEServer.h"
#include "BLEUtils.h"
#include "BLE2902.h"

const int ledPin = 2;
const int led2Pin = 0;
const int channel = 0;
const int freq = 5000;
const int resolution = 8;
const char *bleName = "ESP32_LED";
String receivedText = "";
unsigned long lastMessageTime = 0;

// Wichtig!
// Die UUIDs unbedingt durch "eigene" UUIDs von der folgenden Webseite ersetzen:
// https://www.uuidgenerator.net/
#define SERVICE_UUID           "736fffed-e3ea-4ef7-a0a5-40939037b3aa"
#define CHARACTERISTIC_UUID_RX "e3af84cf-d7dd-405b-b825-63701a3dbf89"
#define CHARACTERISTIC_UUID_TX "031d83bc-4efb-4133-a287-93a0d8e055c9"
BLECharacteristic *pCharacteristic;

void setupBLE();

void setup() {
  Serial.begin(115200);
  setupBLE();
  pinMode(ledPin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  digitalWrite(led2Pin, LOW);
}

void loop() {
  delay(1000);
}

class MyServerCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer *pServer) {
    Serial.println("Verbunden");
    digitalWrite(led2Pin, HIGH);
  }
  void onDisconnect(BLEServer *pServer) {
    Serial.println("Getrennt");
    digitalWrite(led2Pin, LOW);
    pServer->getAdvertising()->start(); 
  }
};

class MyCharacteristicCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    // Für der Arduino IDE mit Boardtreiber 3.0.x nächste Zeile nutzen
    String value = pCharacteristic->getValue();
    // Für VSCode mit PlatformIO stattdessen die nächste Zeile nutzen
    // std::string value = pCharacteristic->getValue();
    if (value == "aus") {
      analogWrite(ledPin, 0);
      Serial.println("LED aus");
    } else if (value == "20") {
      analogWrite(ledPin, 21);
      Serial.println("20%");
    }
    else if (value == "40") {
      analogWrite(ledPin, 51);
      Serial.println("40%");
    }
    else if (value == "60") {
      analogWrite(ledPin, 100);
      Serial.println("60%");
    }
    else if (value == "80") {
      analogWrite(ledPin, 155);
      Serial.println("80%");
    }
    else if (value == "100") {
      analogWrite(ledPin, 255);
      Serial.println("100%");
    }
  }
};

void setupBLE() {
  BLEDevice::init(bleName);
  BLEServer *pServer = BLEDevice::createServer();
    if (pServer == nullptr) {
    Serial.println("Fehler beim Starten des Servers!");
    return;
  }
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID);
  if (pService == nullptr) {
    Serial.println("Fehler beim Einrichten des Dienstes!");
    return;
  }
  pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX,
                                       BLECharacteristic::PROPERTY_NOTIFY);
  pCharacteristic->addDescriptor(new BLE2902()); 
  BLECharacteristic *pCharacteristicRX = pService->createCharacteristic(
                                        CHARACTERISTIC_UUID_RX,
                                        BLECharacteristic::PROPERTY_WRITE);
  pCharacteristicRX->setCallbacks(new MyCharacteristicCallbacks());
  pService->start();
  pServer->getAdvertising()->start();
  Serial.println("Warte auf eine Verbindung...");
}

Wichtig:

Damit sich auch hier die verschiedenen Server nicht stören und unterscheidbar bleiben, müssen die UUIDs durch individuelle ersetzt werden. Damit man die verschiedenen Server auch am Namen unterscheiden kann, sollte dieser auch einen individuellen Namen besitzen.

 

Aufgaben

  1. Bauen Sie die die Schaltung mit den LEDs auf einem Breadboard auf.
    Beachten Sie dabei die Polung der LEDs.
  2. Geben Sie den Sketch in die IDE ein.
    Beachten Sie die Alternative in der class MyCharacteristicCallbacks (Zeile 59) des Quellcodes, wenn VS Code verwendet wird.
  3. Generieren Sie sich auf der Seite https://www.uuidgenerator.net/ drei UUIDs und ersetzen Sie die in den betreffenden Zeilen (25, 26 und 27) Ihres Sketches.
  4. Wählen Sie einen individuellen Namen für Ihren Server und tragen diesen hinter der Variablendefinitionconst char *bleName = (Zeile 18) ein.
  5. Kompilieren und Übertragen Sie das Programm auf den ESP32.
  6. Sollte es zu Problemen beim Kompilieren geben, müssen ggf. noch fehlende Bibliotheken zur IDE hinzugefügt werden.
  7. Prüfen Sie im seriellen Monitor oder Terminal, dass der Server eingerichtet ist.
    Achten Sie auf die richtige Baudrate!
  8. Laden Sie eine Scanner-App für Ihr Smartphone und suchen Sie „Ihren“ Server.
    Mögliche Apps sind:
                
    Der linke QR-Code ist für Android- (PlayStore), der rechte für Apple-Smartphones.
  9. Sobald Sie sich mit dem Server verbinden sollte die grüne LED leuchten, Durch ändern des Wertes auf einen der vordefinierten Werte (UTF-8 String) sollte die rote LED reagieren.