Apple’s Audio Adapter: There I fixed it!

Es ist noch nicht so lange her, da hatten Apple Geräte noch die wunderbare 3,5″ Klinkenbuchse für Audiostecker. Ein weltweiter Standard in der Audiobranche. Aber was scheren Apple schon Standards! Dann fing man an und eliminierte diese Buchse angefangen mit den Mobilgeräten, um den proprietären Apple Anschluss „Lightning“ stattdessen dafür zu benutzen.

Adapter Rant

Jetzt hat man mit einem iPhone zwei neue Probleme:

  1. Man kann es nur mit Strom aufladen ODER Musik hören und das Mikrofon benutzen, beides gleichzeitig (weil z.B. der Akku leer ist) geht nicht mehr; ja super Apple!
  2. Man braucht für sein Audioequipment jetzt einen Adapter (der zumindest den ersten verkrüppelten iPhones noch beilag), weil nur noch Lightning verwendet wird, oder USB-Typ-C

Das Problem mit diesen ganzen Adaptern die man an Apple Geräte anschließen muss besteht kurz umrissen aus folgenden folgenden Problemen:

  1. Diese Adapter müssen immer wieder in die eine Buchse (am Mac Thunderbolt/USB-C; am iPhone Lighting Port) gesteckt werden und erhöhen die Abnutzung dieser Buchse, da ja die Anzahl der Buchsen reduziert wurde im Gerät muss jetzt mehr Zeug, öfter in die EINE Buchse gesteckt werden
  2. Diese Adapter besitzen vom Stecker an in der Regel ein Kabel, dessen Ummantelung ständigem Verfall ausgesetzt ist, nar einigen Jahren oft zerbröselt und das Kabel unbrauchbar macht
  3. Diese Adapter gehen sehr schnell verloren, weil sie klein sind und in Taschen schnell verschwinden auch mal in den Taschen anderer Leute als den rechtmäßigen Besitzern
  4. Das größte Problem ist allerdings meistens, dass man wenn man den Adapter bräuchte man ihn leider nicht dabei hat, oder noch gar nicht weiß dass man diesen separat kaufen muss
  5. Diese Adapter erhöhen den Frust für den Nutzer, denn statt einer direkten Verbindung zwischen Endgerät und Mac/iPhone wird zweimal eine Verbindung/Kontaktstelle möglicher Probleme in das System eingeführt wo sonst nur eine ist; das Risiko eines Wackelkontakts verdoppelt sich also

Ich könnte diesen Rant hier endlos fortführen über die moralische Verwerflichkeit dieser Adapter vor allem hinsichtlich der Kurzlebigeit, weil auch die Rechneranschlüssen bewusst kurzlebig gestaltet werden (dann kann man neue Adapter verkaufen). Auch ist der ökologische Fußabdruck diese Millionen Apple Adapter eine Schande für die Menschheit.

Verwerfliches Adapter Business


Quelle: https://alvinalexander.com/photos/apple-dongle-company-sells-other-stuff/

Aber kommen wir zu etwas Erfreulicherem, ich persönlich halte sogut es eben geht dagegen. Um den Adapter an sich komme natürlich auch ich nicht herum, vor allem bei so komplexen Anschlüssen wie $Apple-Gerät-to-HDMI aber ich kümmere mich zumindest um zwei der krassen Probleme dieser Adapter:

  1. Sie gehen halt schnell verloren (auch in den Taschen anderer)
  2. Sie unterliegen schnellem Zerfall bzw. Wear & Tear insbesondere gehen die Kabel oft zuerst an den Enden der Stecker kaputt

Meine Lösung

Ich setze u.a. regelmäßig folgende Adapter ein:

  1. Mac-Thunderbolt-to-HDMI (weil Apple nicht in der Lage ist einen HDMI Port in moderne Rechner einzubauen)
  2. iPhone-to-HDMI (das ist nochmit der Adapter, für den ich am meisten Verständnis aufbringe, der aber überflüssig wäre, würde Apple einen gängigen drahtlosen Videostreaming Standard unterstützen)
  3. Lighting-to-3,5″ Audio Klinke (weil ich im Auto Klinke habe, weil ich Bluetooth-Verbindungen fehleranfällig finde, und weil ich keinen Bock habe Kopfhörer die noch gut sind wegzuwerfen, nur weil die jetzt Lightning benötigen)
  4. USB-Typ-A-Ladekabel-zu-Lightning
  5. USB-Typ-A-Ladekabel-zu-alter proprietärer iPhone-Anschluss
  6. USB-Typ-C-Ladekabel-zu-Lightning (weil das neue Netzteil des iPhone nur noch USB-C spricht; warum nicht wenigstens eine zusätzliche USB-Typ-A Buchse Apple?? *headdesk*)

