Der Grundgedanke

Der promovierenden Person soll mit ihrem Doktorhut etwas mitgeben werden, das sie an ihre Aufgaben oder Interessen am Institut erinnert. Idealerweise wird das mit einem kleinen (Geschicklichkeits-) Spiel kombiniert, dass diejenige noch vor der Übergabe des Hutes lösen muss. Dieses Spiel oder Rätsel wird auf dem Hut montiert, sodass sich ein köstliches Bild ergibt, wenn die Person den Hut aufsetzt. Blinkereien und Bewegungen sollten für diesen Moment nicht ausgelassen werden.

Es ist jedoch auch zu bedenken, dass der oder die frisch gebackene DoktorIn im Moment der eigentlichen Verteidigung bereits einen einen anstrengenden Tag hinter sich hat. Man kann sich zwar trotzdem einen Spaß erlauben, sollte die Aufgabe des Hutes aber einfach und lösbar halten. Die Dauer zur Lösung der Aufgabe sollte nicht viel länger als 10 min. betragen. Der Hut muss auch immer noch aufsetzen können und auch (zumindest wenige Minuten lang) getragen werden können. Größe, Gewicht und Sitz sollten daher beim Bau beachtet werden

Materialien

Folgende Materialien sind eigentlich immer zu beschaffen:
  • Der Hut selbst kann bspw. auf der Seite Robe Academicus bestellt werden.
    Bisher wurden Hüte vom Typ DOKTORHUT DELUXE gewählt. Die Hüte können in verschiedenen Größen bestellt werden, idealerweise hat man für die Wahl den Kopfumfang bereits einmal gemessen oder abgeschätzt.
  • Leichtes Bastelholz, wie bspw. von Hornbach, mindestgröße A3
  • Scharzer Glanzlack, Grundierung zur Nivellierung.
  • Kleine Supermagneten für den Verschluss.
  • Mikrocontroller, wie Arduino Nano oder Raspberry Pi Pico sowie weitere Bauteile, wie Widerstände, Kondensatoren, Mikrotaster usw.
  • Eine möglichst flache Powerbank, am einfachsten mit einer USB-A Buchse.
  • Neopixel RGB-LEDs für alle möglichen Beleuchtungsaufgaben.
  • Empfohlener Kleber für beinahe Alles: Heißkleber, geht Schnell und lässt sich notfalls per Cutter wieder auftrennen.

Konstruktion

Das Gehäuse

  • Die Grundfläche kann bis zu 24x24cm groß sein, die quadratische Fläche der eigentlichen Hüte ist manchmal geringfügig kleiner.
  • Die Seitenwände sollten am Deckel angebracht werden und die Grundfläche von Außen umschließen. Damit ist die Deckelfläche stabilisiert und biegt sich nicht beim Lackieren oder bei der Bearbeitung. Gleichzeitig gibt es bereits eine mechanische Haltekraft, die das Gehäuse auf der Grundfläche halten kann.
  • Die Haltekraft kann mit Magneten auf der Grundfläche verbessert werden, auf Schrankmagnete sollte verzichtet werden, da die Haltekraft zu groß und die Magnete zu schwer sind.
  • Die Grundplatte, die auf dem Hut befestigt wird und auf der die PowerBank montiert wird, sollte am Rand schwarz angestrichen werden, da sich das Holz manchmal verbiegt und die Grundplatte von Außen sichtbar werden kann.
  • Die Haftung zwischen Hut und Grundplatte ist am Besten, wenn man Heißkleber verwendet (schnell auftragen und kleben, da der Kleber sonst kalt wird). Zusätzlich können von der Unterseite her innerhalb des Hutteils kleine Schräubchen gesetzt werden. Alternativ wird doppelseitiges Klebeband eingesetzt werden, was allerdings nicht immer hält.
  • Sollten Batterien oder ähnliches verwendet werden, dann müssen diese erreichbar sein, Verschlüsse wie Magnetschnapper, Verschlußhaken oder Klettband sollten daher eingeplant werden.

Fotodokumentation

