{"id":425,"date":"2021-01-27T17:11:08","date_gmt":"2021-01-27T16:11:08","guid":{"rendered":"https:\/\/followthescore.org\/schueler-labor\/?p=425"},"modified":"2021-02-02T14:21:10","modified_gmt":"2021-02-02T13:21:10","slug":"verkehrsampel-v1","status":"publish","type":"post","link":"https:\/\/followthescore.org\/schueler-labor\/verkehrsampel-v1\/","title":{"rendered":"Verkehrsampel V1"},"content":{"rendered":"\n<p>Der erste Entwurf unseres Programms ist fertig. Wir sind ein wenig stolz, weil der Code so sch\u00f6n lesbar und so gut kommentiert ist. Das Ein- und Ausschalten der Anlage fehlt noch, aber es funktioniert schon prima! Und in Englisch ist es auch noch!<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n\/\/ Two traffic lights, using the standard pattern (R,R+Y,G,Y).\n\/\/ GREEN time is shared 50:50 between the two lights\n\n\/\/ version 1\n\n#include &lt;Adafruit_NeoPixel.h&gt;\n\n\/\/ we use a single strip of 14 LEDs\n\/\/ traffic light A =  RED( 1, 2), YELLOW( 3, 4), GREEN( 5, 6)\n\/\/ traffic light B =  RED(11,12), YELLOW( 9,10), GREEN( 7, 8)\nAdafruit_NeoPixel strip = Adafruit_NeoPixel(14,26);\n \nvoid setup() {\n    Serial.begin(115200);\n    delay(100);\n\n    Serial.println(&quot;all dark&quot;);\n    strip.fill(0);\n}\n \nvoid loop() {\n\n    \/\/ all red\n    Serial.println(&quot;* = R&quot;);\n    strip.setPixelColor( 1, 20, 0, 0);  \/\/ tlA = RED\n    strip.setPixelColor( 2, 20, 0, 0);\n    strip.setPixelColor(11, 20, 0, 0);  \/\/ tlB = RED\n    strip.setPixelColor(12, 20, 0, 0);\n    strip.show();\n    delay(500);\n\n    Serial.println(&quot;A = R+Y&quot;);\n    strip.setPixelColor( 3, 20,20, 0);  \/\/ tlA = RED + YELLOW\n    strip.setPixelColor( 4, 20,20, 0);\n    strip.show();\n    delay(1000);\n\n    Serial.println(&quot;A = G&quot;);\n    strip.setPixelColor( 1,  0, 0, 0);  \/\/ tlA = no red\n    strip.setPixelColor( 2,  0, 0, 0);\n    strip.setPixelColor( 3,  0, 0, 0);  \/\/ tlA = no yellow\n    strip.setPixelColor( 4,  0, 0, 0);\n    strip.setPixelColor( 5,  0,20, 0);  \/\/ tlA = GREEN\n    strip.setPixelColor( 6,  0,20, 0);\n    strip.show();\n    delay(10000);\n\n    Serial.println(&quot;A = Y&quot;);\n    strip.setPixelColor( 5,  0, 0, 0);  \/\/ tlA = no green\n    strip.setPixelColor( 6,  0, 0, 0);\n    strip.setPixelColor( 3, 20,20, 0);  \/\/ tlA = YELLOW\n    strip.setPixelColor( 4, 20,20, 0);\n    strip.show();\n    delay(2000);\n\n    \/\/ all red\n    Serial.println(&quot;* = R&quot;);\n    strip.setPixelColor( 3,  0, 0, 0);  \/\/ tlA = no yellow\n    strip.setPixelColor( 4,  0, 0, 0);\n    strip.setPixelColor( 1, 20, 0, 0);  \/\/ tlA = RED\n    strip.setPixelColor( 2, 20, 0, 0);\n    strip.show();\n    delay(500);\n\n    Serial.println(&quot;B = R+Y&quot;);\n    strip.setPixelColor( 9, 20,20, 0);  \/\/ tlB = RED + YELLOW\n    strip.setPixelColor(10, 20,20, 0);\n    strip.show();\n    delay(1000);\n\n    Serial.println(&quot;B = G&quot;);\n    strip.setPixelColor(11,  0, 0, 0);  \/\/ tlB = no red\n    strip.setPixelColor(12,  0, 0, 0);\n    strip.setPixelColor( 9,  0, 0, 0);  \/\/ tlB = no yellow\n    strip.setPixelColor(10,  0, 0, 0);\n    strip.setPixelColor( 7,  0,20, 0);  \/\/ tlB = GREEN\n    strip.setPixelColor( 8,  0,20, 0);\n    strip.show();\n    delay(10000);\n\n    Serial.println(&quot;B = Y&quot;);\n    strip.setPixelColor( 7,  0, 0, 0);  \/\/ tlB = no green\n    strip.setPixelColor( 8,  0, 0, 0);\n    strip.setPixelColor( 9, 20,20, 0);  \/\/ tlB = YELLOW\n    strip.setPixelColor(10, 20,20, 0);\n    strip.show();\n    delay(2000);\n\n    strip.setPixelColor( 9,  0, 0, 0);  \/\/ tlB = no yellow\n    strip.setPixelColor(10,  0, 0, 0);\n    \n}\n<\/pre><\/div>\n\n\n<p>Als wir das Programm unserem Lehrer zeigen, lobt er uns, denn er hat gelernt, dass Lob die Motivation f\u00f6rdert. <\/p>\n\n\n\n<p>Innerlich denkt er sich allerdings: Wie kann ich euch jetzt schonend beibringen, dass dieses wundervolle Programm ein komplette Katastrophe ist?<\/p>\n\n\n\n<p>Er versucht es mit der Methode von Aristoteles: Er stellt ein paar unverf\u00e4ngliche Fragen und bringt uns ins Nachdenken:<\/p>\n\n\n\n<p><em><strong>Ich sehe, ihr habt die Helligkeit recht dunkel eingestellt. F\u00fcr den Test ist das prima. An wievielen Stellen m\u00fcsst ihr euer Programm eigentlich \u00e4ndern, wenn die Ampel sp\u00e4ter richtig sch\u00f6n hell leuchten soll?<\/strong><\/em><\/p>\n\n\n\n<p>Na ja, die Zahl 20 kommt ungef\u00e4hr 20 mal vor (Was f\u00fcr ein netter Zufall;-).<br>Aber jeder Editor beherrscht doch &#8222;Suchen&#8220; und &#8222;Ersetzen&#8220;. Das ist doch nur ein Handgriff! Ein bisschen dumm ist allerdings, dass die 20 auch den Anfang von 2000 bildet. Die Wartezeit der Gelbphase w\u00fcrde kaputt gehen, wenn wir nicht aufpassen&#8230;<\/p>\n\n\n\n<p><em><strong>Ist euch aufgefallen, dass ihr zum Umschalten einer einzelnen Lampe immer zwei Programmzeilen braucht?<\/strong><\/em><\/p>\n\n\n\n<p>Wir ahnen einen leisen Vorwurf hinter dieser Frage, aber wir antworten tapfer: <em>Ja schon, aber soo schlimm ist das doch wohl nicht. Das war doch von Anfang an die Idee, weil wir doch den Weihnachtsstern als Grundlage nehmen wollten. Und der hat eben zwei LEDs pro Arm.<\/em><\/p>\n\n\n\n<p><strong>Stellt euch mal vor, eine verbesserte Hardware bietet euch pl\u00f6tzlich viel mehr LEDs je Lampe an, vielleicht 20 anstatt nur 2. Wie viele Zeilen m\u00fc\u00dftet ihr denn da noch ins Programm einf\u00fcgen?<\/strong><\/p>\n\n\n\n<p>Also den Gefallen tun wir ihm nicht, das auszurechnen. Na gut, dann m\u00fcssen wir da wohl eine Schleife einbauen, obwohl es doch jetzt wirklich nur zwei LEDs sind. Wenn wir das ordentlich schreiben, dann brauchen wir aber zumindest 3 Zeilen daf\u00fcr, jedesmal. <em>Da wird das Programm aber auf jeden Fall jetzt erst mal l\u00e4nger!<\/em> Ein schwacher Versuch der Verteidigung, aber immerhin &#8230;<\/p>\n\n\n\n<p><strong>Nicht unbedingt. Wenn jemand eine Bibliothek entwirft, dann \u00fcberlegt er sich, was die aufrufenden Programme von ihm typischerweise wollen k\u00f6nnten.<\/strong> <strong>Kann es sein, dass die Bibliothek bereits eine Funktion bietet, um einen zusammenh\u00e4ngenden Bereich von LEDs mit einer einheitlichen Farbe auszustatten?<\/strong><\/p>\n\n\n\n<p>Also, wie soll diese komische Funktion denn hei\u00dfen? <\/p>\n\n\n\n<p><strong>Leute, es gibt nicht nur das Header-File. Seht euch halt auch mal die <a href=\"https:\/\/adafruit.github.io\/Adafruit_NeoPixel\/html\/class_adafruit___neo_pixel.html\">DOKU<\/a> an!<\/strong><\/p>\n\n\n\n<p>Dann legen wir mal los!<\/p>\n\n\n\n<p><strong>HAAALT !!!<\/strong><br><br><strong>Das Wichtigste beim Programmieren ist, ein Problem in unterschiedliche ABSTRAKTIONSEBENEN zu zerlegen. Daf\u00fcr muss man Begriffe definieren und sich das Zusammenspiel von FUNKTIONEN \u00fcberlegen. Von ganz weit oben betrachtet k\u00f6nnte man z.B. sagen:<\/strong><\/p>\n\n\n\n<p><br><em>(1) An Stra\u00dfenkreuzungen benutzt man Lichtsignalanlagen zur Regelung des Verkehrs. Ihre Lichtzeichen (manchmal auch unterst\u00fctzt durch akustische Signale f\u00fcr Sehbehinderte) repr\u00e4sentieren jeweils einen ZUSTAND, wie z.B. &#8222;Halt, Stehen bleiben&#8220; oder &#8222;Freie Fahrt&#8220; oder &#8222;Gerade aus fahren ist erlaubt, Linkssabbieger m\u00fcssen aber noch warten&#8220; oder &#8222;Radfahrer k\u00f6nnen losfahren&#8220;.<\/em><\/p>\n\n\n\n<p><em>(2) Man sieht, dass die Ampeln sich an unterschiedliche <strong>Adressaten<\/strong> (Autos, Radfahrer, Fu\u00dfg\u00e4nger) richten bzw. an Gruppen mit bestimmten <strong>Absichten<\/strong> (&#8222;Linksabbieger&#8220;).<\/em><br> <br><em>(3) Letztlich regeln Ampeln den Verkehr, indem sie eine streng definiert <strong>Folge von Zust\u00e4nden durchlaufen<\/strong> und den jeweiligen Zustand durch eine bestimmte Kombination von Lichtern anzeigen.<\/em><\/p>\n\n\n\n<p><em>(4) Die Zeitdauer der einzelnen Zust\u00e4nde kann fest eingestellt sein; sie kann sich auch abh\u00e4ngig von der Tageszeit \u00e4ndern oder sogar Sensordaten ber\u00fccksichtigen, \u00fcber die fahrende und\/oder stehende Fahrzeuge erfasst werden.<\/em><\/p>\n\n\n\n<p><strong>Auf den unteren Ebenen des Programms geht es dann darum, die richtigen LEDs mit der richtigen Farbe anzusteuern und das Zeitschema genau einzuhalten.<\/strong><\/p>\n\n\n\n<p><br><strong><em>Diese Ebene dominiert in eurem bisherigen Programm, Nun seht mal zu, dass auch die abstrakteren Ebenen einen Niederschlag in euerem Programmcode finden!<\/em><\/strong><\/p>\n\n\n\n<p><em>Schlechte Software zeichnet sich dadurch aus, dass man den Wald vor lauter B\u00e4umen nicht sieht, weil man st\u00e4ndig mit den unteren Ebenen konfrontiert wird beim Lesen des Programmcodes. Gute Software repr\u00e4sentiert die Wirklichkeit durch passende Konzepte, durch nat\u00fcrliche Namensgebung und durch das Aufeinander-Schichten von Funktionen unterschiedlicher Abstraktionsebenen.<\/em> &#8222;Zahlen&#8220; geh\u00f6ren beispielsweise zu den niedrigen Schichten, die oberen Ebeben arbeiten grunds\u00e4tzlich mit symbolischen Konstanten. Aber das hatten wir ja schon erw\u00e4hnt&#8230;<\/p>\n\n\n\n<p><strong><em>So, jetzt k\u00f6nnt ihr loslegen!<\/em><\/strong><\/p>\n\n\n\n<p>Herausgekommen ist <a href=\"https:\/\/followthescore.org\/schueler-labor\/2021\/01\/27\/verkehrsampel-v2\/\">Version 2 des Programms<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der erste Entwurf unseres Programms ist fertig. Wir sind ein wenig stolz, weil der Code so sch\u00f6n lesbar und so gut kommentiert ist. Das Ein- und Ausschalten der Anlage fehlt noch, aber es funktioniert schon prima! Und in Englisch ist es auch noch! Als wir das Programm unserem Lehrer zeigen, lobt er uns, denn er&hellip; <a class=\"more-link\" href=\"https:\/\/followthescore.org\/schueler-labor\/verkehrsampel-v1\/\"><span class=\"screen-reader-text\">Verkehrsampel V1<\/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\/425"}],"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=425"}],"version-history":[{"count":10,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/posts\/425\/revisions"}],"predecessor-version":[{"id":480,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/posts\/425\/revisions\/480"}],"wp:attachment":[{"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/media?parent=425"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/categories?post=425"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/followthescore.org\/schueler-labor\/wp-json\/wp\/v2\/tags?post=425"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}