Insbesondere die Ladekabel von Apple haben das Problem, dass vor allem an den mechanisch stark belasteten Bereichen in der Nähe der Stecker das Kabel früher oder später porös wird und bricht. Insbesondere deshalb, weil hier sehr dünne aber flexible Kabel mit Weichmacher benutzt werden. Der Weichmacher verschwindet irgendwann und das Plaste versprödet und bricht.

Diesem Problem begegne ist damit, dass ich Schrumpfschlauch nehme und diesen um die Stecker und deren erste paar Zentimeter Kabel anbringe. Das stabilisiert die Enden der Kabel soweit, dass zumindest hier sich der Kabelbruch in Grenzen hält und das Kabel nochmal länger hält.

Der zweite Fix den ich an allen meinen Adaptern vorgenommen habe bezieht sich darauf, dass man die Adapter zum einen schwer wiederfindet, weil sie oft so klein sind und all diese weißen Kabel einfach in einem weißen Kabelknäul verschwimmen. Ich befestige an jedem meiner Adapter einfach eine kleine Textilband-Fahne (einfach ein Textilband umschalgen und mit ein paar Nadelstichen und Faden vernähen), die optisch auffällig ist. So findet man zum einen den Adapter schnell unter einer Menge Zeug wieder und zum anderen ist klar, dieser Adapter gehört mir und niemand anders; er verschwindet somit auch nicht mal eben in den Taschen anderer.

Der Adapter über den ich mich am meisten in letzter Zeit aufgeregt habe ist der Mini-Adapter für Lightning-auf-3,5″ Klinke, da ich diesen gerne mit mir führe, weil mein Mac noch 3,5″ Klinke hat und mein iPhone 11 Pro leider nicht, ich aber nur EIN verdammtes Kopfhörer-Set mitnehmen möchte, also braucht es für das iPhone nun einen Adapter.

Was andere meinen


Quelle: xkcd https://imgs.xkcd.com/comics/universal_converter_box_2x.png

Why do I blog this? Es ist einfach nur traurig, wie hier ganz offensichtlich Profit auf Kosten der Umwelt, der Nachhaltigkeit und gegen jede Vernunft gemacht wird. Apple steht wirtschaftlich so gut da wie kaum ein anderes Unternehmen, warum sie diese Adapter-Scheiße abziehen ist mir ein Rätsel. Es muss einfach Gier sein, anders ist es nicht zu erklären.

blulamp: funny e-cigarette hacking

I had some fun tweaking my blu e-cigarette a little. It is actually quite nicely hackable. Those small plastic containers are actually assembled in a well defined way. You can easily disassemble them and clean them. Though you need to be careful to not use any force disassembling it.

Here you see, how I disassembled one empty smoked container (greetings to my lung here!). I carefully removed the top, black cap first, then worked my way down to the lower parts. To actually get all the not needed stuff out you need to pull out the bottom of the container.

As you see, I removed the small heating coil to actually solder the cables for the LED I wanted to power. Then I soldered the cables first to the LED I put through the black cap and put on top of the container. Then I soldered the cables to the contacts of the bottom of the container and closed the container.

And taddaaaaa… ready is blulamp a tiny flashlight build on top of the blu-container system. You should kinda remember which way you insert the final container to not swap plus and minus contacts for the LED accidentially. But now comes the funny part…

blulamp video in action

…it only lights up, if you blow and suck air through the USB-charging-port. LOL. Smoke your USB to create light, yeah, soooo cool!

Why do I blog this? I just thought, hey I carry a battery with me all the time, why can’t I use this as a flashlight at the same time? I still need to work on the power-on/off-switch though. Right now it is a safety feature which I fully grasp. But maybe I find an elegant way to occasionally bypass this safety net when I operate this thing in blulamp-mode.

ESP32/ESP8266: Von 100 zu 10000 Zeilen Code

Die ersten Zeilen Code waren schnell geschrieben und liefen in der Arduino IDE. Doch bei der einzigen Methode void testLedStrip() sollte es nicht unbedingt bleiben. Und bereits diese allererste Version behrrschte das Art-Net-Protokoll. Doch schnell wurde es deutlich mehr Code…