...
Deckel des Doktorhuts von unten mit Seitenwänden; Elektronik und Mechanik wird hier direkt eingebaut; Sichtbar sind Abstandhalter für die Bodenplatte sowie Schrauben als Gegenstücke für die Magneten auf der Bodenplatte; Größere Öffnungen sollten vor dem Streichen eingebracht werden, runde Bohrungen können nach dem Bemalen gebohrt werden, da ansonsten die Bohrung durch den Lack zuläuft (darauf achten, dass der Lack nicht durch das Bohren beschädigt wird); Damit es besser aussieht sollten alle Öffnungen durch gedruckte Blenden eingefasst werden.
...
Deckel mit angebrachter Bodenplatte; Wichtig sind die Aussparungen in den Ecken, damit der Deckel später geöffnet werden kann; Die große Öffnung ist hier für die Powerbank vorgesehen, da sie etwas dicker ist und die Huthöhe begrenzt sein soll.
...
Grundplatte mit eingesetzter Powerbank; Einbau diagonal, hier aufgrund der Größe der Powerbank, Ausrichtung ist auch quer denkbar, beachtet werden sollte aber, dass der Hut später mit einer Spitze nach vorn zeigt; Arretiert wird die Powerbank durch einen Bügel und den USB-Stecker; USB-Stecker kann gezogen werden und so die Powerbank auch ausgebaut werden; Es ist zu beachten, dass der Ein-Schalter der Powerbank zugänglich ist; USB-Stecker sollte von Gehäuse getrennt werden, sodass eigene Kabel mit größerem Querschnitt eingelötet werden können.
...
Powerbank mit gezogenen USB-Stecker.
...
Detailaufnahme Bodenplatte mit Supermagneten.
...
Detailaufnahme des magnetischen Gegenstücks.
...
Detailaufnahme Kante am Deckel von Außen; grobe Unebenheiten können mit Heißkleber ausgeglichen werden, der mit scharfem Cuttermesser begradigt wird.
...
Zwei Aufnahmen Grundierung/Ausgleichslack; Zwei Schichten; Jede Schicht schleifen, anschließend Schwarzlack auftragen.
...
Die beginnende Glättung der Oberfläche ist zu erkennen. Nötig sind mehrere Schichten, die jeweils angeschliffen werden. Zu Empfehlen ist auch das Schleifen des Holzes vor der Grundierung.
...
Bodenplatte nach dem Anstrich von Oben und Unten; Voranstrich nicht nötig, aber nach der Montage mit dem eigentlichen Hut, könnte das Holz der Unterseite der Bodenplatte sichtbar sein, da der Hut keine feste Platte hat, sondern biegsame Pappe;
...
Bodenplatte von Unten. Diese Seite liegt auf dem Stoff des Doktorhuts auf und wird großzügig geschwärzt, damit der sich verbiegende Stoff bzw. die darin eingearbeitete Pappe nicht auffallen.
...
Deckel mit fertiger schwarzer Lackierung.
...
Der eigentliche Doktorhut muss von Tassel und Knopf befreit werden; Verschmutzung vermeiden, erst mit der Bodenplatte verheiraten, wenn alle Arbeiten abgeschlossen sind.
...
Beim Verheiraten von Hut und Bodenplatte muss schnell vorgegangen werden: Zu empfehlen ist Heißkleber; Rundherum auftragen und sehr schnell die Bodenplatte aufpressen; Heißkleber verbindet sich sehr gut mit dem Textil;
...
Zusätzlich sollte die Bodenplatte um die Mitte herum mit Schräubchen befestigt werden; Zu empfehlen sind Phillips C 2,2x6,5H nach DIN 7981 A4 (Metall Schneideschrauben mit Linsenkopf und Kreutzschlitz-Antrieb.
...
Die Halterung führt nach dem Einstecken des USB-Steckers zur Arretierung der Powerbank.
...
Arretierte und angeschlossene Powerbank.
...
Fertig montierter geschlossener Hut; Zwischen Bodenplatte und Hut ist kein Holz zu sehen; Holz verbiegt sich nicht, da auf Bodenplatte nichts weiter montiert ist und Deckel durch die Seitenwände in Form gehalten wird.

Elektronische Komponenten

Servo-Motoren
  • Einige Bauteile gehen schnell kaputt, darunter Servomotoren, sie sollten so verbaut werden, dass sie ausgetauscht werden können.
  • Für Servomotoren existieren druckbare Halterungen in klein und groß.
  • Es sollten nicht die billigsten Servos eingesetzt werden, da die schnell kaputt gehen. Ein Servo sollte ca. 5€ kosten.
  • Servomotoren werden mittels PWM-Signalen gesteuert. Die Standard-Arduino Bibliothek generiert dieses Signal mit dem internen Timer und einem Interrupt. Wenn im restlichen Code viel sequentielles gemacht wird, was einem bestimmten timing unterliegt, wie etwa eine Software-Serial-Schnittstelle oder die Ansteuerung der Neopixels, so kommt es schnell zu jittern und ungewünschten Bewegungen der Motoren.
    • Lösung1: Die Hardware-PWM benutzen, dazu braucht es eine andere Bibliothek und die Servos müssen an den richtigen Ports angeschlossen werden.
    • Lösung2: Mindestens auf Animationen der Neopixels verzichten, während Bewegungen ausgeführt werden.
    • Lösung3: Wenn Servos sich nicht bewegen sollen und die aktuelle Position nicht aktiv gehalten werden muss, Servos abschalten per detach().
NeoPixel
  • Neopixels sind RGB-LEDs, die mittels eines Bus in Serie betrieben werden können. Es braucht lediglich einen µC-Port. Allerdings ist das Protokoll Timing-sensitiv, was bedeutet, dass während der Aktualisierung der Farben keine andere Tätigkeit ausgeführt werden kann. Das führt gerne zu Problemen bei der Ansteuerung von Servomotoren.
Mp3-Player
  • Folgende Komponenten werden benötigt (Links exemplarisch):
  • Probleme gab es bisher mit Stereosignalen. Mp3s sollten daher zu Mono konvertiert werden. Es ist zu beachten, dass am Player-Modul die Anschlüsse Spk1 und Spk2 nicht rechter und linker Kanal sind, sondern beide Anschlüsse des Lautsprechers bezeichnen.
  • Mp3-Player und Verstärker können an derselben Powerbank betrieben werden.
  • Beim Ansteuern der Songs per Software ist zu beachten, dass die Nummer der Reihenfolge entspricht, in der die Songs auf die SD-Karte gespielt worden sind.
  • Der Player braucht einen TTL-Pegel (0-3.3V) an der seriellen Schnittstelle, der Arduino gibt 0-5V aus. Daher wird in Sendepfad der Arduinos (Tx-Arduino -> Rx-mp3-Modul) ein Spannungsteiler benötigt, nicht im Empfangspfad.
  • Audio-Schaltkreise immer mit reichlich Kondensatoren (etwa 1000µF ++) puffern.
  • Nicht die Hardware-Serial-Schnittstelle des Arduinos verwenden, die wird für das USB zum Flashen benötigt. Es sollte die SoftwareSerial Bibliothek verwendet werden, die emuliert das UART-Modul und damit die Sende- und Empfangspuffer in Software. Das Bedeutet auch, dass an anderer Stelle im code Jitter entstehen kann, etwa bei der Ansteuerung der Servos in Software.
Schrittmotoren
  • Die billigen 28byj-48 können mit der nativen Arduino Bibliothek betrieben werden, irgendwelche Third-Party-Bibliotheken sind meist unzuverlässig.
  • Achtung: Schrittmotoren können heiß werden. Es können die vier Ports einfach auf Input umgeschaltet werden, dann wird Strom gespart und dem heiß werden vorgebeugt. Allerdings gibt es dadurch einen Positionsglitch und der Motor lässt sich per Hand bedienen.
  • Leider ist das Verfahren des Servos meist blocking, d.h. während der Abarbeitung steht der restliche Code still. Animationen sind in der Zeit nicht möglich. Daher sollte stets überlegt werden, ob man die Bewegung in sehr kleine Teilabschnitte unterteilt. Im Raspberry Pi Pico oder Teensy kann der zweite Core zur Ansteuerung verwendet werden, es ist dann ein kleines IPC-Protkoll zu realisieren.
Powerbank
  • Die Powerbank sollte auf der Grundplatte montiert werden durch eine Halterung, die die Entnahme der Powerbank erlaubt.
  • Der Anschluss der Energieversorgung im Hut erfolgt über ein altes USB-Kabel, einfach die schwarze und rote Ader verwenden. Ggf. das Kabel ersetzen, wenn mehr Strom benötigt wird.
  • Üblicherweise können alle Bauteile mit der Powerbank betrieben werden, zusätzliche Batterien sind nicht nötig.
  • Die meißten Powerbanks schalten nach kurzer Zeit ab, wenn kein Strom entnommen wird. Es sollte ein 500Ω Widerstand zur permanenten Stromentnahme vorgesehen werden. Dieser lässt sich zum Stromsparen je nach Modell auch gepulst betreiben, was mit der Powerbank ausprobiert werden muss.
Schalter
  • Der gesamte Strom des Huts sollte über einen Hauptschalter abschaltbar sein (DIP-Schalter sind dazu gut geeignet.
  • Es sollten weiterhin Geräuschgeber, wie Buzzer abschaltbar sein. Deren Stromversorgung kann einfach über einen weiteren DIP-Schalter unterbrochen werden.
Druckteile
  • Mit Sekundenkleber aufpassen, das Ausdampfen des Lösungsmittels hinterlässt Spuren, dann auch auf dem Lack des Huts. Zu empfehlen wäre hier Heißkleber.

Programmierung

IDE und Projekt
  • Zu empfehlen ist VSCode mit dem Platform.io Plugin
  • Zur Installation von Platform.io, die Anleitung befolgen.
  • Oder falls Python schon installiert ist: pip install -U platformio
  • Im Projekt eine platformio.ini Datei verwenden mit folgendem anpassbarem Inhalt: [env:nanoatmega328]
    platform = atmelavr
    board = nanoatmega328
    framework = arduino
    targets = upload
    lib_extra_dirs = ./lib
    build_flags = -O2
    lib_deps =
    Adafruit NeoPixel
    Hierin wird spezifiziert, dass ein Arduino Nano verwendet wird und dass zusätzliche Bibliotheken benötigt werden.
  • Den Befehl platformio init --ide vscode --board nanoatmega328 ausführen, damit das Projekt mit seinen Abhängigkeiten initialisiert wird. Diesen Schritt wiederholen, wenn sich am ini-File etwas ändert.
  • VSCode installiert die platform.io Tools automatisch.
  • Der Befehl pio run -t upload kompiliert das Projekt und lädt es hoch. Der Port sollte hierbei automatisch bestimmt werden können. In VSCode steht dafür auch ein Build-Target zur Verfügung.
Ablauf
  • Nach dem Anschluss der Stromversorgung, sollte die Programmierung eine Phase vorsehen, in der alles aus ist, da bei der Übergabe des Huts einige Zeit zwischen Einschalten und dem eigentlichen Beginn des Rätsels vergehen kann. Der eigentliche Start des Programms sollte dann durch eine aktive Nutzerinteraktion gestartet werden.
Displays
  • Soll viel Text auf einem Display angezeigt werden, kommt die Software sehr schnell an die Grenzen des Arbeitsspeichers. Daraufhin verhält sich der Mikrocontroller eratisch und tut nicht mehr was er soll. Das kann durch die Verwendung des Makros "F" verhindert werden, das dafür sorgt, dass die Strings im Quelltext nicht in den Arbeitsspeicher, sondern in den Flash-Speicher geschrieben werden. display.println(F("Button!!1!"));
Große Datenstrukturen
  • Wenn viele Daten im Code hinterlegt werden sollen, wir der Arbeitsspeicher schnell voll sein. Per Makro kann der Flash (Programmspeicher) benutzt werden, allerdings braucht es dann Methoden um Daten aus dem Flash erst zu lesen. Pointer auf die gespeicherten Daten sind möglich und werden dazu verwendet den Flash auszulesen.
  • Die Inhalte des Flashs müssen dann aber zunächst gecastet werden: //Anlegen der Datenstruktur, Speichern im Programmspeicher mittels PROGMEM:
    const SCENE_OBJECTS_TYPE SCENE_OBJECTS PROGMEM = {
    .list = {
    //SUN =
    {2u, &COLORS.YELLOW_COLOR, {
    {3, 8},
    {2, 7}
    }}
    };

    //Auslese-Methoden inkl. Cast
    template <typename T> void PROGMEM_readAnything (const T * sce, T& dest)
    {
    memcpy_P (&dest, sce, sizeof (T));
    }

    template <typename T> T PROGMEM_getAnything (const T * sce)
    {
    static T temp;
    memcpy_P (&temp, sce, sizeof (T));
    return temp;
    }

    //Variable im Arbeitsspeicher
    static SCENE_OBJECT loadedSceneObjects[MAX_SCENE_OBJECT_COUNT] = {};

    //Auslesen des Programmspeichers
    PROGMEM_readAnything(loadedScene->objects[i], loadedSceneObjects[i]);