ESP32- Umsetzung


Die Idee

Die Idee war ein selbst malbares Launchpad, das ungefähr so aussehen sollte:


Der Prototyp

Das ist jedoch leider nur die digital nachbearbeitet Form.. Mir fehlten die nötigen Bauteile, daher sieht der Prototyp nun so aus:


Jetzt aber zum Wesentlichen - Hier ein kurzer Video-Walkthrough durch das Projekt:



Dokumentation

Gestartet habe ich damit einzelne Bauteile zum testen zu bestellen:

Mit einzelnen Testprojekten habe ich dann die Einzelfunktionen der Bauteile getestet. Also Daten speichern und abspielen von der SD Karte, die LED des Buttons auf Knopfdruck zum blinken bringen, den Wert des Potentiometers auslesen und verarbeiten, die Touch-Inputs auf Genauigkeit testen und zuletzt die Audio Ausgabe.

SD Karte

Der SD Kartenleser kann von der SD.h Bibliothek angesteuert werden und mit der dort angegebenen Pin-Belegung und den Example-Projekten ließen sich Beispiel-Dateien auf die SD Karte schreiben! Ich habe dann weiter versucht .wav und .mp3 Dateien dort zu speichern und wiederzugeben.
















DAC

Der Digital-Analog-Converter soll die Audio-Signale auf einen 3,5mm Klinkenport ausgeben. Dazu muss er mit dem I2S Protokoll angesteuert werden. Hier hat es extrem viele Versuche gebraucht um überhaupt Ton aus dem DAC herauszubekommen. Bei dem kleinsten Wackelkontakt der Pins wurde gar kein Ton mehr ausgegeben, außerdem musste ich fünf verschiedene I2S Audio Bibliotheken für Arduino und besonders den ESP32 durchprobieren bis ich den DAC erfolgreich zum laufen bringen konnte. Die Unsicherheit nicht zu wissen an welcher Stelle es gerade hakt, hat das besonders schwierig gemacht. Nachdem ich die Pins dann fest verlötet hatte und mit Klebeband zueinender gebunden hatte um Wackelkontakte zu vermeiden war auch eine halbwegs störgeräuschfreie Audio Wiedergabe möglich.




Push Button mit LED

Bei diesem Button war es nur schwierig zunächst die Pin-Belegung durch ausprobieren herauszufinden, da er keine Dokumentation über die Belegung hat. Nachdem die Pin-Belegung klar war, habe ich direkt Kabel mit Steckpins an die Anschlüsse gelötet, damit er dann leichter zu verwenden ist. Die ersten Tests mit LED blinken lassen und Button Status erkennen waren jeweils direkt erfolgreich!














Potentiometer

Das Potentiometer war zwar leicht anzuschließen, hatte jedoch auch mit Wackelkontakten zu kämpfen, die im Zweifelsfall für einen plötzlichen Lautstärke Wechsel sorgen würden. Klebeband konnte die Kontakte etwas stärker zusammenhalten, ganz gelöst ist das Problem jedoch nicht. Das Auslesen des Potentiometer-Werts war auch problemlos möglich, lediglich die weitere Verwendung dieses Wertes auf einer Skala von 0 bis 4095 war etwas umständlich in Lautstärken-Werte umzuwandeln. Ich habe zur Vereinfachung Schwellwerte pro Lautstärke Stufe definiert, nachder die jeweils höhere Stufe erreicht wird. Damit waren Float-Werte vermeidbar und der Übergang relativ einfach, auch wenn es im Code nicht besonders schön gelöst ist.




Erster Prototyp

Ein erster Prototyp sollte dann die Audioausgabe und die SD Karte miteinander vereinen indem er beim Start eine Sound-Datei von der SD Karte abspielen sollte.
Nach zahlreichen Versuchen war dann (obwohl es als kompatibel angegeben war), das Format .wav das Problem. Mit einer .mp3 Datei konnte der Sound dann erfolgreich abgespielt werden!
Ich habe daraufhin versucht weitere Sounds mit auf die SD Karte zu spielen und diese hintereinander abzuspielen. Daraufhin war es jedoch nicht mehr möglich überhaupt Sounds von der SD Karte abzuspielen - auch nach zurücksetzen auf den vorherigen Stand mit nur einem Sound File.
Ich habe mich dann nach endlosen Tests dazu entschieden erstmal mit dem restlichen Prototyp fortzufahren und dann das SD Karten Problem anzugehen.




Zweiter Prototyp

