{"id":263,"date":"2020-11-26T09:15:27","date_gmt":"2020-11-26T08:15:27","guid":{"rendered":"https:\/\/followthescore.org\/schueler-labor\/?p=263"},"modified":"2021-01-25T06:44:56","modified_gmt":"2021-01-25T05:44:56","slug":"weihnachtsstern","status":"publish","type":"post","link":"https:\/\/followthescore.org\/schueler-labor\/weihnachtsstern\/","title":{"rendered":"Weihnachtsstern"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"859\" height=\"859\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/stzern.jpg\" alt=\"\" class=\"wp-image-298\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/stzern.jpg 859w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/stzern-300x300.jpg 300w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/stzern-150x150.jpg 150w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/stzern-768x768.jpg 768w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/stzern-850x850.jpg 850w\" sizes=\"(max-width: 859px) 100vw, 859px\" \/><\/figure>\n\n\n\n<p>Wir bauen einen <em>modularen<\/em> Weihnachtsstern. Er soll von einem kleinen Rechner gesteuert werden und mehrfarbig leuchten, alleine oder im Verbund mit anderen Sternen.<\/p>\n\n\n\n<p>Was ist mit <em>modular<\/em> gemeint?<\/p>\n\n\n\n<h2>Liste der Anforderungen<\/h2>\n\n\n\n<ul><li>(A) Die Teile des Sterns sollen gut gegeneinander abgegrenzt sein, mit einfachen mechanischen Verbindungen und leicht l\u00f6sbaren elektrischen Schnittstellen.  Die Farben sollen den einzelnen Armen des Sterns klar zugeordnet sein, an den \u00dcbergangsstellen jedoch etwas verwischen.<\/li><li>(B) Man soll den Rechner auch anderweitig verwenden k\u00f6nnen.<\/li><li>(C) Idealerweise sollen unterschiedliche Varianten des Rechners (ES32, ES8266, als Entwicklungsboard oder als barebone) einsetzbar sein.<\/li><li>(D) Die Montage soll einfach sein. <\/li><li>(E) Der fertige Stern soll als Modul innerhalb einer Gruppe von Sternen dienen k\u00f6nnen.<\/li><li>(F) Die Zahl der Arme eines Sterns soll relativ leicht \u00e4nderbar sein. <\/li><li>(G) Es soll m\u00f6glich sein, den Rechner innerhalb des Sterns zu haben, aber auch au\u00dferhalb.<\/li><li>(H) Bei gro\u00dfen Sternen soll auch der Akku (Powerbank oder Lithium-Akku) innerhalb des Sterns Platz finden k\u00f6nnen. Ein passendes Geh\u00e4use f\u00fcr eine Powerbank w\u00e4re auch ganz nett.<\/li><\/ul>\n\n\n\n<h2>Modularit\u00e4t<\/h2>\n\n\n\n<p>Aus (A) und (B) ergibt sich, dass wir ein eigenes kleines Geh\u00e4use f\u00fcr das Rechnermodul schaffen m\u00fcssen. Aus (A), (D) und (F) ergibt sich, dass wir einen separaten Tr\u00e4ger f\u00fcr die LEDs ben\u00f6tigen, der steckbar mit dem Rechnergeh\u00e4use verbunden wird. Aus (B), (F) und (G) ergibt sich, dass der Stern eine Steckverbindung zu dem Rechnergeh\u00e4use aufweisen soll. Aus (G) folgt, dass ein leeres Rechnergeh\u00e4use im Inneren des Sterns als mechanisches Verbindungselement zum LED-Tr\u00e4ger dient, falls der Rechner selbst au\u00dferhalb positioniert ist. Aus (D) leiten wir ab, dass der Stern aus zwei zusammensteckbaren H\u00e4lften bestehen soll.<\/p>\n\n\n\n<h2>Mechanische Bestandteile<\/h2>\n\n\n\n<ul><li>Rechner, USB-Zwischenstecker, USB-Kabel<\/li><li>Rechnergeh\u00e4use mit Deckel<\/li><li>LED-Tr\u00e4ger, LED-Streifen, Verbindungskabel<\/li><li>zwei sternf\u00f6rmige Halbschalen; eine davon besitzt eine Halterung zur Verbindung mit dem Rechnergeh\u00e4use<\/li><\/ul>\n\n\n\n<h2>Der Steuercomputer<\/h2>\n\n\n\n<p>Der Steuerrechner soll m\u00f6glichst klein sein und wenig Strom verbrauchen, muss aber \u00fcber WLAN verf\u00fcgen. Wir benutzen ein SoC (System on a Chip) auf Basis des ESP32. Das ist ein sehr preiswerter, aber dennoch ziemlich leistungsf\u00e4higer Rechner, der den Vorteil hat, dass man ihn \u00fcber die weit verbreitete und kostenlose Arduino-Entwicklungsumgebung mit C bzw. C++ programmieren kann.<\/p>\n\n\n\n<p>In der barebone-Ausf\u00fchrung haben solche SoCs keine USB Schnittstelle. Man muss dann eine zus\u00e4tzliche Adapter-Platine benutzen, um die Software auf den Rechner zu \u00fcbertragen. Das Bild zeigt den kleineren Bruder des ESP32, den ESP8266 (obere Platine) und einen USB-Adapter (untere Platine). Im fertigen Ger\u00e4t sitzt nur der ESP8266, kleiner als eine Briefmarke&#8230;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"480\" height=\"241\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/esp8266-1.jpg\" alt=\"\" class=\"wp-image-325\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/esp8266-1.jpg 480w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/esp8266-1-300x151.jpg 300w\" sizes=\"(max-width: 480px) 100vw, 480px\" \/><\/figure>\n\n\n\n<p>Wesentlich einfacher ist es f\u00fcr unser Projekt, ein sog. Entwicklungsmodul zu benutzen. Am bequemsten ist es mit dem (sehr preiswerten) LILY TTGO. Er hat eine USB-Schnittstelle, einen kleinen TFT Screen, WLAN und Bluetooth, zwei Buttons, einen Magnetsensor, einen Reset-Taster und man kann \u00fcber eine Stiftleiste auf zahlreiche GPIO Pins zugreifen. Das Board hat sogar noch einen Akku-Anschluss und eine passende Ladeschaltung dazu.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"1024\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_124539-1024x1024.jpg\" alt=\"\" class=\"wp-image-274\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_124539-1024x1024.jpg 1024w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_124539-300x300.jpg 300w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_124539-150x150.jpg 150w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_124539-768x768.jpg 768w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_124539-1536x1536.jpg 1536w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_124539-2048x2048.jpg 2048w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_124539-850x850.jpg 850w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>Ansicht der UNTERSEITE &#8212; Die USB-C-Buchse ist am linke Seitenrand.<br>Der wei\u00dfe Adapter ist f\u00fcr den Anschluss eines 3.7 Volt-Lithium-Akkus vorgesehen. <br>Den schwarzen Winkeladapter haben wir so angel\u00f6tet, dass die Stifte nach innen zeigen.<\/figcaption><\/figure>\n\n\n\n<p>Wir benutzen die ersten 4 Pins neben der USB-Buchse: +5Volt, Ground, Pin 27 und Pin 26). Pin 26 dient uns als Datenleitung f\u00fcr den LED-Streifen, Pin 27 eignet sich f\u00fcr ein optionales Bedienelement. An diesen Pin kann man n\u00e4mlich (anders als bei Pin 26) sogar einen <a href=\"https:\/\/randomnerdtutorials.com\/esp32-touch-pins-arduino-ide\/\">touch-Sensor<\/a> anschlie\u00dfen. <\/p>\n\n\n\n<p>Zusammen mit dem Rechnermodul erh\u00e4lt man eine gerade Steckerleiste. Wir verwenden sie nicht, sondern l\u00f6ten eine gewinkelte Steckerleiste mit den Anschl\u00fcssen nach innen auf. So bleibt die Baueinheit sch\u00f6n kompakt.<\/p>\n\n\n\n<p>Wollen wir noch mehr Sensoren anschlie\u00dfen, so sollten wir allerdings alle Pins des ESP32 mit (geraden oder gewinkelten) L\u00f6tstiften ausstatten. <\/p>\n\n\n\n<p>Im Bild haben wir nur ein Kabel aufgesteckt:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"713\" height=\"373\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/esp-pin.jpg\" alt=\"\" class=\"wp-image-316\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/esp-pin.jpg 713w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/esp-pin-300x157.jpg 300w\" sizes=\"(max-width: 713px) 100vw, 713px\" \/><\/figure>\n\n\n\n<p>Der LILY TTGO hat einen USB-C-Anschluss. Wir k\u00f6nnten dort direkt ein Kabel hineinstecken. Aus mechanischen Gr\u00fcnden benutzen wir jedoch einen Zwischenstecker, der auf der einen Seite in den TTGO passt und auf der anderen Seite eine Micro-USB-Buchse bietet. Um den Weihnachtsstern mit Strom zu versorgen, kann man auf ein billiges und meist ohnehin vorhandenes USB-Ladeger\u00e4t mit Micro-USB-Kabel zur\u00fcckgreifen.<\/p>\n\n\n\n<h2>Rechnergeh\u00e4use (TTGO Box)<\/h2>\n\n\n\n<p>Die TTGO Box nimmt den Rechner fest auf (Klemmsitz) und besitzt (siehe Anforderung (B)) Kabelausl\u00e4sse an drei Seiten und im Boden. Sie erlaubt Zugang zu dem Reset-Taster, der seitlich auf der Platine angebracht ist und zu den beiden Tastern auf der Platine unterhalb des Displays. Das Geh\u00e4use hat Au\u00dfenma\u00dfe von 28.6 mm x 60 mm. Es ist 13 mm hoch (ohne Deckel). Der Au\u00dfenbereich vom Boden bis zu 4mm H\u00f6he dient der Klemm-Befestigung des Rechners. Der Bereich dar\u00fcber dient zur Verbindung mit dem Deckel bzw. mit anderen Elementen, in unserem Fall mit dem LED-Tr\u00e4ger.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"423\" height=\"334\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ttgo-box.png\" alt=\"\" class=\"wp-image-296\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ttgo-box.png 423w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ttgo-box-300x237.png 300w\" sizes=\"(max-width: 423px) 100vw, 423px\" \/><\/figure>\n\n\n\n<p>F\u00fcr jeden Rechner, den wir alternativ benutzen wollen (siehe Anforderung (C)), muss ein eigenes Geh\u00e4use entworfen werden. Die Abmessungen der TTGO Box sind so gew\u00e4hlt, dass der LILY TTGO genau darin Platz hat. Andere ESP-32-Development Boards sind in der Regel kleiner und finden daher ebenfalls Platz. Wollte man allerdings einen Arduino als Steuerrechner verwenden, so m\u00fcsste dieser au\u00dferhalb des Sterns platziert werden. Ein Arduino ist n\u00e4mlich erheblich gr\u00f6\u00dfer, zumal man auch noch ein Zusatzmodul verwenden m\u00fcsste, um die WLAN-Verbindung herzustellen.<\/p>\n\n\n\n<p>Ein geschlossener Deckel k\u00f6nnte n\u00fctzlich sein, wenn der TFT-Screen nicht ben\u00f6tigt wird. Ein Deckel mit Display-Aussparung und mit kleinen L\u00f6chern f\u00fcr die beiden Taster wird uns zur Befestigung des LED-Tr\u00e4gers dienen. Wir k\u00f6nnen dann das TFT-Display als zus\u00e4tzliches zentrales Licht in besonderen F\u00e4llen einsetzen. Au\u00dferdem kann es w\u00e4hrend der Entwicklungszeit f\u00fcr Kontroll-Ausgaben benutzt werden (&#8222;Debugging&#8220;).<\/p>\n\n\n\n<p>Der USB-Anschluss liegt an der Schmalseite (im Bild: vorn). Wir verwenden einen USB-C-zu Micro-USB-Adapter, um den Rechner mechanisch zu fixieren. Dies ist ganz praktisch und schafft sehr viel mechanische Stabilit\u00e4t; man k\u00f6nnte es aber auch anders machen.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"749\" height=\"927\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/box.jpg\" alt=\"\" class=\"wp-image-301\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/box.jpg 749w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/box-242x300.jpg 242w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/box-300x371.jpg 300w\" sizes=\"(max-width: 749px) 100vw, 749px\" \/><\/figure>\n\n\n\n<p>Die TTGO Box wird mit ONSHAPE entworfen und mit wei\u00dfem PLA gedruckt. Wir benutzen, wie bereits gesagt, die ersten vier Pins rechts vorn und f\u00fchren das Kabel in einem leichten Bogen innerhalb des Geh\u00e4uses rechts im hinteren Bereich heraus. Das Geh\u00e4use sitzt ziemlich knapp. Eventuell muss man in den Ecken mit einer kleinen Feile etwas Grat entfernen, damit die mechanische Beanspruchung der Platine beim vorsichtigen Hineindr\u00fccken nicht zu gro\u00df ist. Um die Platine wieder herauszubekommen, f\u00e4hrt man vorsichtig mit einem kleinen Schraubendreher in den Schlitz an der oberen hinteren Stirnseite und hebelt ein wenig.<\/p>\n\n\n\n<p>Man dr\u00fcckt die Platine so tief hinein, dass der USB-C-Anschluss genau mittig hinter der Aussparung liegt. Dann wird der schwarze Adapter hineingedr\u00fcckt und sitzt dann ziemlich fest in dem Geh\u00e4use. Wenn man an dem wei\u00dfen Stecker zieht, l\u00f6st sich der Stecker vom Adapter; der Adapter bleibt jedoch fest im TTGO stecken. An der rechten Seite sieht man die Aussparung  f\u00fcr den Reset Knopf.<\/p>\n\n\n\n<p>Damit ist das erste Modul fertig. Seine Schnittstellen sind das Geh\u00e4use, der USB-Adapter, der Reset-Taster, die beiden Buttons, der Hall-Sensor (zur Magnetfeld-Erkennung) und das Display.<\/p>\n\n\n\n<h2>Der LED-Tr\u00e4ger<\/h2>\n\n\n\n<p>Wir konstruieren ein regelm\u00e4\u00dfiges Polygon (5 oder 7 Ecken), so dass auf jeder Au\u00dfenfl\u00e4che genau 2 LEDs eines LED-Streifens (60 LEDs\/Meter) Platz haben. Das Polygon dient gleichzeitig als Deckel der TTGO Box. Der Umfang des Polygons ist ein Vielfaches von 33.3 mm, wobei die Ecken au\u00dfen mit 1mm verrundet sind.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"702\" height=\"567\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/led-carrier.png\" alt=\"\" class=\"wp-image-303\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/led-carrier.png 702w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/led-carrier-300x242.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/figure>\n\n\n\n<p>Man erkennt links vorn die Aussparung f\u00fcr den USB-Adapter. Sie sitzt an einer Spitze des Polygons, damit sie sp\u00e4ter mittig zwischen zwei Armen des Sterns herauskommt, denn die Arme sitzen wiederum mittig auf den Polygonfl\u00e4chen. Man k\u00f6nnte bei der Konstruktion das Polygon auch so gegen\u00fcber dem Deckel verdrehen, dass der USB-Auslass in der Mitte einer Polygon-Seite liegt. Dann w\u00fcrde allerdings das USB-Kabel im Inneren des Sterns bis zur Spitze eines Arms laufen, was optisch st\u00f6ren w\u00fcrde. <\/p>\n\n\n\n<p>Rechts an der Seite ist ein Durchbruch f\u00fcr die drei Dr\u00e4hte, die an den LED-Streifen angel\u00f6tet werden. An der Oberseite sieht man die Aussparungen f\u00fcr das Display und die beiden Buttons. An der Seite des Deckels, nahe bei den Buttons ist die Aussparung f\u00fcr den Reset-Taster.<\/p>\n\n\n\n<p>Der Deckel sitzt durch Klemmpassung (0.2 mm Toleranz) ziemlich fest auf der TTGO-Box.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"925\" height=\"695\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/step2.jpg\" alt=\"\" class=\"wp-image-306\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/step2.jpg 925w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/step2-300x225.jpg 300w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/step2-768x577.jpg 768w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/step2-850x639.jpg 850w\" sizes=\"(max-width: 925px) 100vw, 925px\" \/><\/figure>\n\n\n\n<p>Den Deckel mit dem LED-Halter haben wir im Bild provisorisch auf die TTGO-Box gesteckt. Das Kabel wird zum Testen mit einem LED-Streifen verbunden. Die Buttons und der Reset-Taster k\u00f6nnen mit einem spitzen Gegenstand bet\u00e4tigt werden. Dies kann w\u00e4hrend der Software-Entwicklung n\u00fctzlich sein &#8211; sp\u00e4ter werden sie nicht mehr gebraucht.<\/p>\n\n\n\n<p>Im n\u00e4chsten Schritt montieren wir den LED-Streifen. Beim Einbau muss man die aufgedruckte Pfeilrichtung beachten. Unsere drei Kabel werden an der Eingangsseite angel\u00f6tet. Die Ausgangsseite wird nicht verbunden (bei gr\u00f6\u00dferen Streifen w\u00fcrde man die \u00e4u\u00dferen Kabel der Ausgangsseite zus\u00e4tzlich mit GND und 5V verbinden). Wir schneiden 10 bzw. 14 LEDs von der Rolle ab ab und zwar nicht genau in der Mitte, sondern so, dass die Kontaktfl\u00e4chen an der START-Seite des Streifens etwas l\u00e4nger sind und am Ende etwas k\u00fcrzer. Auf diese Weise ist die L\u00f6tfl\u00e4che etwas gr\u00f6\u00dfer. Wichtig ist, die Lackschicht bei den Kontakten mechanisch zu entfernen, bevor man l\u00f6tet. Ein scharfes Messer oder eine Schere k\u00f6nnen zum Schaben eingesetzt werden. Es geht auch mit feinem Schleifpapier. Dann verzinnen wir die drei Kontaktfl\u00e4chen mit etwas Lot.<\/p>\n\n\n\n<p>Wir k\u00fcrzen die Adern 1,2,4 auf  5-6cm, isolieren sie ab und verzinnen sie d\u00fcnn. Wir benutzen also +5V, GND und Pin #26. Die Ader von Pin #27 lassen wir etwas l\u00e4nger und isolieren sie nicht ab. Sie bleibt vorl\u00e4ufig ungenutzt. Wir k\u00f6nnen sp\u00e4ter einen Touch-Sensor daran anschlie\u00dfen, wenn wir wollen.  <\/p>\n\n\n\n<p>Dann f\u00fchren wir die drei ben\u00f6tigten Kabel durch den Schlitz bis sie ganz heraush\u00e4ngen; das Kabel von Pin #27 bleibt im Inneren des Polygons.<\/p>\n\n\n\n<p>Nun l\u00f6ten wir die drei Adern in der richtigen Zuordnung auf den Streifen. Achtung: Beim L\u00f6ten darf der Streifen keinen Kontakt zu dem LED-Tr\u00e4ger haben, denn das PLA w\u00fcrde sofort weich werden und sich verformen.<\/p>\n\n\n\n<p>Abschlie\u00dfend wird das Kabel durch den Schlitz zur\u00fcckgedr\u00fcckt und der Streifen aufgeklebt. Wir sollten ihn an den Kanten sauber knicken, bevor wir den Klebestreifen abziehen, damit er sich gut anlegt. Eventuell fixieren wir das Ende mit einem Tesafilm, damit es nicht wieder aufsteht.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"876\" height=\"605\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ledstrip.jpg\" alt=\"\" class=\"wp-image-319\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ledstrip.jpg 876w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ledstrip-300x207.jpg 300w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ledstrip-768x530.jpg 768w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ledstrip-850x587.jpg 850w\" sizes=\"(max-width: 876px) 100vw, 876px\" \/><\/figure>\n\n\n\n<p>Als Luxus k\u00f6nnten wir danach noch die Farben der Dr\u00e4hte dokumentieren, z.B. auf einem kleinen Schild, das am Ende die \u00d6ffnung f\u00fcr die Buttons an der TTGO Box abdeckt. Hier kommt man allerdings schnell an die Aufl\u00f6sungsgrenzen des 3D-Drucks. Wir benutzen die \u00fcbliche 0.4 mm D\u00fcse. Also empfiehlt es sich, Fettschrift einzusetzen und mit Zeichen zu sparen.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"546\" height=\"205\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/plate.png\" alt=\"\" class=\"wp-image-309\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/plate.png 546w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/plate-300x113.png 300w\" sizes=\"(max-width: 546px) 100vw, 546px\" \/><\/figure>\n\n\n\n<h2>Der Stern<\/h2>\n\n\n\n<p>Der Stern besteht aus zwei Halbschalen, die durch Klemmpassung zusammengehalten werden. Wir bevorzugen aus \u00e4sthetischen Gr\u00fcnden eine ungerade Zahl von Armen und f\u00fchren das Versorgungskabel zwischen zwei Armen des Sterns heraus. Man k\u00f6nnte auch noch einen Kometenschweif hinzuf\u00fcgen.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"631\" height=\"395\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/star-parts.png\" alt=\"\" class=\"wp-image-321\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/star-parts.png 631w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/star-parts-300x188.png 300w\" sizes=\"(max-width: 631px) 100vw, 631px\" \/><\/figure>\n\n\n\n<p>Wir konstruieren den Stern so, dass das Polygon mit den LEDs einen kleinen Abstand von den inneren Ecken hat. Auf diese Weise ergeben sich weiche Farbverl\u00e4ufe an den \u00dcbergangsstellen und dennoch sind die Arme des Sterns farblich deutlich getrennt. <\/p>\n\n\n\n<p>Die Au\u00dfenw\u00e4nde des Sterns sollen m\u00f6glichst d\u00fcnn sein (ca. 2 mm), damit das Licht gut durchscheint. Dann bleibt f\u00fcr das Zusammenstecken eine Wanddicke von 0.9 mm \u00fcbrig (plus jeweils 0.1 mm Toleranz f\u00fcr die Klemmpassung). F\u00fcr die Deckfl\u00e4chen auf der Vorder- und R\u00fcckseite gen\u00fcgen 0.6 mm Dicke.<\/p>\n\n\n\n<p>Im Bild ist der Stern nur angedeutet durch eine Bodenplatte mit sieben Zacken (die Zacken sind zu klein und zu nah an dem Polygon). Man sieht die Schlaufe des Kabels, das zu dem LED-Streifen f\u00fchrt; das Kabel von Pin 27 ist in einen kleinen Schlauch rechts daneben versteckt. Der Rechner ist in Betrieb, das Display zeigt Testausgaben.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"733\" height=\"684\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/star.jpg\" alt=\"\" class=\"wp-image-318\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/star.jpg 733w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/star-300x280.jpg 300w\" sizes=\"(max-width: 733px) 100vw, 733px\" \/><\/figure>\n\n\n\n<p>Hier die fertige Version mit 5 Zacken. Die kleine Powerbank liefert f\u00fcr einige Stunden Energie.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"1024\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_200557-1024x1024.jpg\" alt=\"\" class=\"wp-image-270\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_200557-1024x1024.jpg 1024w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_200557-300x300.jpg 300w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_200557-150x150.jpg 150w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_200557-768x768.jpg 768w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_200557-1536x1536.jpg 1536w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_200557-2048x2048.jpg 2048w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/11\/20201127_200557-850x850.jpg 850w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2>Wetterfeste Ausf\u00fchrung<\/h2>\n\n\n\n<p>F\u00fcr den Au\u00dfeneinsatz kann man spezielle Ausf\u00fchrungen des LED-Streifens verwenden. Man sollte dann allerdings den Rechner au\u00dferhalb des Sterns unterbringen, um ihn besser gegen Feuchtigkeit kapseln zu k\u00f6nnen. Das hat den zus\u00e4tzlichen Vorteil, dass man mehrere Sterne mit einem einzigen Rechner steuern kann. Man ben\u00f6tigt dann dreiadrige Leitungen zur Verbindung zwischen dem Rechner und den Sternen.<\/p>\n\n\n\n<h2>Touch-Sensoren<\/h2>\n\n\n\n<p>Mechanische Tasten einzubauen ist m\u00fchsam und teuer. Man muss zu jeder Taste zwei Stromleitungen f\u00fchren und wetterfest sind Taster auch nicht. Gl\u00fccklicherweise k\u00f6nnen manche Eing\u00e4nge des LILY TTGO kapazitive Ladungs\u00e4nderungen erkennen, die entstehen, wenn man als Mensch den Eingang mit der Hand ber\u00fchrt. Es gen\u00fcgt daher, von diesen Eing\u00e4ngen aus jeweils einen Draht zu den Spitzen des Sterns zu f\u00fchren.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"601\" height=\"587\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/touch.jpg\" alt=\"\" class=\"wp-image-333\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/touch.jpg 601w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/touch-300x293.jpg 300w\" sizes=\"(max-width: 601px) 100vw, 601px\" \/><\/figure>\n\n\n\n<p>Der Draht wird von innen durch einen &#8222;Hohlsaum&#8220; in der Seitenwand gesteckt. Dann biegt man eine kleine \u00d6se und zieht den Draht zur\u00fcck, bis die \u00d6se fest anliegt. Bei CAD-Design muss man darauf achten, dass in dem langen, d\u00fcnnen Tunnel f\u00fcr den Draht kein Support gedruckt wird. Man schr\u00e4gt dazu das Dach wie einen Giebel einseitig oder symmetrisch an. F\u00fcr Winkel bis 45 Grad wird normalerweise kein Support beim Slicing erzeugt. Man kann diese Grenze in den Einstellungen von CURA bis auf 60 Grad hoch setzen.<\/p>\n\n\n\n<p>Wenn man 7 weitere Leitungen an den TTGO anschlie\u00dfen will, muss man allerdings die entsprechenden Pins bereitstellen. In diesem Fall sollte man die Winkelstecker andersherum einl\u00f6ten, so dass die Stifte nach <em>au\u00dfen<\/em> zeigen, Das Geh\u00e4use muss man entsprechend anpassen. Weil die Seitenw\u00e4nde jetzt weitgehend wegfallen, sorgen wir durch ein st\u00e4rkere Bodenplatte, durch eine Fase in Richtung R\u00fcckwand und durch zwei Stege f\u00fcr mehr Stabilit\u00e4t.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"286\" height=\"374\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ttgo-2.png\" alt=\"\" class=\"wp-image-336\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ttgo-2.png 286w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/ttgo-2-229x300.png 229w\" sizes=\"(max-width: 286px) 100vw, 286px\" \/><\/figure>\n\n\n\n<p><em>Soviel zum mechanischen Aufbau. Jetzt fehlt uns noch die Software.<\/em><\/p>\n\n\n\n<p>Es empfiehlt sich, jetzt den <a href=\".\/2020\/12\/02\/esp32-lily-ttgo\/\">Beitrag \u00fcber den LILY TTGO<\/a> zu lesen.<\/p>\n\n\n\n<h2>Programm-Wahl und WLAN<\/h2>\n\n\n\n<p>Der Weihnachtsstern kann (autonom) lokal Farben wechseln. Dabei sollen unterschiedliche Farb-Programme m\u00f6glich sein. Ein eleganter Weg, zwischen den Programmen zu wechseln, besteht darin, dass man einen Magneten kurz an eine bestimmte Stelle des Sterns h\u00e4lt.<\/p>\n\n\n\n<p>Eines der Programme bewirkt, dass der Stern Kommandos von einem anderen Rechner erwartet. Damit er auf diese Weise ferngesteuert werden kann, muss er versuchen, sich mit einem WLAN zu verbinden. Misslingt dieser Versuch, soll er in den lokalen Modus zur\u00fcckfallen.<\/p>\n\n\n\n<p>Kommen l\u00e4ngere Zeit keine Kommandos von dem Steuerrechner, soll der Stern ebenfalls in einen lokalen Modus zur\u00fcckfallen.<\/p>\n\n\n\n<h2>Anforderungen an die Software<\/h2>\n\n\n\n<ol><li>autonomer Betrieb mit sanft wechselnden Farben<\/li><li>Abschaltautomatik nach einigen Stunden??<\/li><li>wechselbare Lichtmuster<\/li><li>WLAN-Verbindung<\/li><li>Erkennung des Schaltmagneten<\/li><li>Empfang von Steuerkommandos \u00fcber WLAN<\/li><\/ol>\n\n\n\n<h2>Version 1<\/h2>\n\n\n\n<p>Das Programm erzeugt ein wanderndes Regenbogen-Muster, das ab und zu die Richtung wechselt. Das Display wird noch nicht angesteuert. Der Magnet wird nicht abgefragt. Es gibt keine LAN-Verbindung. Es gibt nur ein einziges, fest eingebautes Lichtprogramm, den RAINBOW.<\/p>\n\n\n\n<p><em>HINWEIS: <\/em><br><em>Wenn man eines der nachfolgenden Source-Code-Beispiele kopiert und in die Arduino-IDE oder in einen externen Editor einf\u00fcgt, dann muss man die Zeichenkette &#8222;<strong>&amp;amp;<\/strong>&#8220; durch ein einzelnes &#8222;<strong>&amp;<\/strong>&#8220; ersetzen.<br>Die Ursache daf\u00fcr ist, dass das &#8222;<strong>&amp;<\/strong>&#8222;-Zeichen in HTML eine <strong>Sonderbedeutung<\/strong> hat und deshalb als &#8222;<strong>&amp;amp;<\/strong>&#8220; codiert wird (der Browser zeigt es jedoch als einfaches &#8222;<strong>&amp;<\/strong>&#8220; an). <\/em><\/p>\n\n\n\n<div class=\"wp-container-1 wp-block-group\"><div class=\"wp-block-group__inner-container\"><div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n\/\/ A star with softly changing rainbow colors\n\nint NumLeds     = 14;   \/\/ 7 arms with two LEDs per arm\n\n#include &lt;Adafruit_NeoPixel.h&gt;\nAdafruit_NeoPixel strip = Adafruit_NeoPixel(        \/\/ define the LED strip (type WS2812)\n    NumLeds,                                        \/\/ number of color triples\n    26,                                             \/\/ pin connected to the strip\n    NEO_GRB + NEO_KHZ800                            \/\/ 800 kHz bit stream in GRB sequence\n);\n\nunsigned long   speedDelay = 40;    \/\/ 40 msecs x 256 steps ~ 10 seconds per cycle\nbyte            colorPosition;      \/\/ the current color: 0..255 degrees in a color circle\n\nvoid setup() {\n  strip.begin();            \/\/ initialize LED strip\n  colorPosition = 0;        \/\/ start at the top of the circle (red)\n}\n\nvoid loop() {\n    int steps = 500-random(1000);    \/\/ positive = clockwise, negative = counter-clockwise\n    rainbowCycle(speedDelay,steps);  \/\/ walk through the cycle for the given number of steps\n}\n\nvoid rainbowCycle(int speedDelay, int nrSteps) {\n    \/\/ perform the given number of steps (256 steps would be a full cycle)\n    \/\/ negative step numbers walk counter-clockwise\n    \n    byte *c;\n    uint16_t l, j;\n\n    for(j=0; j&lt;abs(nrSteps); j++) {                     \/\/ for each step\n        if (nrSteps&gt;0) {\n            if (++colorPosition&gt;=255) colorPosition=0;  \/\/ increment position (clockwise)\n        }\n        else {\n            if (--colorPosition&lt;0) colorPosition=255;   \/\/ decrement position (counter clockwise)\n        }\n        \/\/ based on the color position divide the circle into NumLed parts\n        \/\/ and assign the suitable color to each LED\n        \/\/ note that this does not yet change the LEDs themselves\n        \/\/ it only assigns values to the internal memory representation of the LEDs\n\n        int factor = 1;     \/\/ you may want to try other values like 2, 5, 10\n        \/\/ if we divided the circle into smaller portions (say, 2*NumLeds),\n        \/\/ only half of the spectrum would be visible at any point in time\n        \/\/ (which also might be nice)\n        \n        for(l=0; l&lt; NumLeds; l++) {\n            c= wheel(((l * 256 \/ NumLeds \/ factor) + colorPosition) % 256);\n            strip.setPixelColor(l, *c, *(c+1), *(c+2));\n        }\n\n        \/\/ now transfer the memory as a bit stream to the LED strip\n        strip.show();\n\n        \/\/ wait before we advance the step counter\n        \/\/ if we show smaller parts of the spectrum we extend the delay\n        \/\/ so that we can enjoy the fine variations of color in peace ;-)\n        delay(speedDelay*factor);\n    }\n}\n\nbyte *wheel(byte wheelPos) {\n    \/\/ implements a color circle (&quot;wheel&quot;) beginning with (1) red, changing to (2) green and (3) to blue\n    \/\/ the wheel if divided into 256 steps, so 0=red, 256\/3=green, 256*2\/3=blue, etc.\n    \/\/ the &lt;wheelPos&gt; parameter is a number between 0..255\n    \/\/ the function returns an RGB array of three bytes\n    \n    static byte c&#x5B;3];   \/\/ the resulting RGB triple\n\n    \/\/ we have three segments (0..84, 85..169, 170..255)\n    \/\/ in each segment one RGB color is completely missing (i.e. it has a value of 0)\n    \/\/ another one is growing from 0..255 and the third color goes down from 255 to 0\n    \/\/ this means that we have equal brightness over the whole spectrum\n\n    if(wheelPos &lt; 85) {             \/\/ first segment 0..84\n        c&#x5B;0]= 255 - wheelPos * 3;   \/\/ declining RED\n        c&#x5B;1]= wheelPos * 3;         \/\/ growing   GREEN\n        c&#x5B;2]= 0;                    \/\/ no        BLUE\n    \n    } else if(wheelPos &lt; 170) {     \/\/ second segment 85..169\n        wheelPos -= 85;             \/\/ make position relative to segment start\n        c&#x5B;0]= 0;                    \/\/ no        RED\n        c&#x5B;1]= 255 - wheelPos * 3;   \/\/ declining GREEN\n        c&#x5B;2]= wheelPos * 3;         \/\/ growing   BLUE\n        \n    } else {                        \/\/ third segment  170..255\n        wheelPos -= 170;            \/\/ make position relative to segment start\n        c&#x5B;0]= wheelPos * 3;         \/\/ growing   RED\n        c&#x5B;1]= 0;                    \/\/ no        GREEN \n        c&#x5B;2]= 255 - wheelPos * 3;   \/\/ declining BLUE\n    }\n\n    return c;                       \/\/ return the RGB triple\n}\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"731\" height=\"342\" src=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/03.jpg\" alt=\"\" class=\"wp-image-373\" srcset=\"https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/03.jpg 731w, https:\/\/followthescore.org\/schueler-labor\/wp-content\/uploads\/2020\/12\/03-300x140.jpg 300w\" sizes=\"(max-width: 731px) 100vw, 731px\" \/><figcaption>Zur Illustration hier ein beispielhafter Farbkreis; es geht oben mit &#8222;rot&#8220; los; dann folgen im Uhrzeigersinn gelb (als Mischfarbe aus rot und gr\u00fcn, dann gr\u00fcn und  t\u00fcrkis (Mischung von gr\u00fcn und blau), dann blau und violett (Mischung von blau und rot). Bei unserer Art der Berechnung ist gr\u00fcn allerdings bereits bei 120\u00b0 erreicht, also nach einem Drittel-Kreis; man sieht, dass es nicht &#8222;den&#8220; Farbkreis gibt, sondern viele Spielarten.<\/figcaption><\/figure>\n<\/div><\/div>\n\n\n\n<h2>Version 2<\/h2>\n\n\n\n<p>Wir f\u00fcgen ein zweites Lichtmuster hinzu, das einen farbigen Lichtfleck kreisen l\u00e4sst.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nvoid runningDots(int speedDelay, int nrSteps) {\n    \/\/ move a colored dot around and change its color every full round\n\n    int l=0;                \/\/ current LED\n    byte *rgb;              \/\/ red, green ,blue\n    unsigned long color;    \/\/ color of running pixel\n\n    for(int n=0;n&amp;lt;nrSteps;n++) {\n        \n        \/\/ at the beginning of a new cycle: switch color\n        if (l==0) {\n            rgb=wheel(random(255));\n            color= strip.Color(rgb&#x5B;0],rgb&#x5B;1],rgb&#x5B;2]);\n        }\n        \n        strip.setPixelColor(l,0);           \/\/ switch off current LED\n        l=(l+1) % NumLeds;                  \/\/ advance to next LED\n        strip.setPixelColor(l,color);       \/\/ set color for next LED\n        strip.show();                       \/\/ transfer LED settings to the strip\n        delay(speedDelay);                  \/\/ wait a moment\n    }\n}\n\n<\/pre><\/div>\n\n\n<h2>Version 3<\/h2>\n\n\n\n<p>Wir schlie\u00dfen Dr\u00e4hte an diejenigen Pins des TTGO an, die eine kapazitive Ladungs\u00e4nderung erkennen k\u00f6nnen (&#8222;Touch-Pins&#8220;). Wir bauen das Programm so um, dass man duch das Ber\u00fchren der Dr\u00e4hte die Farbeffekte beeinflussen kann.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ A star with rainbow colors rotating at adjustable speed\n  \nint NumLeds         = 14;                       \/\/ 7 arms with two LEDs per arm\nint touchPins&#x5B;]     = {32,27,12,13,15,2,33,20}; \/\/ arms 0 .. 7\n \n#include &amp;lt;Adafruit_NeoPixel.h&gt;\n \nAdafruit_NeoPixel strip = Adafruit_NeoPixel(    \/\/ define the LED strip (type WS2812)\n    NumLeds,                                    \/\/ number of color triples\n    26,                                         \/\/ pin connected to the strip\n    NEO_GRB + NEO_KHZ800                        \/\/ 800 kHz bit stream in GRB sequence\n);\n \nbyte colorPosition = 0;         \/\/ the current position of the color wheel; 0 = red\n  \nvoid setup() {\n    Serial.begin(115200);       \/\/ for monitoring\n    delay(100);\n     \n    strip.begin();              \/\/ initialize LED strip\n \n    rainbowCycle();             \/\/ start the cycle\n}\n  \nvoid loop() {\n}\n  \nvoid rainbowCycle() {\n      \n    byte *c;\n    uint16_t l, j;\n \n    unsigned long   speedDelay  = 50;   \/\/ delay between iterations\n    int             gap         =  1;   \/\/ gap between color increments\n    int             segment     = 10;   \/\/ segment size of color circle \n                                        \/\/ (10=full, 20=half, ..)\n     \n    for(;;) {   \/\/ forever\n         \n        \/\/ increment color position\n        colorPosition= (colorPosition+gap) % 256;\n \n        \/\/ based on the color position divide the circle into NumLed parts\n        \/\/ and assign the suitable color to each LED\n        \/\/ note that this does not yet change the LEDs themselves\n        \/\/ it only assigns values to the internal memory representation \n        \/\/ of the LEDs\n  \n        \/\/ if we divide the circle into smaller portions (e.g. segment=20),\n        \/\/ only half of the spectrum would be visible at any point in time\n \n          \n        for(l=0; l&amp;lt; NumLeds; l++) {\n            c= wheel(((l * 256 \/ NumLeds * 10 \/ segment) \n                + colorPosition) % 256\n            );\n            strip.setPixelColor(l, *c, *(c+1), *(c+2));\n        }\n  \n        \/\/ now transfer the memory as a bit stream to the LED strip\n        strip.show();\n  \n        \/\/ check touch sensors\n        if (touched(1) &amp;amp;&amp;amp; speedDelay&amp;lt;1000) speedDelay++;     \/\/ slower\n        if (touched(2) &amp;amp;&amp;amp; speedDelay&gt;   1) speedDelay--;\n        if (touched(3) &amp;amp;&amp;amp; gap&gt;1           ) gap--;           \/\/ closer\n        if (touched(4) &amp;amp;&amp;amp; gap&amp;lt;100         ) gap++;\n        if (touched(5) &amp;amp;&amp;amp; segment&gt;1       ) segment--;       \/\/ smaller\n        if (touched(6) &amp;amp;&amp;amp; segment&amp;lt;50  ) segment++;\n        if (touched(0) ) { \n            speedDelay=random(20); \n            gap=random(10); \n            segment=random(10); \n        }\n \n        Serial.println(\n            &quot;delay=&quot;+String(speedDelay)+\n            &quot;  gap=&quot;+String(gap)+\n            &quot;  segment=&quot;+String(segment)\n        );\n  \n        \/\/ wait before we advance the step counter        \n        delay(speedDelay);\n    }\n}\n  \nbyte *wheel(byte wheelPos) {\n    \/\/ implements a color circle (&quot;wheel&quot;) beginning with \n    \/\/     (1) red, changing to (2) green and (3) to blue\n    \/\/ the wheel if divided into 256 steps, \n    \/\/     so 0=red, 256\/3=green, 256*2\/3=blue, etc.\n    \/\/ the &amp;lt;wheelPos&gt; parameter is a number between 0..255\n    \/\/ the function returns an RGB array of three bytes\n      \n    static byte c&#x5B;3];   \/\/ the resulting RGB triple\n  \n    \/\/ we have three segments (0..84, 85..169, 170..255)\n    \/\/ in each segment one RGB color is completely missing \n    \/\/ (i.e. it has a value of 0)\n    \/\/ another one is growing from 0..255 and the third color \n    \/\/ goes down from 255 to 0\n    \/\/ this means that we have equal brightness \n    \/\/ over the whole spectrum\n  \n    if(wheelPos &amp;lt; 85) {             \/\/ first segment 0..84\n        c&#x5B;0]= 255 - wheelPos * 3;   \/\/ declining RED\n        c&#x5B;1]= wheelPos * 3;         \/\/ growing   GREEN\n        c&#x5B;2]= 0;                    \/\/ no        BLUE\n      \n    } else if(wheelPos &amp;lt; 170) {     \/\/ second segment 85..169\n        wheelPos -= 85;             \/\/ make position relative to segment\n        c&#x5B;0]= 0;                    \/\/ no        RED\n        c&#x5B;1]= 255 - wheelPos * 3;   \/\/ declining GREEN\n        c&#x5B;2]= wheelPos * 3;         \/\/ growing   BLUE\n          \n    } else {                        \/\/ third segment  170..255\n        wheelPos -= 170;            \/\/ make position relative to segment\n        c&#x5B;0]= wheelPos * 3;         \/\/ growing   RED\n        c&#x5B;1]= 0;                    \/\/ no        GREEN \n        c&#x5B;2]= 255 - wheelPos * 3;   \/\/ declining BLUE\n    }\n  \n    return c;                       \/\/ return the RGB triple\n}\n \nboolean touched(int arm) {\n    int t= touchRead(touchPins&#x5B;arm]);\n    if (t==0) return false;\n    if (t&amp;lt; 30) {       \/\/ a reasonable threshold is 30\n        delay(100);    \/\/ wait a moment so the user can release the touch\n        return true;        \n    }\n    return false;\n}\n\n<\/pre><\/div>\n\n\n<h2>Version 4<\/h2>\n\n\n\n<p>Wir nehmen das TFT Display in Betrieb und zeigen dort st\u00e4ndig die aktuellen Einstellungen an.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ A star with rainbow colors rotating at adjustable speed\n\/\/ settings are shown on the TFT display\n\/\/ note that the library for the TFT must have been installed in the Arduino IDE\n \n\/\/ ===================== DISPLAY ==============\n \n#include &amp;lt;SPI.h&gt;                                  \/\/ SPI interface for TFT display\n#include &amp;lt;TFT_eSPI.h&gt;                                 \/\/ Hardware-specific TFT library                                \nTFT_eSPI tft = TFT_eSPI();                          \/\/ define a variable for the TFT display\n \n#define NUM_ARMS  7                                 \/\/ the star has 7 arms (&quot;legs&quot;)\n#define NUM_LEDS (2*NUM_ARMS)                       \/\/ we have two LEDs per arm\n \n\/\/ ===================== LED STRIP ============\n \n#include &amp;lt;Adafruit_NeoPixel.h&gt;\nAdafruit_NeoPixel strip = Adafruit_NeoPixel(        \/\/ define the LED strip (type WS2812)\n    NUM_LEDS,                                       \/\/ number of color triples\n    26,                                             \/\/ the pin# connected to the strip\n    NEO_GRB + NEO_KHZ800                            \/\/ 800 kHz bit stream in GRB sequence\n);\nbyte colorPosition  = 0;                            \/\/ initial position of color wheel (0 = red)\n \n\/\/ ===================== TOUCH PINS ===========\n \nint touchPins&#x5B;] = {32,27,12,13,15,2,33,20};         \/\/ pins (#0..#6) connectesd to touch contacts\n \n\/\/ ===================== SETUP ================\n  \nvoid setup() {\n    Serial.begin(115200);                           \/\/ for monitoring\n    delay(100);\n \n    tft.begin();                                    \/\/ initialize, 240 x 135 pixels (~ 20x4 chars)\n    tft.setRotation(1);                             \/\/ 1=landscape orientation\n    tft.setTextDatum(TL_DATUM);                     \/\/ top left reference point for texts\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);         \/\/ white on black\n    tft.fillScreen(TFT_BLACK);                      \/\/ clear screen, all black\n    tft.setFreeFont(&amp;amp;FreeSans12pt7b);               \/\/ fairly large font (allows for 4 lines)\n     \n    strip.begin();                                  \/\/ initialize LED strip\n \n    rainbowCycle();                                 \/\/ start the cycle\n}\n  \nvoid loop() {\n    \/\/ we never get here because rainbowCycle contains and endless loop\n}\n \n\/\/ ===================== RAINBOW ================\n  \nvoid rainbowCycle() {\n     \n    \/\/ initial settings:\n    unsigned long   speedDelay  = 50;   \/\/ delay between iterations in msecs\n    int             gap         =  1;   \/\/ gap between color increments (wheel steps)\n    int             segment     = 10;   \/\/ segment size of color circle (10=full, 20=half, ..)\n     \n    byte *c;                            \/\/ a triple of color values obtained from the wheel\n \n    tftPrint(0,&quot;Rotating Rainbow&quot;);\n \n    for(;;) {   \/\/ forever\n         \n        colorPosition = (colorPosition+gap) % 256;      \/\/ increment color position\n \n        \/\/ divide the circle into equi-distant colors for the LEDs\n        \/\/ if segments==10 use full spectrum, else use less (e.g. 10%) or more (eg 200%)\n        \/\/ assign a color to each LED starting from the current color position\n          \n        for(int l=0; l&amp;lt; NUM_LEDS; l++) {\n            c= wheel(((l * 256 \/ NUM_LEDS * 10 \/ segment) + colorPosition) % 256);\n            strip.setPixelColor(l, *c, *(c+1), *(c+2));\n        }\n  \n        strip.show();               \/\/ now transfer the LED memory to the LED strip\n  \n        \/\/ check touch sensors and modify settings if desired\n        if (touched(1) &amp;amp;&amp;amp; speedDelay&amp;lt;1000) speedDelay++;     \/\/ slower\n        if (touched(2) &amp;amp;&amp;amp; speedDelay&gt;   1) speedDelay--;\n        if (touched(3) &amp;amp;&amp;amp; gap&gt;1           ) gap--;           \/\/ closer\n        if (touched(4) &amp;amp;&amp;amp; gap&amp;lt;100         ) gap++;\n        if (touched(5) &amp;amp;&amp;amp; segment&gt;1       ) segment--;       \/\/ smaller\n        if (touched(6) &amp;amp;&amp;amp; segment&amp;lt;50  ) segment++;\n        if (touched(0) ) { \n            speedDelay=random(20); \n            gap=random(10); \n            segment=random(10); \n        }\n        \n        \/\/ show current settings for debugging on serial line\n        Serial.println(&quot;delay=&quot;+String(speedDelay)+&quot;  gap=&quot;+String(gap)+&quot;  segment=&quot;+String(segment));\n \n        \/\/ show current settings for the user on the TFT display\n        tftPrint(1,&quot;speed =&quot;+String(speedDelay));\n        tftPrint(2,&quot;gap  =&quot;+String(gap));\n        tftPrint(3,&quot;segment =&quot;+String(segment));\n         \n        \/\/ wait for the configured time (msecs)        \n        delay(speedDelay);\n    }\n}\n \n\/\/ ===================== COLOR WHEEL ================\n  \nbyte *wheel(byte wheelPos) {\n    \/\/ implements a color circle (&quot;wheel&quot;) beginning with (1) red, changing to (2) green and (3) to blue\n    \/\/ the wheel if divided into 256 steps, so 0=red, 256\/3=green, 256*2\/3=blue, etc.\n    \/\/ the &amp;lt;wheelPos&gt; parameter is a number between 0..255\n    \/\/ the function returns an RGB array of three bytes\n      \n    static byte c&#x5B;3];   \/\/ the resulting RGB triple\n  \n    \/\/ we have three segments (0..84, 85..169, 170..255)\n    \/\/ in each segment one RGB color is completely missing (i.e. it has a value of 0)\n    \/\/ another one is growing from 0..255 and the third color goes down from 255 to 0\n    \/\/ this means that we have equal brightness over the whole spectrum\n  \n    if(wheelPos &amp;lt; 85) {             \/\/ first segment 0..84\n        c&#x5B;0]= 255 - wheelPos * 3;   \/\/ declining RED\n        c&#x5B;1]= wheelPos * 3;         \/\/ growing   GREEN\n        c&#x5B;2]= 0;                    \/\/ no        BLUE\n      \n    } else if(wheelPos &amp;lt; 170) {     \/\/ second segment 85..169\n        wheelPos -= 85;             \/\/ make position relative to segment start\n        c&#x5B;0]= 0;                    \/\/ no        RED\n        c&#x5B;1]= 255 - wheelPos * 3;   \/\/ declining GREEN\n        c&#x5B;2]= wheelPos * 3;         \/\/ growing   BLUE\n          \n    } else {                        \/\/ third segment  170..255\n        wheelPos -= 170;            \/\/ make position relative to segment start\n        c&#x5B;0]= wheelPos * 3;         \/\/ growing   RED\n        c&#x5B;1]= 0;                    \/\/ no        GREEN \n        c&#x5B;2]= 255 - wheelPos * 3;   \/\/ declining BLUE\n    }\n  \n    return c;                       \/\/ return the RGB triple\n}\n \n\/\/ ===================== TOUCH DETECTION ================\n \nboolean touched(int arm) {\n    \/\/ return true if the user touches the arm\n    \/\/ if a touch is detected the function will delay the return for 100 msecs\n    \/\/ this allows finer control for the user\n     \n    int t= touchRead(touchPins&#x5B;arm]);   \/\/ high values:untouched, lower values: maybe touched\n    if (t==0) return false;             \/\/ ignore a value of zero\n    if (t&amp;lt; 30) {                     \/\/ a reasonable to detect a touch is a value of 30..60\n        delay(100);                     \/\/ wait a moment so that the user can release the touch\n        return true;\n    }\n    return false;                       \/\/ retun immediately if no touch was detected\n}\n \n\/\/ ===================== DISPLAY ================\n \nString tftLines&#x5B;4] = {&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;};     \/\/ the current four lines shown on the display\n \nvoid tftPrint(int nr, String text) {\n    \/\/ print text into the specified line (0..3)\n \n    \/\/ we must fill the text to be shown with spaces; \n    \/\/ otherwise portions of previous contents would still be visible \n    \/\/ if the new text was shorter than the previous text\n    String line = (text+&quot;                    &quot;).substring(0,20);\n     \n    \/\/ In case the text has not changed: do nothing (avoiding flickering of the display)\n    if (tftLines&#x5B;nr]==line) return;\n \n    \/\/ store line\n    tftLines&#x5B;nr]=line;\n     \n    \/\/ print the line, calculating the vertical position from the line number\n    tft.drawString(line,0,nr*33,1); \n}\n \n\/\/ ===================== END ================\n<\/pre><\/div>\n\n\n<h2>Version 5<\/h2>\n\n\n\n<p>Wir f\u00fcgen ein kleines Spiel hinzu, zu dem man gelangt, wenn man den Arm #0 ber\u00fchrt. Der Stern gibt eine Farbe vor und zeigt sie auf drei Armen. Wir k\u00f6nnen durch das Ber\u00fchren der Arme #1 &#8230; #6 eine zweite Farbe einstellen, die auf den restlichen vier Armen gezeigt wird. Dabei sind #6\/#1 f\u00fcr den ROT-Anteil zust\u00e4ndig, #5\/#2 f\u00fcr GR\u00dcN und #4\/#3 f\u00fcr BLAU. Das Ziel ist, unsere Farbe der vorgegebenen Farbe so \u00e4hnlich wie m\u00f6glich zu machen. <br>Um zu gewinnen, muss der Spieler den Farbton nicht perfekt treffen, ihm aber doch ziemlich nahe kommen.<\/p>\n\n\n\n<p>Gelangt der Spieler in die N\u00e4he der richtigen Farbe, so wird er durch Bildschirmmeldungen und\/oder akustische Signale unterst\u00fctzt &#8211; f\u00fcr die akustische Ausgabe haben wir dazu einen kleinen Buzzer an Pin #25 angeschlossen). Wenn das Spiel beginnt, wird am Bildschirm gezeigt, welche Art der Unterst\u00fctzung gerade (zuf\u00e4llig) aktiviert wurde. Ist keinerlei Unterst\u00fctzung aktiv, so ist es nicht einfach, den Farbton genau genug zu treffen.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n    This program shows rotation rainbow colors and offers a game\n    where you try to match a given random color\n \n    The program is made of the following components:\n        ------------------------------------------------------------\n        * Touch pin recognition\n        * TFT display control\n        * LED strip control and color wheel\n        ------------------------------------------------------------\n        * Rainbow patterns: arms #1..6 control the pattern, #0=EXIT  \n        * ColorMatcher:     arms #1..6 change colors, #0=EXIT\n        ------------------------------------------------------------\n        * SETUP and LOOP\n         ------------------------------------------------------------\n \n    VERSION: 5\n*\/\n \n\/\/ ===================== TOUCH DETECTION ================\n \nint touchPins&#x5B;]={32,27,12,13,15,2,33};  \/\/ pins (#0..#6) connected to touch contacts\n \n#define TOUCH_THRESHOLD 20              \/\/ values below mean &quot;touched&quot; \n \nboolean touched(int arm, int wait=0) {\n    \/\/ return true if the user touches the given arm\n    \/\/ if a touch is detected the function will delay the return for 100 msecs\n    \/\/ this allows finer control for the user\n       \n    int t= touchRead(touchPins&#x5B;arm]);   \/\/ high values:untouched, lower values: maybe touched\n    if (t==0) return false;             \/\/ ignore a value of zero\n    if (t&amp;lt;= TOUCH_THRESHOLD) {          \/\/ a reasonable to detect a touch is a value of 30..60\n        delay(5);                       \/\/ try a second time after a short pause\n        t =touchRead(touchPins&#x5B;arm]);\n        if (t==0 || t &gt; TOUCH_THRESHOLD) return false;\n        delay(wait);                    \/\/ wait a moment so that the user can release the touch\n        return true;\n    }\n    return false;                       \/\/ return immediately if no touch was detected\n}\n \n \n\/\/ ===================== DISPLAY ================\n    \n#include &amp;lt;SPI.h&gt;                            \/\/ SPI interface for TFT display\n#include &amp;lt;TFT_eSPI.h&gt;                       \/\/ Hardware-specific TFT library                                \nTFT_eSPI tft = TFT_eSPI();                  \/\/ define a variable for the TFT display\n \nString tftLines&#x5B;4] = {&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;};         \/\/ the current four lines shown on the display\n \nvoid tftClear() {\n    tft.fillScreen(TFT_BLACK);     \n}\nvoid tftPrint(int nr, String text) {\n    \/\/ print text into the specified line (0..3)\n   \n    \/\/ we must fill the text to be shown with spaces; \n    \/\/ otherwise portions of previous content might still be visible \n    \/\/ if the new text was shorter than the previous text\n    String line = (text+&quot;                    &quot;).substring(0,20);\n       \n    \/\/ In case the text has not changed: do nothing (avoiding flickering of the display)\n    if (tftLines&#x5B;nr]==line) return;\n   \n    \/\/ store line\n    tftLines&#x5B;nr]=line;\n       \n    \/\/ print the line, calculating the vertical position from the line number\n    tft.drawString(line,0,nr*33,1); \n}\n \n \n\/\/ ===================== SOUND BUZZER ================\n \n#define BUZZER_PIN      25\n#define BUZZER_CHANNEL  0\n \nvoid buzzerSetup() {\n    int vol = 64; \/\/ 127 = 50% duty cycle = max volume\n    int freq = 443;\n    int resolution = 8;\n    ledcSetup(BUZZER_CHANNEL, freq, resolution);\n    ledcAttachPin(BUZZER_PIN, BUZZER_CHANNEL);\n    ledcWrite(BUZZER_CHANNEL,vol);              \/\/ set duty cycle (aka volume)\n    ledcWriteTone(BUZZER_CHANNEL,0);            \/\/ mute\n}\n \nvoid buzzerPlay(int freq, int duration, int vol) {\n    Serial.println(&quot;buzzer &quot;+String(freq)+&quot; &quot;+String(duration)+&quot; &quot;+String(vol));\n    ledcWrite(BUZZER_CHANNEL,vol); \/\/ set duty cycle 0..127 (=50%)\n    ledcWriteTone(BUZZER_CHANNEL, freq);\n    delay(duration);\n    ledcWriteTone(BUZZER_CHANNEL,0);   \/\/ mute\n}\n \nvoid buzzerPlay(int freq, int duration) {\n    buzzerPlay(freq,duration,127);              \/\/ use max. volume\n}\n \nvoid buzzerBeep() {\n    buzzerPlay(443,100,127);    \/\/ short note &quot;a&quot;\n}\n \n \n\/\/ ===================== LED STRIP and COLOR WHEEL ============\n \n#define NUM_ARMS  7                                 \/\/ the star has 7 arms (&quot;legs&quot;)\n#define NUM_LEDS (2*NUM_ARMS)                       \/\/ we have two LEDs per arm\n \n#include &amp;lt;Adafruit_NeoPixel.h&gt;\nAdafruit_NeoPixel strip = Adafruit_NeoPixel(        \/\/ define the LED strip (type WS2812)\n    NUM_LEDS,                                       \/\/ number of color triples\n    26,                                             \/\/ the pin# connected to the strip\n    NEO_GRB + NEO_KHZ800                            \/\/ 800 kHz bit stream in GRB sequence\n);\nbyte colorPosition  = 0;                            \/\/ initial position of color wheel (0 = red)\n    \nbyte *wheel(byte wheelPos) {\n    \/\/ implements a color circle (&quot;wheel&quot;) beginning with (1) red, changing to (2) green and (3) to blue\n    \/\/ the wheel if divided into 256 steps, so 0=red, 256\/3=green, 256*2\/3=blue, etc.\n    \/\/ the &amp;lt;wheelPos&gt; parameter is a number between 0..255\n    \/\/ the function returns an RGB array of three bytes\n        \n    static byte c&#x5B;3];   \/\/ the resulting RGB triple\n    \n    \/\/ we have three segments (0..84, 85..169, 170..255)\n    \/\/ in each segment one RGB color is completely missing (i.e. it has a value of 0)\n    \/\/ another one is growing from 0..255 and the third color goes down from 255 to 0\n    \/\/ this means that we have equal brightness over the whole spectrum\n    \n    if(wheelPos &amp;lt; 85) {             \/\/ first segment 0..84\n        c&#x5B;0]= 255 - wheelPos * 3;   \/\/ declining RED\n        c&#x5B;1]= wheelPos * 3;         \/\/ growing   GREEN\n        c&#x5B;2]= 0;                    \/\/ no        BLUE\n        \n    } else if(wheelPos &amp;lt; 170) {     \/\/ second segment 85..169\n        wheelPos -= 85;             \/\/ make position relative to segment start\n        c&#x5B;0]= 0;                    \/\/ no        RED\n        c&#x5B;1]= 255 - wheelPos * 3;   \/\/ declining GREEN\n        c&#x5B;2]= wheelPos * 3;         \/\/ growing   BLUE\n            \n    } else {                        \/\/ third segment  170..255\n        wheelPos -= 170;            \/\/ make position relative to segment start\n        c&#x5B;0]= wheelPos * 3;         \/\/ growing   RED\n        c&#x5B;1]= 0;                    \/\/ no        GREEN \n        c&#x5B;2]= 255 - wheelPos * 3;   \/\/ declining BLUE\n    }\n    \n    return c;                       \/\/ return the RGB triple\n}\n \n   \n   \n\/\/ ===================== RAINBOW ================\n    \nvoid rainbowCycle() {\n \n    tftClear();\n    tftPrint(0,&quot;Rotating Rainbow&quot;);\n \n    unsigned long   speedDelay; \/\/ delay between iterations in msecs\n    int             gap;        \/\/ gap between color increments (wheel steps)\n    int             segment;    \/\/ segment size of color circle (10=full, 20=half, ..)\n \n    \/\/ start with random settings:\n    speedDelay  = random(20); \n    gap         = random(10); \n    segment     = random(10); \n \n    byte *c;                            \/\/ a triple of color values obtained from the wheel\n    boolean changed=true;\n    for(;;) {   \/\/ forever\n           \n        colorPosition = (colorPosition+gap) % 256;      \/\/ increment color position\n   \n        \/\/ divide the circle into equi-distant colors for the LEDs\n        \/\/ if segments==10 use full spectrum, else use less (e.g. 10%) or more (eg 200%)\n        \/\/ assign a color to each LED starting from the current color position\n            \n        for(int l=0; l&amp;lt; NUM_LEDS; l++) {\n            c= wheel(((l * 256 \/ NUM_LEDS * 10 \/ segment) + colorPosition) % 256);\n            strip.setPixelColor(l, *c, *(c+1), *(c+2));\n        }\n    \n        strip.show();               \/\/ now transfer the LED memory to the LED strip\n    \n        \/\/ check touch sensors and modify settings if desired\n        if (touched(1,100) &amp;amp;&amp;amp; speedDelay &amp;lt; 1000 ) { changed=true; speedDelay++; } \/\/ slower\n        if (touched(2,100) &amp;amp;&amp;amp; speedDelay &gt;    1 ) { changed=true; speedDelay--; }\n        if (touched(3,100) &amp;amp;&amp;amp; gap&gt;1             ) { changed=true; gap--;        } \/\/ closer\n        if (touched(4,100) &amp;amp;&amp;amp; gap&amp;lt;100           ) { changed=true; gap++;        }\n        if (touched(5,100) &amp;amp;&amp;amp; segment&gt;1         ) { changed=true; segment--;    } \/\/ smaller\n        if (touched(6,100) &amp;amp;&amp;amp; segment&amp;lt;50        ) { changed=true; segment++;    }\n          \n        \/\/ show current settings for debugging on serial line\n        if (changed) {\n            Serial.println(&quot;delay=&quot;+String(speedDelay)+&quot;  gap=&quot;+String(gap)+&quot;  segment=&quot;+String(segment));\n            changed=false;\n        }\n   \n        \/\/ show current settings for the user on the TFT display\n        tftPrint(1,&quot;delay   =&quot;+String(speedDelay));\n        tftPrint(2,&quot;gap     =&quot;+String(gap));\n        tftPrint(3,&quot;segment =&quot;+String(segment));\n           \n        \/\/ wait for the configured time (msecs)        \n        delay(speedDelay);\n \n        if (touched(0,400)) break;     \/\/ EXIT rainbow if user touches arm #0\n    }\n}\n \n \n\/\/ ===================== COLOR MATCH GAME ================\n    \nvoid colorMatch(boolean withSound, boolean withHints) {\n \n    tftClear();\n    tftPrint(0,&quot;Color Matcher&quot;);\n    tftPrint(1,withSound? &quot;SOUND&quot; : &quot;SILENT&quot;);\n    tftPrint(2,withHints? &quot;HINTS&quot; : &quot;NO HINTS&quot;);\n \n    uint8_t r,rr,g,gg,b,bb;\n \n    boolean success=true;   \/\/ triggers a new color to be chosen\n     \n    for(;;) {   \/\/ forever\n \n        if (success) {\n\n            \/\/ choose a new color\n            rr=random(256), gg=random(256), bb=random(256);    \/\/ the color to be matched\n            r=10, g=10, b=10;                                  \/\/ the current color\n            for(int l=0; l&amp;lt; NUM_LEDS; l++) {\n                if(l&gt;=3 &amp;amp;&amp;amp; l&amp;lt;=10)   strip.setPixelColor(l, r, g, b );\n                else                strip.setPixelColor(l, rr,gg,bb);\n            }\n            strip.show();               \/\/ now transfer the LED memory to the LED strip\n            success=false;\n            tftPrint(3,&quot;&quot;);                \n        }\n \n        \/\/ check touch sensors and modify settings if desired\n        if (touched(1,5)) if (r&amp;lt;255) r++;\n        if (touched(2,5)) if (g&amp;lt;255) g++;\n        if (touched(3,5)) if (b&amp;lt;255) b++;\n        if (touched(4,5)) if (b&gt;0) b--;\n        if (touched(5,5)) if (g&gt;0) g--;\n        if (touched(6,5)) if (r&gt;0) r--;\n \n        if (touched(1) || touched(2) || touched(3) || touched(4) || touched(5) || touched(6)) {\n             \n            for(int l=3; l&amp;lt;=10; l++) strip.setPixelColor(l, r ,g ,b );\n            strip.show();\n             \n            int distance = (r-rr)*(r-rr)+(g-gg)*(g-gg)+(b-bb)*(b-bb);   \/\/ sum of squares\n             \n            if (abs(r-rr)&amp;lt;=5 &amp;amp;&amp;amp; abs(g-gg)&amp;lt;=5 &amp;amp;&amp;amp; abs(b-bb) &amp;lt;=5) {   \/\/ success\n                tftPrint(3,&quot;well done!&quot;);\n\t\t\t\t\/\/ play tone scale\n\t\t\t\tfor (int f=264;f&amp;lt;=264;f++) {\n\t\t\t\t\tfloat freq=f;\n\t\t\t\t\tfor(int n=0;n&amp;lt;=12;n++) {\n\t\t\t\t\t\tif (n==0||n==2||n==4||n==5||n==7||n==9||n==11|| n==12) buzzerPlay(round(freq),200);\n\t\t\t\t\t\tfreq=freq*1.059463;\n\t\t\t\t\t\tdelay(100);     \n\t\t\t\t\t}\n\t\t\t\t\tdelay(500);\n\t\t\t\t}\n                success=true;\n                for(int n=0;n&amp;lt;5;n++) {\n                    delay(200);\n                    for(int l=3; l&amp;lt;=10; l++) strip.setPixelColor(l,0,0,0);\n                    strip.show();\n                    delay(200);\n                    for(int l=3; l&amp;lt;=10; l++) strip.setPixelColor(l, r ,g ,b );\n                    strip.show();\n                }\n            }\n            else if (abs(r-rr)&amp;lt;=10 &amp;amp;&amp;amp; abs(g-gg)&amp;lt;=10 &amp;amp;&amp;amp; abs(b-bb) &amp;lt;=10) {   \/\/ close\n                if (withHints) tftPrint(3,&quot;looks good&quot;);\n            }\n            else if (abs(r-rr)&amp;lt;=20 &amp;amp;&amp;amp; abs(g-gg)&amp;lt;=20 &amp;amp;&amp;amp; abs(b-bb) &amp;lt;=20) {   \/\/ closer\n                if (withHints) tftPrint(3,&quot;not bad&quot;);\n            }\n            else {\n                tftPrint(3,&quot;&quot;);                \n            }\n            if (withSound &amp;amp;&amp;amp; distance&amp;lt;3000) buzzerPlay(800-distance\/6,100);   \/\/ buzzer feed back\n             \n            Serial.printf(&quot;red %d %d    green %d %d      blue %d %d \\n&quot;,\n                rr,r-rr,gg,g-gg,bb,b-bb);\n        }\n        if (touched(0,400)) break;     \/\/ EXIT rainbow if user touches arm #0\n    }\n}\n \n   \n\/\/ ===================== SETUP ================\n    \nvoid setup() {\n    Serial.begin(115200);                           \/\/ for monitoring\n    delay(100);\n   \n    tft.begin();                                    \/\/ initialize, 240 x 135 pixels (~ 20x4 chars)\n    tft.setRotation(1);                             \/\/ 1=landscape orientation\n    tft.setTextDatum(TL_DATUM);                     \/\/ top left reference point for texts\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);         \/\/ white on black\n    tft.fillScreen(TFT_BLACK);                      \/\/ clear screen, all black\n    tft.setFreeFont(&amp;amp;FreeSans12pt7b);               \/\/ fairly large font (allows for 4 lines)\n       \n    strip.begin();                                  \/\/ initialize LED strip\n     \n    buzzerSetup();                                  \/\/ a piezo electric buzzer\n    buzzerBeep();\n}\n    \nvoid loop() {\n    \/\/ toggle between rainbow and color matching game\n    rainbowCycle();\n    colorMatch(random(2) ? true:false,random(2) ? true:false);               \n}\n \n\/\/ ===================== END ================\n<\/pre><\/div>\n\n\n<h2>Mathe-Stern<\/h2>\n\n\n\n<p>Wenn man einen Stern mit 7 Zacken und 7 Sensoren gebaut hat, kann man viele weitere Ideen mit Software umsetzen.<br>Wir haben dazu eine <a href=\"https:\/\/followthescore.org\/schueler-labor\/2020\/12\/21\/mathe-stern\/\" data-type=\"post\" data-id=\"344\">eigene Seite \u00fcber den Mathe-Stern<\/a> verfasst.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wir bauen einen modularen Weihnachtsstern. Er soll von einem kleinen Rechner gesteuert werden und mehrfarbig leuchten, alleine oder im Verbund mit anderen Sternen. Was ist mit modular gemeint? Liste der Anforderungen (A) Die Teile des Sterns sollen gut gegeneinander abgegrenzt sein, mit einfachen mechanischen Verbindungen und leicht l\u00f6sbaren elektrischen Schnittstellen. Die Farben sollen den einzelnen&hellip; <a class=\"more-link\" href=\"https:\/\/followthescore.org\/schueler-labor\/weihnachtsstern\/\"><span class=\"screen-reader-text\">Weihnachtsstern<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/posts\/263"}],"collection":[{"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/comments?post=263"}],"version-history":[{"count":61,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/posts\/263\/revisions"}],"predecessor-version":[{"id":405,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/posts\/263\/revisions\/405"}],"wp:attachment":[{"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/media?parent=263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/categories?post=263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/tags?post=263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}