Teeodohr: Change Request

In meiner Beitragsreihe zu Teeodohr, dem kleinen Roboter mit der Fähigkeit zur Teezubereitung, geht es diesmal darum, wie unser Freund noch alltagstauglicher gemacht wird. Ich zeige dir, welche weiteren Skills ich ihm beigebracht habe. Dazu sind keine Veränderungen an der Hardware notwendig.

Bevor wir uns ins in die Details stürzen, lass mich kurz rekapitulieren, was wir im letzten Beitrag über die professionelle Softwareentwicklung am Beispiel von Teeodohr gelernt haben: Bevor wir die erste Zeile Code niederschreiben, sollten wir so viel wie möglich darüber wissen, welche Aufgaben Teeodohr erfüllen soll. Das Ergebnis dieser Überlegungen war eine lange Liste mit funktionalen Anforderungen. Neben den funktionalen gibt es noch die nicht-funktionalen Anforderungen, welche z. B. das Zeitverhalten, die Zuverlässigkeit und den Ressourcenverbrauch spezifizieren. Diese sind und werden zur Vereinfachung erst einmal ausgeklammert.

Teeodohrs neue Zusatzfähigkeiten widersprechen den bestehenden Anforderungen. Wir müssen diese daher ändern bzw. erweitern, um weiterhin eine vollständige Spezifikation des Teehasen zu haben. Im professionellen Umfeld spricht man hier von einem Change Request:

Eine Änderungsanforderung (auch Change Request abgekürzt CR) bezeichnet im Änderungswesen von Projekten einen formalisierten Wunsch nach Veränderung der Eigenschaften eines bestimmten Produktmerkmals. Jede Änderungsanforderung sollte in einem kontrollierten Prozess bewertet, entschieden und kommuniziert werden.

Wikipedia

Mein kontrollierter Prozess besteht hier nur aus intensivem Nachdenken über die generelle Machbarkeit und den entstehenden Implementierungsaufwand. Im Profi-Bereich wären hier aufwendigere Überlegungen und weitergehende Bewertungen, wie z. B. über Kosten und Risiko, notwendig. Als Ergebnis entstehen auf beiden Wegen Teeodohrs neue Anforderungen, die es umzusetzen gilt. In den folgenden Abschnitten erläutere ich diese näher. Den vollständigen Code findest du am Ende dieses Beitrags.

Beim Einschalten von Teeodohr, beim Starten der Zubereitung und am Ende der Zubereitung sollen jeweils verschiedene Melodien gespielt werden.

Original-Teeodohr kennt genau eine Melodie, welche er beim Einschalten und am Ende der Teezubereitung abspielt. Etwas eintönig, oder? Ich wünsche mir hier etwas mehr Abwechslung und eine zusätzliche akustische Rückmeldung, wenn Teeodohr mit der Zubereitung beginnt.

Meine Wahl fiel auf die Melodien und Sounds aus Nintendos „Super Mario“ Universum. Diese gibt es kostenlos in Form von Notenblättern und MIDI-Files auf der Seite mariopiano.com. Von dort übernehme ich die ersten Takte des „Main Themes“, den „Coin“- sowie den „1-Up Mushroom“-Sound. Als Notation wähle ich eine gut lesbare Kombination aus Tonhöhe und Dauer, sodass sich das Main Theme beispielsweise so im Code wiederfindet:

Tone bootMelody[] = { { NOTE_E7, 12 }, { NOTE_E7, 12 }, { PAUSE, 12 }, { NOTE_E7, 12 }, { PAUSE, 12 }, { NOTE_C7, 12 }, { NOTE_E7, 12 }, { PAUSE, 12 }, {NOTE_G7, 12}, {PAUSE,  12}, {PAUSE, 6} };

Das Abspielen der Melodie erfolgt über einen MelodyPlayer. Diese von mir eingeführte generische Klasse übernimmt die Ansteuerung des Piezo-Schallwandlers. Die Verwendung sollte aus dem folgenden Beispielcode hervorgehen:

static const uint8_t PIEZO = 10;
MelodyPlayer melodyPlayer(PIEZO);
melodyPlayer.play(bootMelody);

Während der Zubereitung sollen die LEDs den aktuellen Fortschritt anzeigen.