Handbremse lösen hilft

Als eine der wichtigsten Veränderungen sehe ich rückblickend den Wechsel auf PlatformIO in VSCode von der Arduino IDE. Die Arduino IDE hat durchaus ihre Berechtigung, jedoch ist die Java Basis ein solcher Nervfaktor bei der Geschwindigkeit bestimmter Operationen, dass man schon viel Geduld aufbringen muss. VSCode + PlatformIO hat einige sehr wichtige Vorteile gebracht:

  • Code Completion
  • Macros
  • Übersichtliches File Handling
  • Konfigurierbare Build-Targets
  • Perfekte Suchen/Ersetzen-Funktionen für Refactoring
  • Pre-Compiler checks

Um nur einige zu nennen. VSCode ist im Prinzip mehr der Atom Editor und hat mit Visual Studio wenig zu tun. Das PlatformIO Plugin rüstet den Editor auf zu einer IDE. Das ist durchaus verblüffend, wie gut das funktioniert.

Sehr hilfreich ist vor allem die Peek-Funktion in den Code der hinter bestehenden Funktionsaufrufen steht. Gerade wenn diese Funktionsaufrufe z.B. im Code eines Frameworks liegen oder in Code den man länger nicht angefasst hat, ist es superhilfreich ein kleines Snippet von dem betroffenen Code mal eben sehen zu können. Ruck Zuck weiß man wieder was das Ding eigentlich tut.

Auch die breite Miniatur-Vorschau-Scrollleiste ist einfach megapraktisch. Weil man sich gerade bei langen Codefiles optisch perfekt orientieren kann.

Ab und an muss man VSCode dann zwar mal neustarten, wenn es zu langsam wird, aber das ist vertretbar, ich hatte keinen einzigen Crash der App und keine Datenverluste beim Coden damit.

C/C++

Etwas kann einem die IDE nicht abnehmen, das Wissen um C/C++ ist nicht mal eben auf Abruf erhältlich. Und hier bin ich im Learning-by-Doing, schnell in viele kleine Fallen gerannt. Von den speziellen Dingen rund um Scopes bis hin zu Pointern und Objektorientierung C-Style, hab ich alles berührt was nötig war, um stabilen Code zu schreiben.

Eine der wichtigsten Erkenntnisse für mich war, dass diese ganzen Dateien die man da so anlegt, letztlich nur Strukturierungshilfen für Menschen sind, dem Compiler ist es völlig schnurz, denn behandelt wird all das lustig geschriebene als wäre es EINE große DATEI. Und daher ergeben sich auch manche Probleme die man nicht erkennen kann, wenn man nicht auf diese Metaebene steigt und sieht, dass alle Dateien eigentlich in eine große Datei einfliessen, die für den Compiler die Wahrheit abbildet.

Von Variablen die angeblich schon deklariert wurden, bis hin zu fehlenden Deklarationen und doppelten imports sowie weitergereichten Pointern, die beim Verlassen des Scope ungültig wurden, habe ich alle Fehler gemacht, die man sich so vorstellen kann.

Aber es hat mich dennoch nicht vom Ziel abgebracht und mit einigem Google-Aufwand habe ich mich soweit fortgebildet dass mir die Arbeitsweise mit dieser Sprache immer vertrauter wurde. Am Ende habe ich sogar Bit-Shifting gemacht, um das Art-Net-Protokoll für soegenannte Art-Poll-Requests zu befähigen. Bits zählen ist so mit das Langweiligste was man tun kann, und sehr fehleranfällig noch dazu.

Mein wichtigstes Debugging Werkzeug war

Serial.println( "DEBUG: I AM HERE." )

das habe ich dann später ausgebaut zu ein paar Macros, die ich über des BUILD-Flag DEBUG_LAM dann komplett abschalten konnte.

    #ifdef DEBUG_LAM
    #define LOG( x )  Serial.print( x )
    #define LOG_ENC( x, y )  Serial.print( x, y )
    #define LOG_LN( x )  Serial.println( x )
    #define LOG_LN_ENC( x, y )  Serial.println( x, y )
    #else
    #define LOG( x )
    #define LOG_ENC( x, y )    
    #define LOG_LN(x)
    #define LOG_LN_ENC( x, y )
    #endif

Später habe ich dann begonnen auch Stackdumps zu dekodieren. Aber da war die Software eigentlich schon fertig.

Features: OTA Updates, WebServer, Art-Net, Drucktaster, Konfiguration