Als Oberfläche für das Interface habe ich mir ein Papier-Schneidebrett ausgesucht, da es ein gutes Maß hatte und gut zum Konzept gepasst hat. Dort habe ich Klammern eingesetzt die das Papier einerseits festklemmen sollen und andererseits einen Kontakt zu der Zeichnung herstellen sollen. Daher gibt es am Rand des Bretts aktuell drei, geplant jedoch acht Kontakte für Touch-Inputs. Diese sind dann auf der Unterseits verkabelt um sie an den ESP anschließen zu können. Im Gegensatz zu einem ersten Touchtest, konnte hier jedoch kurz nach dem eigentlich Kontakt schon keine Veränderung des Touch-Input-Wertes hergestellt werden. Damit ist das gesamte Konzept schon nicht mehr sinnvoll umsetzbar. Lediglich durch Ergänzung von Alufolie lässt sich so ein Input ermöglichen, was jedoch das Konzept des gezeichneten Launchpads zerstört. Es hat sich damit eher zur Umsetzung eines "gebastelten" Lauchnpads gewandelt.

Das Potentiometer und der LED-Button ließen sich dafür problemlos in das Board integrieren!




Verkabelung

Mit vollständiger Verkabelung ließen sich dann auch Sprachausgaben durch Berührung der Inputs bzw. durch drücken des Buttons erzeugen. Das war der größte Erfolg bei diesem Prototyp, da es beweist, dass die Technik grundsätzlich funktionieren kann!

Was sich bis zum Schluss, auch mit einem zweiten Lesegerät, mehreren SD Karten, komplett neuer Verkabelung, mehrere SD Bibliotheken und verschiedenster Datei-Formate und Formatierungen nicht lösen ließ war das Abspielen einer Datei von der SD-Karte. Ich kann mir nicht erklären wo der Fehler liegt, da es in einem Zwischenschritt bereits möglich war den einzelnen Sound-File erfolgreich abzuspielen. An dieser Stelle bin ich zeitlich und technisch gescheitert. Es lässt sich auf Knopfdruck jedoch Online-Radio über das WLAN abpsielen :D




Pin-Belegung

Zum besseren Verständnis hier die Pin-Belegung und der verwendete Code:
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#include "SD.h"
#include "FS.h"

#define SD_CS 5
#define SPI_MOSI 23
#define SPI_MISO 19
#define SPI_SCK 18
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26


Audio audio;

String ssid = "*******";
String password = "********";

void setup() {
pinMode(SD_CS, OUTPUT); digitalWrite(SD_CS, HIGH);
SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
Serial.begin(115200);
SD.begin(SD_CS);
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(ssid.c_str(), password.c_str());
while (WiFi.status() != WL_CONNECTED) delay(1500);
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(21);

audio.connecttospeech("Willkommen auf deinem Launchpad", "de");

}

void loop()
{
if (analogRead(34)>0){
audio.setVolume(20);
}
if (analogRead(34)>200){
audio.setVolume(19);
}
if (analogRead(34)>400){
audio.setVolume(18);
}
if (analogRead(34)>600){
audio.setVolume(17);
}
if (analogRead(34)>800){
audio.setVolume(16);
}
if (analogRead(34)>1000){
audio.setVolume(15);
}
if (analogRead(34)>1200){
audio.setVolume(14);
}
if (analogRead(34)>1400){
audio.setVolume(13);
}
if (analogRead(34)>1600){
audio.setVolume(12);
}
if (analogRead(34)>1800){
audio.setVolume(11);
}
if (analogRead(34)>2000){
audio.setVolume(10);
}
if (analogRead(34)>2200){
audio.setVolume(9);
}
if (analogRead(34)>2400){
audio.setVolume(8);
}
if (analogRead(34)>2600){
audio.setVolume(7);
}
if (analogRead(34)>2800){
audio.setVolume(6);
}
if (analogRead(34)>3000){
audio.setVolume(5);
}
if (analogRead(34)>3200){
audio.setVolume(4);
}
if (analogRead(34)>3400){
audio.setVolume(3);
}
if (analogRead(34)>3600){
audio.setVolume(2);
}
if (analogRead(34)>3800){
audio.setVolume(1);
}
if (analogRead(34)>4000){
audio.setVolume(0);
}

if (digitalRead(2)==1){
audio.connecttospeech("Audio Set 1 ausgewählt.", "de");
audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.mp3");
audio.loop();
}

if (touchRead(4)<20){
audio.connecttospeech("Sound 1", "de");
Serial.println(touchRead(4));
}

if (touchRead(13)<20){
audio.connecttospeech("Sound 2", "de");
Serial.println(touchRead(13));
}

if (touchRead(12)<20){
audio.connecttospeech("Sound 3", "de");
Serial.println(touchRead(12));
}

delay(500);
}






Fazit

Trotz der vielen technischen Schwierigkeiten, der endlosen Ladezeiten bis der Code auf dem Controller war und den unerklärlichen Fehlern hat dennoch Einiges geklappt. Ich werde mir hiernach auf jeden Fall einen eigenen Arduino zulegen um weiter damit zu experimentieren, da sich diese Art des Prototypens für mich definitiv bewährt hat! Gerade um reale interaktive Prototypen zu bauen ist das eine gute und schnell realisierbare Möglichkeiten ohne größere Kosten und Aufwand.