Wäre es nicht schön von Teeodohr zu erfahren, wie lange man noch auf das Heißgetränk warten muss? Da unser guter Freund mittels drei LEDs kommunizieren kann, nutze ich diese als rudimentäre Fortschrittsanzeige. Da die LEDs mit PWM-fähigen Ausgängen des Arduinos verbunden sind, können diese in der Helligkeit gedimmt werden. Original-Teeodohr nutzt dieses Feature, um während der Zubereitung eine Animation mit den LEDs auszuführen. Ich beschränke mich auf drei Helligkeiten (100 %, 50 % und 0 %) pro LED, um insgesamt 6 Fortschritts-Stufen à 16,5 % abzubilden. Damit lässt sich klar erkennen, wie weit die Ziehzeit bereits vorangeschritten ist.

Als zusätzliche Ziehzeiten sollen 8 und 15 Minuten auswählbar sein.

Zu Teeodohrs Füßen befindet sich der „3-5-7“-Taster, mit denen neben 3, 5, und 7 Minuten auch 10 und 12 Minuten ausgewählt werden können. Diese Zeiten werden durch das gleichzeitige Leuchten von jeweils zwei LEDs signalisiert. Eigenartigerweise ist die Auswahl von 8 und 15 Minuten nicht implementiert, obwohl dies Soft- und Hardware-technisch kein Problem darstellt. Tragisch ist dieser Funktionsmangel auch gerade aus folgendem Grund:

Die Nachrüstung der zusätzlichen Zeiten stellt kein großes Problem dar und vervollständigt Teeodohrs Repertoire. Zugegeben: Bis jetzt habe ich noch keinen Tee mit einer Ziehzeit von 15 Minuten gefunden…

Die zuletzt vom Nutzer ausgewählte Ziehzeit soll beim Wechsel in den betriebsbereiten Zustand ausgewählt sein. Dies gilt auch, wenn Teeodohr aus- und wiedereingeschaltet wird.

Ärgerlich ist Original-Teeodohrs Vergesslichkeit. Direkt nach jeder Teezubereitung setzt er die Ziehzeit auf 3 Minuten zurück. Gerade dann, wenn man hauptsächlich genau eine Teesorte zubereiten möchte, ist das immer wiederkehrende Einstellen derselben Ziehzeit recht unpraktisch und auch unnötig. Teeodohr soll einfach die zuletzt ausgewählte Zeit einstellen. Und das auch dann, wenn man ihn aus- und wieder einschaltet.

Den ersten Teil der Anforderung zu implementieren ist recht einfach. In der Original-Software wird die Ziehzeit explizit auf 3 Minuten zurückgesetzt. Diese Anweisung kann im Quelltext einfach entfernt werden. Dies hilft allerdings nicht dagegen, dass Teeodohr zu spontaner Amnesie neigt, wenn man ihm die Möhre aus der Pfote nimmt. Die damit verbundene Unterbrechung der Stromversorgung führt zur Löschung des flüchtigen Arbeitsspeichers des Arduinos, in dem die Zeitauswahl bisher gespeichert ist.

Das Zauberwort für die Lösung dieses Problems heißt „Persistenz“. Die Ziehzeit muss in einem Speicher hinterlegt werden, der seine Daten unabhängig von der Stromversorgung behält. Praktischerweise verfügt der Arduino über ein paar Kilobyte EEPROM, der mehr als ausreichend für diese Aufgabe ist. Ich implementiere daher das Schreiben der Ziehzeit in diesen nichtflüchtigen Speicher, wenn die Zubereitung gestartet wird. Das Lesen und Einstellen der letzten Ziehzeit geschieht immer beim Einschalten.

Während des Zustands „Zubereitung“ soll Teeodohrs Ohr nach jeder vollen Minute kurzzeitig in eine halb-aufgestellte Position bewegt werden.

Insbesondere bei heißen Früchte-„Tees“ passiert es manchmal, dass sich während der Zubereitung eine hochkonzentrierte Schicht am Tassenboden absetzt. Das Wasser darüber hingegen bleibt klar. Um diese und anderweitig entstandene inhomogene Durchmischungen zu verhindern, bewegt Original-Teeodohr sein Öhrchen brav jede Minute einmal ganz nach oben und wieder zurück, was zu Verwirbelungen im Wasser sorgt. Das erzielt zwar den erwünschten Effekt, jedoch finde ich das komplette Herausziehen des Teebeutels aus der Tasse etwas übertrieben und wünsche mir daher eine weniger dramatische Bewegung.

