Software Entwicklung

Inbetriebnahme der Komponenten

LED-Ringe

Aller Anfang ist das Testen der Komponenten mit Beispielcode. Die ersten zu testenden Komponenten waren die LED-Ringe. Wer lesen kann, ist klar im Vorteil und wir hätten uns einiges an Herumprobieren sparen können. Denn beim großen Ring handelte es sich um einen NeoPixel RGBW Ring, wir hatten jedoch Beispielcode der FastLED Library benutzt, die kein RGBW unterstützt. Gleichzeitig kann der kleinere LED Ring nicht mit der Adafruit NeoPixel-Library betrieben werden, sodass beide Ringe einzeln getestet werden mussten. Nach erfolgreicher Inbetriebnahme der LEDs ging es dann an das Testen der Internetverbindung.

Internetverbindung, MQTT & Uhrzeit

Ein Besispiel-Sketch der PubSub-Library verband den ESP8266 fehlerfrei mit dem Internet und dem MQTT-Broker der Uni. Bei der Suche danach, auf dem ESP eine funktionierende Uhr zu implementieren, stießen wir auf Clock-Module, aber auch auf das Network-Time-Protocol (NTP). Da wir ohnehin schon eine Internetverbindung realisiert hatten, welche für die MQTT-Kommunikation essentiell ist und wir uns außerdem von unnötiger Hardware distanzieren wollten, sowohl um Platz im Gehäuse der Uhr als auch Kosten zu sparen, haben wir uns für das NTP entschieden. Schnell haben wir auch hier eine entsprechende Bibliothek für Arduino gefunden und mit dem enthaltenen Beispiel die Uhrzeit ausgegeben. Mit einem Offset lässt sich die UTC-Zeit auf unsere Zeitzone anpassen. Problematisch ist allerdings der Wechsel von Sommer- auf Winterzeit und andersherum, da dieser in UTC nicht vorhanden ist und das Offset dahingehend angepasst werden muss.

BMe680 & BH1750

Diese beiden Sensoren benutzen das I2C-BUS-Protokoll. Das hat den Vorteil, dass nur zwei PINs für Clock und Data gebraucht werden. Allerdings kann man nicht entscheiden welche das sein sollen, sondern der ESP hat fest definierte PINs dafür. Diese unterscheiden sich jedoch teilweise nach Modell und auch die Unterscheidung zwischen der Schreibweise D1 und GPIO1 (NICHT der gleiche PIN) haben zunächst dafür gesorgt, dass wir die falschen PINs genutzt und daher auch keine Verbindung zum Sensor erhalten haben.

Beide Sensoren haben eigene Bibliotheken, der BME680 hat jedoch die Besonderheit, dass die Bosch BSEC Library Veränderungen an den Compiler-Einstellungen braucht, die zwar gut dokumentiert aber trotzdem schlecht zu finden waren. Außerdem benutzt der BME680 nur seine Standardadresse, wenn der Adresspin mit GND verbunden ist.

Die Beispiel-Sketche gaben dann aber realistische Werte aus, auch wenn der BME680 einige Minuten brauchte um sich zu kalibrieren.

Komposition

Als nächstes haben wir die Beispiele zusammengefügt und die Zeit, die wir vom NTP-Server bekommen, in eine LED-Animation umgerechnet. Außerdem musste die Zeit vom 24h- ins 12h-Format umgerechnet werden, damit die LEDs die Uhrzeit wie bei einer analogen Uhr anzeigen. Die Uhrzeit wurde nach kurzer Zeit richtig dargestellt – unser erster Erfolg. Anschließend haben wir die Animationen für den Pomodoro-Timer implementiert und entsprechende MQTT-Topics geschaffen, um den Timer zu starten, zu stoppen und des Weiteren die LED Ringe komplett abzuschalten.

Button

Unsere Uhr soll einen markanten Knopf auf der Obereite bekommen und dafür wurde für einen simplen Steck-Button die entsprechende Schnittstelle geschrieben und getestet. Hier musste garantiert werden, dass der Knopf nur beim Wechsel des Zustandes auslöst und nicht merhfach, falls er gedrückt gehalten wird. Leider hat der Button den Timer nur gestoppt und nur selten gestartet, da der Delay in der Uhrenanimation das Auslesen des Eingangs geblockt hat. Die Animation wurde geändert und der Knopf funktionierte schlussendlich einwandfrei.

Helligkeit

Der BH1750 ist ein digitaler Belichtungssensor, der je nach Umgebungshelligkeit die Helligkeit der LEDs steuern soll. Dafür muss der ausgelesene Wert in Lux auf einen Wert zwischen 0 und 255 gemappt werden. Da die Einheit Lux keine obere Grenze hat, mussten wir uns für eine exemplarische Grenze entscheiden, bei der unsere LEDs dann auf 100% (255) leuchten. Wir haben uns dann für 150 Lux entschieden, auch wenn ein etwas geringerer Wert wahrscheinlich genauso gut funktioniert hätte.

Sensor-Animationen

Als nächstes ging es daran, den kleinen LED Ring nützlich zu machen. Für die Temperatur wird der gemessene Wert in °C auf einen Wert der HSV Skala zwischen 240 (blau) und 0 (rot) gemappet, dabei bleibt die LED allerdings ausgeschaltet solange der Wert zwischen 80 und 160 (Bereich von grün) liegt.

Für die Luftfeuchtigkeit haben wir genau das Gleiche gemacht, bloß mit einer umgedrehten Skala, denn eine hohe Luftfeuchtigkeit ist eher mit blau zu assozieren und eine hohe Temperatur eher mit rot.

Für die Luftqualität und die Konzentration von CO2 Äquivalenzen ist die Animation eine stufenlose Ampel, da man keine zu niedrige (gute) Luftqualität haben kann, wie es beispielsweise bei der Temperatur möglich ist. Auch hier haben wir die grüne Farbe weggelassen, um den Nutzer möglichst wenig abzulenken, falls alles in Ordnung ist und nur im Falle von schlechten Werten darauf aufmerksam zu machen.

Bei allen Animationen entstand durch die seltene Aktualisierung der Sensoren eine deutliche Verzögerung, wenn das Licht, nachdem es aus war, wieder angeschaltet wurde. Daher erstellen wir eine Kopie des CRGB Arrays beim Ausschalten und übertragen diese Werte beim Einschalten wieder in das eigentliche Array. Hierbei sind uns bisher allerdings noch einige Probleme aufgefallen, die dafür sorgen, dass manche LEDs nicht ausgehen und andere nicht wieder an. Generell lässt sich außerdem sagen, dass die Farbdarstellung nicht sonderlich akkurat ist und gerade blau eher lila aussieht.

Umstellung des äußeren LED Rings

Da uns die Uhr mit dem ursprünglichen LED Ring zu klein war, haben wir uns einen Größeren gekauft. Dieser hat trotzdem die gleiche Anzahl an LEDs (was kein Vorteil ist, da dies nur die Änderung einer Variable im Code bedeutet hätte, aus der sich alles Weitere berechnet), dafür verwendet er allerdings ein anderes Chipset, welches nicht von der Adafruit NeoPixel Library unterstützt wird. Wir mussten also alle Referenzen auf die alte Library durch die neue ersetzen. Da gleichzeitig die Kommentare im Code verbessert wurden hatten wir leider einen riesigen Mergekonflikt, der aber kurze Zeit später schnell wieder aufgelöst werden konnte.