Nachdem die ersten LED’s am leuchten waren, wollte ich natürlich Effekte. Also wurde ein paar mal die LED-Routine die den Streifen befeuert umgeändert und erweitert. Doch das reichte irgendwann nicht mehr, denn die Anzahl der Effekte nahm zu. Und ich wollte gerne wechseln können zwischen den Effekten. Auch ein einfacher Ein-Aus-Schalter wäre nützlich.

Also begann ich zunächst zwei PINS mit Drucktastern zu verbinden und diese Taster mit einen PULL-UP-Widerstand zu verdrahten, der beim Drücken der Taste volles Pegelsignal liefert. Hier war tatsächlich die Vorarbeit im Arduinokurs zu Ampelschaltungen mit Grünanforderung extrem nützlich. Denn ich wusste dass ich einen PULL-UP oder PULL-DOWN Widerstand in der Schaltung brauchte für ein gutes Signalhandling.

WebServer zur Bedienung

Relativ schnell kam dann der Wunsch auf, nicht nur einen Effekt zu haben, sondern eine Art Benutzeroberfläche / UI für die Bedienung der „Lampe“. Das An-/Ausschalten und auch z.B. die Helligkeit zu regeln. Durch Delphino hab ich dann gelernt, dass es einen kleinen WebServer für Microcontroller gibt, den ESPAsyncWebServer.

Nach ein wenig Rumprobieren, hatte ich den Server am Laufen und konnte zumindest rudimentär meine Lampe steuern. Das war schon ein beeindruckender erster Moment, das sowas auch mit einem Microcontroller geht. Es war nicht sonderlich schnell aber es funktionierte mit einem simplen Webbrowser und ich konnte damit die die Lampe selbst An- und Ausschalten, Art-Net Support An- und Ausschalten, die Helligkeit regeln, und den Controller Neustarten. Das waren so die wichtigsten Sachen die mir erstmal einfielen, die ich haben wollte.

Die aktuelle Ausbaustufe der Webseite sieht jedoch mittlerweile deutlich umfangreicher aus. Die gesamte Web UI ist mittlerweile optimiert darauf, nicht nur auf dem Desktop, sondern vor allem auf mobile Devices perfekt als Progressive Web Application (PWA) zu funktionieren, also möglichst den Eindruck einer eigenständigen App zu erzeugen.

Durch einige ergänzte <meta>-Tags und ein paar Icon-Dateien konnte ich für iOS und Android ein App-Erscheinungsbild realisieren, das auf beiden Plattformen eine schöne Bedienung zulässt und Home-Screen-Shortcuts erlaubt. Nachstehend ein Foto von der PWA auf einem alten iPod.

Webseiten in Code bauen?

Die erste Webseite die man da weiter oben im Screenshot sieht, hatte ich komplett in Code zusammengesetzt, inkl. des CSS. Das ist eine ziemlich krass Speicherfressende Methode wie ich schnell feststellte. Den gerade das Verketten von Strings sorgt schnell für Speicherfragmentierung und Stackoverflows. Ein Ausweg: Das Flash Filesystem (FS).

Mit Hilfe des SPIFFS Framework, aktivierte ich ein Filesystem auf dem Microcontroller, das es erlaubt Dateien auf dem Controller zu speichern und abzurufen.

SPIFFS steht für (S)erial (P)eripheral (I)nterface (F)lash (F)ile (S)ystem und gemeint ist dabei, dass unser ESP im SPI Programmspeicher, der auch unseren Programmcode enthält, ein einfaches Dateisystem halten kann. — Quelle

Ab jetzt musste der WebServer „nur noch“ Dateien ausliefern. Und ich konnte deutlich schneller meine Webseiten bauen, das CSS anpassen. Es dauerte nicht sehr lange und ich stellte fest, dass jeder TcpRequest der den WebServer traf ganz schön die CPU belastet. Trotz dass der WebServer auf dem zweiten Kern läuft, wird das Rendering der Lampen beeinflusst und andere Tasks scheinbar solange angehalten.

Daher war das Neuladen einer Webseite nach jedem Klick überhaupt keine gute Idee. Es musste eine leichtgewichtige Kommunikation musste her. Als Mittel der Wahl entschied ich mich für Asynchrone Requests per JavaScript. Das war dann auch der Startschuss, ein API zu definieren, denn ich wollte ja keine ganze Webseite mehr ausliefern, sondern am liebsten nur noch kleine JSON-Datenpakete.

Es folgte ein massiver Aufbau einer API (siehe Screenshot). Und mit jedem neuen API Endpunkt konnte die Bedienungs-UI komplexer und umfangreicher werden. Neue Features waren jetzt mehr eine Frage der Nützlichkeit, denn per API hätte ich jetzt alles einbauen können.

Ich hab mir gleich auch doe Mühe gemacht, das API auf dem Controller selbst mit einer HTML-Datei zu dokumentieren. So ist auch for andere ein schneller Lookup möglich.

Remote Fernbedienung? Remote Firmware Update!

Hat man sich erstmal dran gewöhnt, dass man die Lampe fernsteuern kann per Browser über das Wifi, kommt schnell der Wunsch auf mal eben ein Firmwareupdate auf den Controller zu spielen OHNE dass man ihn wieder per USB an den Rechner hängt.

Und das geht tatsächlich megaeinfach. Es nennt sich Over the Air (OTA) Update und wird von den Frameworks unterstützt. Mit einem PlatformIO CLI Command kann man das Update over the Air wie folgt starten:

platformio run -e BUILD_ESP8266_OTA --target upload --upload-port LAM-ESP8266.local

Wichtig ist hier die Angabe der Buildenvironment (hier BUILD_ESP8266_OTA) und des Upload Port (hier LAM-ESP8266.local der mDNS-Hostname den ich für den Microcontroller festgelegt habe; man kann aber auch die IP-Adresse direkt angeben).

Mit in folgender Zeile definiertem Handler im Code legt man z.B. fest, was passieren soll bei Beginn eines Firmwareupdates over the Air:

ArduinoOTA.onStart( []() {

// Code zur Behandlung dieses Ereignisses hier einfügen

});

Das besonders Praktische an einem Update over the Air ist, dass man kein USB-Kabel mehr zum Microcontroller braucht. Und der Controller muss sich lediglich per Wifi im selben Netz befinden, um ihn zu erreichen für ein Update. Es gibt natürlich die Möglichkeit das Update auch mit einem Passwort abzusichern und nur authentifizierte Updates zuzulassen.

Tatsächlich geht ein Update over the Air beim ESP8266 sogar schneller als per USB. Und es ist eben auch ein Weg einen Controller zu erreichen, der vielleicht sogar bereits in einem Gehäuse oder schlecht erreichbar hinter einer Wand montiert ist.

Zwischenfazit

Es ist schlichtweg beeindruckend, was man mit diesem Microcontroller alles tun kann. Allerdings profitiert man deutlich von genügend Vorkenntnissen die man mitbringt. Bei mir waren das Vorkenntnisse in folgenden Bereichen:

  • C (vor allem Macros, Debugging Strategien, Library Management)
  • HTML (wie schaut eine gültige Webseite aus)
  • CSS (wie styled man eine Seite gezielt für hübsches UI, siehe cssdiner.com) bzw. https://flukeout.github.io/
  • Javascript (für eine API-basierte Application)
  • API (wie designe ich eine RESTful API)
  • Arduino Grundlagen (wie kann ich Hardware prototypen mit dem Breadboard)
  • WebServer/TCP/UDP (Grundkenntnisse über Netzwerktraffic, Requesthandling)
  • Grafikbearbeitung (um nötige Icons in benötigter Größe selbst zu erstellen)
  • Browser Dev Tools (Umgang mit der Webconsole des Browsers, oder z.B. Postman als HTTP Client)

Why do I blog this? Der Schritt von einer Lights.ino in der Arduino IDE hin zu einer main.cpp in PlatformIO und dann zu einem Projektordner /src voller Files die sich sauber um einzelne Teile/Features kümmern, war nicht so einfach. Ich hab mindestens zwei größere Refactorings durchgeführt.

Aber es lohnt sich. Belohnt wird man mit einer sauberen Code-Struktur, einer tadellos funktionierenden RESTful API inkl. Dokumentation und einer effizienten Web-Application die auf nahezu allen Browsern Mobile und Desktop reibungslos funktioniert.

Demnächst dann eine Vorstellung des „fertigen“ Systems, sofern so ein Teil jemals fertig sein kann. Denn eines sei verraten, bei einer simplen Lampe hab ich es nicht belassen. Der LED-Strip beherrscht mittlerweile Apps genauso wie Audioausgaben und eine Art-Net-Schnittstelle über die er durch Art-Net bzw. DMX-over-IP prima durch Drittanbieter Apps gesteuert werden kann..