Aus diesem Grund führe ich eine dritte Position zwischen vollständig aufgestellter und abgesenkter Position ein. Diese nimmt Teeodohr auch nach Ablauf jeder Minute der Ziehzeit kurz ein.

Zeig mir den Code

Das komplette Arduino-Programm findest du auf GitHub. Findest du es verständlich, nachvollziehbar und gut zu erweitern? Schreib deine Meinung dazu gern in die Kommentare!

Vom Change Request zu Teeodohr 2.0
Die beschriebenen Erweiterungen jetzt auch für die Original-Hardware aus dem Make Magazin! Mehr dazu in diesem Beitrag:

Teeodohr 2.0 – Softwareupdate fügt lang ersehnte Funktionen hinzu

4 Kommentare

  1. Hallo Christian,

    ich habe mich gefreut den Sketch von Dir für den Teeodohr zu finden, der das mitbringt was mir beim Originalen fehlt.
    Ich habe bei Github auch gelesen, dass die Pinzuordnung angepasst werden muss, damit er mit der Originalplatine von Andreas Engel (heise) läuft. M.E. betrifft das die Pins A1 und A2 für die beiden Button. Der Rest für die Leds, Piezo und Servo ist identisch. Nun habe ich dazu folgendes geändert:
    // Used Pins
    static const uint8_t BUTTON_TIME = A1;
    static const uint8_t BUTTON_START_STOP = A2;

    Das scheint aber leider nicht zu reichen. Die Zeit kann ich ändern indem ich den Start/Stop- Button gedrückt halten und dann über den Zeit- Button durch mehrfaches Tasten entsprechend auswähle. Danach lässt sich aber über Start/Stop nichts mehr machen. Beim Druck auf den Zeit- Button senkt sich der Arm aber es passiert nichts mehr.
    Da ich nicht viel vom Programmieren verstehe und Deinen Code nur in Bruchteilen nachvollziehen kann, wäre ich für einen Hinweis wirklich dankbar. Vielen Dank schonmal…

    Grüße Dirk

    1. Hallo Dirk,

      freut mich sehr, dass du den Weg zu meinem Blog gefunden hast und deinen Teeodohr verbessern möchtest.

      Mit der Pin-Zuordnung hast du schon mal den ersten wichtigen Knackpunkt gefunden. Dabei fehlt noch ein kleines, aber wichtiges Detail. Dieses habe ich im Beitrag Teeodohr: Besserer Tee dank eines Hasen wie folgt beschrieben:

      Die Start/Stop- und Zeitauswahl-Taster sind im Original-Schaltplan über externe Pulldown-Widerstände angeschlossen und ziehen den Arduino-Pin beim Drücken auf 5V-Pegel. Ich invertiere diese Logik und schließe die Taster so an, dass sie gegen GND schalten. Softwareseitig aktiviere ich die internen Pullup-Widerstände des Mikrocontrollers. Damit spare ich die externen Widerstände ein.

      Es fehlt also noch die Invertierung der Logik bei der Button-Abfrage. Ich habe das auf einem Branch bei GitHub gerade umgesetzt. Du kannst es gern ausprobieren, indem du die Teeodohr.ino mit dieser hier ersetzt:
      https://github.com/mopongo/teeodohr/blob/original-hardware/Teeodohr.ino

      Da ich nur meine angepasste Teeodohr-Schaltung und nicht die originale habe, kann ich diese Änderung leider nicht praktisch ausprobieren. Wenn bei deinem Teeodohr alles funktionieren sollte, würde ich mich über eine kurze Rückmeldung sehr freuen! Dann kann ich die Änderung auch offiziell hier vorstellen und anderen Teefreunden zu den neuen Features verhelfen 🙂

      Viele Grüße
      Christian

  2. Hallo Christian,
    es läuft wie es soll. Perfekt. Danke für die prompte Hilfe.

    Über pinMode(BUTTON_TIME, INPUT_PULLUP); bin ich gestern auch schon gestolpert und hatte „INPUT“ ausbrobiert. Aber da hat ja trotzdem noch was gefehlt. 😉

    Also, danke nochmal und viele Grüße

    Dirk

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert