Cocktail Mixer
Ein Selbstbauprojekt

Software


Im Folgenden gehe ich grundsätzlich nur auf die Software des Atmega32-Controllers des Cocktailmixers einschließlich einer genauen Beschreibung der Schnittstelle zum Computer ein. Die unter Bedienung beschriebene C#-PC-Oberfläche kann mit diesem Wissen entweder direkt verwendet oder auch selbst neu geschrieben werden.

Die Seite ist unterteilt in die einzelnen Teile der Software. Diese wurde zur besseren Übersichtlichkeit in verschiedene C-Module mit Quellcode- und Headerdatei aufgeteilt. Erstellt wurde die Mikrocontroller-Software mit dem kostenfreien Tool AVR Studio in der Version 4.19 Build 730 und dem Compiler WinAVR2010.

Auflistung C-Module:

  • pump.c
  • scale.c
  • recipe.c
  • uart.c
  • rgb.c
  • rc5.c
  • task1ms.c
  • SystemStateMachine.c
  • sys_mixing.c
  • sys_wait.c
  • sys_error.c
  • general.c
  • main.c

Ein Tipp vorweg: es hilft ungemein, sich während dem Durchlesen der Beschreibung auch gleichzeitig den entsprechenden Code anzuschauen!

Allgemeine Informationen
Eine wichtige Information, die viele bei der Präsentation ihres Projektes oft vergessen, sind die Einstellungen der Fuses im Mikrocontroller. Ohne diese ist oft unklar, mit welcher Frequenz der Mikrocontroller intern arbeitet. Folgende Darstellung zeigt die Einstellung der Fuses im AVR-Studio.


Abbildung 1: Einstellung der Fuses im AVR-Studio


Wichtig bei der Einstellung der Fuses ist, dass die Auswahl des Taktsignals auf den externen Quarz eingestellt ist. Der Controller arbeitet dann mit den 16MHz des Quarzes.

pump.c - Pumpenansteuerung
Das Modul pump.c ist zum Ansteuern der Pumpen auf unterster Ebene zuständig. Da die Pumpen über Mosfets an den Mikrocontroller angeschlossen sind, lassen sich diese ganz einfach über eine PWM in ihrer Abfüllgeschwindigkeit regeln. Da 10 Pumpen am Controller angeschlossen sind, lässt sich hier nicht die Hardware-PWM, die beim Atmega32 nur 4 Ausgänge besitzt, verwenden. Stattdessen wird eine Soft-PWM mithilfte eines Timers des Controllers erzeugt. Dazu existiert eine Initialisierungsfunktion "PumpInit", mit der der Timer entsprechend eingestellt wird. Zwei Interrupt-Service-Routinen des Timers schalten nun zyklisch den Mosfet der ausgewählten Pumpe an und wieder aus. Der Tastgrad lässt sich dabei über die Funktion "SetPump" von 0-255 einstellen. Dieser ist nahezu proportional zur Durchflussmenge der Pumpe und ermöglicht damit ein Einstellen der Abfüllgeschwindigkeit.
Gleichzeitig verhindert die Funktion "SetPump", dass mehrere Pumpen gleichzeitig laufen. Das ist deshalb notwendig, da die Waage zur Abmessung der einzelnen Bestandteile des Cocktails nicht erfassen kann, wenn gleichzeitig zwei Flüssigkeiten auf einmal in das Glas gegeben werden.

scale.c - Auslesen der Waage
Innerhalb des Moduls scale.c wird die Funktionalität der Waage gekapselt. Das Modul dient der Bestimmung des aktuellen Füllstandes im Glas. Zunächst ist zu erwähnen, dass es innerhalb des Moduls ein Define gibt, welches signalisiert, ob mechanisch überhaupt eine Waage angesteckt ist. Dazu wird von der Waage selbst die Betriebsspannung von 5V auf einen Eingangspin des Controllers gelegt, welcher über das Define SCALE_AVAILABLE abgefragt werden kann.
Da die Waage seriell über eine Datenleitung und eine Taktleitung ausgelesen wird, beginnt die Initialisierungsfunktion "ScaleInit" nun damit, die Taktleitung auf High zu ziehen. Solange keine Kommunikation stattfindet, wird diese Leitung auf High gehalten. Nachdem noch die verwendeten Ausgänge des Mikrocontrollers für die LEDs der Waage gesetzt wurden, wird abschließend noch die Funktion "SetScaleOffset" aufgerufen. Diese liest den aktuellen Wert der Waage aus und nullt das scale-Modul. Der aktuelle Messwert entspricht jetzt 0g.

Aus diesem Grund sollte auch beim Einschalten des Cocktailmixers kein Glas auf der Waage stehen!

Das Modul enthält jetzt noch die benötigten Funktionen, um den aktuellen Wert der Waage auszulesen. Der Wert kann in der internen Einheit 'Counts' oder in Gramm gelesen werden. Die Waage übermittelt das aktuelle Gewicht in einem 24Bit-Wert. Diese 24Bit werden seriell (nacheinander) durch Takten der Taktleitung übertragen. Sofern der Wert in Gramm gewünscht wird, wird der 24Bit-Wert noch mit einem Skalierungsfaktor multipliziert.

Zusätzlich zu den Funktionen zur Gewichtsbestimmung enthält das Modul noch Funktionen um die LED-Farbe der Waage einzustellen. Die Waage kann in Rot, Grün und Gelb leuchten und in den Farben Rot und Grün mit einer Frequenz von 1Hz blinken. Diese Signale werden später von der Statusmaschine dazu verwendet, um dem Nutzer der Maschine mitzuteilen, wann ein Füllprozess in Bearbeitung und wann abgeschlossen ist.

recipe.c - Rezeptverwaltung
Die in recipe.c enthaltene Funktionalität bietet die Möglichkeit ein Rezept in der Maschine zu hinterlegen und abzurufen. Das Rezept wird als statische Variable in einem unsigned-char-Array mit einer Größe von 40 abgelegt. Die Informationen einer Zutat werden in diesem Array in Zweierblöcken gespeichert. Damit lassen sich für ein Rezept 20 Bestandteile abspeichern. Der erste 8Bit-Wert im Array gibt dabei immer die Pumpennummer (von Nr. 1-12, inklusive Magnetventile Nr. 11 und Nr. 12) und der zweite 8Bit-Wert die Menge der Flüssigkeit in Gramm an. Da der Cocktailmixer intern mit Gramm arbeitet, muss eine Umrechnung von Milliliter über die Dichte der Flüssigkeit in Gramm in der PC-Software erfolgen.

Im Modul existieren zwei Funktionen "SetRecipe" und "GetRecipe". Diese sollten eigentlich größtenteils selbsterklärend sein. Eine Besonderheit ist für den Zugriff auf das hinterlegte Rezept zu erwähnen: Um auf das Rezept zugreifen zu können, muss die Rezeptverwaltung vorher für den entsprechenden Lese-/Schreibzugriff gesperrt werden, damit während dem Lese-/Schreibvorgang nicht von einer anderen Funktion aus Teile des Rezepts verändert werden. Dies hätte zur Folge, dass ein inkonsistentes Rezept ausgelesen werden würde.

uart.c - Serielle Kommunikation / USB
Der Programmteil uart.c beinhaltet die Kommunikationsanbindung zum Bedien-PC. Die Verbindung ist über einen UART-USB-Wandler gelöst und kann PC-seitig ganz einfach über eine virtuelle serielle Schnittstelle angesprochen werden. Zunächst muss auch die Hardware des UART im Mikrocontroller initialisiert werden. Dabei werden die von der seriellen Schnittstelle bekannten Parameter wie Baudrate, Bitanzahl, Stop- und Paritybit gesetzt. Die entsprechende Funktion heißt "UartInit" und stellt den UART auf 9600 Baud - 8N1 (8 Datenbits, kein Paritybit, 1 Stopbit) ein.

Zum Senden von Daten bediene ich mich der Hilfsfunktion 'printf' aus der Bibliothek 'stdio.h'. Um diese nutzen zu können, muss eine eigene UART-Funktion "int UartPutc(char c, FILE *stream)" geschrieben werden, welche dem printf zugeordnet wird. Dies hat zur Folge, dass man bei der Ausgabe direkt die Formartierungshilfen der printf-Funktion nutzen kann und die Ausgabe gleichzeitig trotzdem über die gewünschte Schnittstelle gesendet wird. Die Zuordnung der Funktion "UartPutc" zu 'printf' erfolgt über eine globale statische Variable in dem Hauptprogrammteil main.c:

static FILE mystdout = FDEV_SETUP_STREAM(UartPutc, NULL, _FDEV_SETUP_WRITE);

Zusätzlich muss noch 'stdout' zugewiesen werden:

// Zur UART-Ausgabe mit printf
stdout = &mystdout;


Dies realisiert man am besten bei Start der Main-Schleife (siehe main.c).

Die Kommunikation über die serielle Schnittstelle wird grundsätzlich von dem Bedien-PC aus initiiert. Dieser sendet eine Anfrage oder ein Befehl an den Cocktailmixer und dieser Anwortet mit dem entsprechend angefragten Wert oder einem Antwortcode. Die dazu geschriebene Empfangsroutine ist gesichert gegen fremde Befehle oder unbekannte Kommunikation. Es existiert ein Validierungsmechanismus, der unsinnig empfangene Zeichen herrausfiltert. Nicht verwertbare Zeichen können zum Beispiel auch durch Störungen auf der Signalleitung verursacht werden.

Jeder Befehl des Cocktailmixers beginnt mit dem Erkennungszeichen '/'. Es gibt Befehle für das Einspielen eines Rezeptes, das Sperren und Freigeben der Rezeptverwaltung, dem Auslesen der Waage, für ein Hard- oder Softreset, für das Abfragen des Fehlerzustandes und dem Einstellen der LED-Beleuchtung.

Folgende Tabelle liefert einen Überblick über die vorhandenen Befehle des Cocktailmixers:

--> Die Befehlsübersicht musste aus Platzgründen leider auf eine extra Seite verschoben werden:
 
Befehlsübersicht

Jeder Befehl hat jeweils einen entsprechenden Antwortcode und einen Fehlercode. Sofern die Übermittlung und die auszulösende Funktion einwandfrei funktioniert haben, sendet der Mikrocontroller den gleichen Befehl zurück. Bei angefragten Variablen enthält dieser zusätzlich noch den jeweiligen Wert. Sofern eine Kommunikation Fehlerhaft war, sendet der Mikrocontroller den dargestellten Fehlercode zurück und der Befehl muss erneut gesendet werden.

rgb.c - LED-Beleuchtung
Die Umsetzung dieses Moduls bereitet immer am meisten Freude. Die RGB-LEDs verleihen dem Cocktailmixer erst sein eindrucksvolles Erscheinen. Natürlich geht es auch ohne die Beleuchtung, für die die es schlicht mögen oder sich den Aufwand sparen möchten. Das Modul rgb.c hat grundsätzlich 5 LED-Programme und das Programm "Off". Die Programme sind wie folgt implementiert:

  • LED_OFF = 0
  • RGB = 1
  • HSB = 2
  • HSB_BLINK = 3
  • HSB_FADE = 4
  • RGB_STROBE = 5
Zur Verwendung der LED-Programme wird die Hardware-PWM des Mikrocontrollers verwendet, um drei PWM-Signale jeweils für die drei Farben rot, grün und blau zu erzeugen. Die drei PWMs werden von zwei Timern Timer1 und Timer2 generiert. Um diese einzustellen und die Programme verwenden zu können muss die Initialisierungsfunktion "RGBInit" aufgerufen werden. Diese Funktion liest zusätzlich alle vorher im EEPROM abgespeicherten Werte für die Farbtöne, Helligkeiten, Geschwindigkeiten und Programmauswahl aus und setzt diese. So startet der Cocktailmixer nach dem Einschalten stets mit dem bei dem letzten Betrieb eingestellten Lichtprogramm.
 
Zur Verwendung der Lichtprogramme bietet das Modul verschiedene Funktionen an. Die zentrale Funktion ist die Funktion "SetRGBProgram", mit der das LED-Programm ausgewählt werden kann. Je nach verwendetem Programm können dann über entsprechende weitere Funktionen die Eigenschaften den Lichtprogramms verändert werden.
So existieren zum Beispiel für den RGB-Modus drei Funktionen "SetRGBRed", "SetRGBGreen" und "SetRGBBlue" zur Einstellung der Farbe
Das Programm HSB verwendet hingegen die Funktionen "SetHSBHue" und "SetHSBSatiation" zur Einstellung des Farbtons und der Sättigung.
Das Programm HSB_BLINK hat zusätzlich noch eine Funktion, um die Blink-Geschwindigkeit einzustellen. Selbes gilt für die Programme HSB_FADE und RGB_STROBE. Für beide existiert ebenfalls eine Methode, um die jeweiligen Effektgeschwindigkeiten einzustellen.
Für alle Lichtprogramme gibt die Funktion "SetBrightness", mit der sich die Helligkeit der Beleuchtung einstellen lässt.

rc5.c - IR-Empfänger
Das Modul rc5.c beschäftigt sich mit dem Auslesen eines Infratorempfängers. Dieser wurde zusätzlich angedacht, um neben dem Bedien-PC eine zweite Möglichkeit zu haben, auf den Cocktailmixer remote zugreifen zu können. Im Fall der hier vorliegenden Implementierung werden bei Tastendruck auf die einzelnen Zifferntasten der Fernbedienung die entsprechenden Pumpen voll angeschaltet. Diese Vorgehensweise dient Reinigungszwecken und kann nach erfolgreichem Einsatz des Cocktailmixers dazu verwendet werden, um Reinigungsflüssigkeit durch die einzelnen Pumpen zu leiten.

Der IR-Empfänger TSOP1136 ist am Interrupt-Pin INT0 des Mikrocontrollers angeschlossen. Um diesen auszuwerten muss zunächst der Interrupt aktiviert werden. Dies wird von der Initialisierungsfunktion "rc5_init" übernommen. Gleichzeitig verwendet die Auswerteroutine des RC5-Codes den Overflow-Interrupt des für die PWM der LEDs verwendeten Timer2. Der Interrupt wird ebenfalls von der Initialisierungsfunktion aktiviert.

Die Arbeit mit dem Modul ist recht einfach gehalten. Das Modul versucht laufend die empfangenen Signale des IR-Empfängers einem RC5-Code zuzuordnen. Dies läuft Interrupt-gesteuert im Hintergrund ab und man muss sich darüber keine Gedanken mehr machen. Um nun einen möglicherweise empfangenen Code auszuwerten kann man über die Funktion "GetFrame" das Modul abpollen. Sofern ein gültiger Code empfangen wurde gibt die aufgerufene Funktion eine 1 zurück und in der übergebenen Variablen steht der entsprechende Code. Zusätzlich zum empfangenen Code gibt das Modul auch die Geräteadresse zurück. So lassen sich auch verschiedene Fernbedienungen für DVD-Player, Fernseher, etc. gleichzeitig für unterschiedliche Funktionen nutzen.
Die Auswertung der RC5-Befehle, also das Pollen der Funktion, erfolgt hier in der while(1)-Schleife der main-Funktion. Grundsätzlich sei erwähnt, dass die while(1)-Schleife optimalerweise bei sauberer Programmierung von Mikroprozessoren mit Timer-Hardware leer ist und man sich vorher Gedanken über die zeitlichen Aufrufe der benötigten Funktionen gemacht hat. Damit ist gemeint, dass alle Funktionen an Interrupt-Service-Routinen eines Timers gebunden sind und zyklisch nach Notwendigkeit aufgerufen werden. Da die RC5-Auswertung jedoch gepollt werden muss und es zusätzlich nicht die wichtigste Funktion ist, welche zeitlich absolut zu exakt bestimmten Zeitpunkt ausgeführt werden müsste, ist dies die einzige Funktionalität die sich hier in der while(1)-Schleife befinden darf!

task1ms.c - Task der Statusmaschine
Dieses Modul bestimmt den zeitlichen Ablauf für den Aufruf aller Funktionen. Wie im vorherigen Kapitel bereits erwähnt, ist die while(1)-Schleife der main-Funktion idealerweise leer. Das macht es notwendig, alle benötigten Aufrufe von Funktionen einem Ablauf zuzuordnen.
Dazu gibt es eine oder mehrere Task-Funktion, deren Name die zyklische Zeit darstellt, mit der diese aufgerufen werden. Im Cocktailmixer gibt es eine Funktion "Task1ms", die vom Timer0 (welcher für die Pumpen verwendet wird) jede Millisekunde aufgerufen wird. In dieser Funktion wird jetzt zum Beispiel Funktionalität aufgerufen, die die Effekte beim ausgewählten LED-Programm erzeugen. Zusätzlich wird ein Zähler für Folge-Task-Funktionen mit geringerer Zykluszeit aufgerufen. Ein Beispiel dafür ist die "Task1s"-Funktion, welche dafür sorgt, dass die Status-LEDs der Waage oder des Cocktailmixers mit 1Hz blinken.
Hauptzweck der Funktion "Task1ms" ist jedoch der Aufruf der Statusmaschine (alle 10ms - mit eigener 10ms-Zählervariablen innerhalb der Task1ms-Funktion).

SystemStateMachine.c - Die Statusmaschine
Zunächst ein paar Worte, was überhaupt der Sinn einer Statusmaschine ist. Eine Statusmaschine in einem Gerät ist ein Verhaltensmodell bestehend aus Zuständen, Zustandsübergängen und Aktionen. Das Gerät befindet sich dabei immer in einem der Zustände. Sofern eine Benutzeingabe oder ein von einem Interrupt einer anderen Funktionalität generierten Events die Statusmaschine zu einem Zustandswechsel zwingt, wird eine Aktion ausgeführt und die Zustandsmaschine welchselt in einen anderen Zustand, abhängig der getätigten Eingabe. Bei einem Wechsel des Zustandes gibt es hier drei Arten von Aktionen:

  • Ausgangsaktion - Funktionalität wird beim Verlassen des alten Zustandes aufgerufen
  • Eingangsaktion - Funktionalität wird beim Eintreten in den neuen Zustand aufgerufen
  • 10ms-Aktion - Funktionalität wird zyklisch alle 10ms im neuen Zustand aufgerufen

Findet nun ein von außen initiierter Wechsel eines Zustandes statt, so ruft der aktuelle Zustand augenblicklich seine eigene Ausgangsfunktion auf. Hier kann sozusagen "aufgeräumt werden". Anschließend wird direkt die Eingangsfunktion des neuen Zustandes aufgerufen. Hier können dann initiale Einstellungen für den nächsten Zustand getroffen werden. Anschließend wechselt der Zustand im nächsten Durchlauf zum neuen Zustand und verharrt dort dann zyklisch im 10ms-Aufruf, wo dessen eigentliche Funktionalität aufgerufen wird.
Dieses Prinzip bietet die einfache Möglichkeit beim Eintreten und Verlassen von Zuständen Dinge zu erledigen. Ein Beispiel dafür ist zum Beispiel das Freigeben der Pumpen im Cocktailmixer. Die Pumpen dürfen nur im Zustand 'cMixing' aktiv sein. In allen anderen Zuständen müssen diese zwangsläufig deaktiviert sein. So kann man nun beim Verlassen des Zustandes 'cMixing' alle Pumpen auf 'Aus' setzen. Damit ist gewährleistet, dass beim Verlassen des Zustandes 'cMixing' alle Pumpen deaktiviert werden.

Die Zustandsmaschine im Cocktailmixer wird anfänglich noch durch eine Funktion "SystemStateMachineInit" initialisiert. Dabei wird der Startzustand gesetzt. Anschließend wird die Funktion "SystemStateMachine" alle 10ms aufgerufen und bestimmt, in welchem Zustand sich der Cocktailmixer befindet.
Der Cocktailmixer hat drei Zustände: 'cMixing', 'cWait' und 'cError'. Für jeden Zustand wird eine eigene Funktion "FctMixing", "FctWait" und "FctError" aufgerufen. Diese Funktionen enthalten die oben beschriebenen Wechselmechanismen, die bestimmen, was bei Ein- und Ausgang in den jeweiligen Zustand ausgeführt wird. So wird zum Beispiel die Farbe der LEDs der Waage eingestellt, die bereits erwähnten Pumpen freigegeben und gesperrt und die Rezeptverwaltung für den Zustand 'cMixing' gesperrt.

Für jeden Zustand gibt es jetzt ein eigenes Modul, um die enthaltene Funktionalität weiter zu gliedern und so übersichtlicher zu gestalten:

  • sys_mixing.c
  •  sys_wait.c
  • sys_error.c

sys_wait.c - Wartezustand
Der im Modul sys_wait.c gekapselte Wartezustand ist der einfachste aller drei Zustände. In diesem Zustand wartet der Cocktailmixer auf Eingaben. Die einzige Eingabe, die nicht ignoriert wird ist das Aufstellen eines Glases. Alle anderen Benutzereingaben, wie das Ausführen eines Resets oder das Drücken des Starttasters des Cocktailmixers haben keinen Effekt.
Wird ein Glas mit mehr als 150 Gramm auf den Teller der Waage gestellt, so erkennt der Cocktailmixer dies und wechsel in den Zustand 'cMixing' (sofern nicht gerade vom Bedien-PC aus ein Rezept eingespielt wird).
Gleichzeitig wird die Funktion der Waage über einen ErrorCounter überwacht. Geht das Auslesen der Waage zu oft schief, so wechselt der Cocktailmixer in den zustand 'cError'.

sys_error.c - Fehlerzustand
Die sich im Modul sys_error.c befindende Implementierung des Fehlerszustandes besitzt eine Initialisierungsfunktion "Troubleshooting01msInit". Diese wird beim Eintreten in den Fehlerzustand aufgerufen und setzt den Fehler sowie die Fehlerquelle im Zustand. Wenn der Fehler im Zustand vorgehalten wird, hat dies den Vorteil, dass man am Bedien-PC den vorliegenden Fehler abrufen kann. Im Zustand selbst werden jetzt jegliche Benutzereingaben ignoriert.
Der Zustand kann nur noch durch einen Soft-Reset verlassen werden. Sofern dieser Reset ausgeführt wird, wird die Waage neu initalisiert und der Fehlercode gelöscht. Anschließend wechselt der Cocktailmixer wieder in den Zustand 'cWait'.

sys_mixing.c - Zustand zur Mixerausführung
Der Zustand bei dem der Cocktailmixer seine eigentliche Arbeit verrichtet und den Cocktail mixt ist logischerweise der komplexeste. Genau genommen besteht dieser Zustand aus einer eigenen Statusmaschine, welche für jede Speicherstelle des Rezeptes einen eigenen Zustand besitzt. Die Ausführung des Mischvorgangs durchläuft nun jeden Zustand einzeln hintereinander und füllt entsprechend des im Rezept gespeicherten Wertes das entsprechende Getränk ab.

Bei dem Eintritt in den Zustand 'cMixing' steht die interne Statusmaschine auf dem durch die Funktion "Mixing10msInit" initial eingestellten Zustand 'cWaitForUserInput', in dem auf das Drücken des Start-Knopfes des Cocktailmixers gewartet wird.
Sofern dieser gedrückt wird erfolgt für jede der 20 Speicherstellen der gleiche Ablauf. Der Cocktailmixer liest sich beim Eintritt in den Zustand für die entsprechende Speicherstelle den aktuellen Waagenwert aus. Von diesem Wert ausgehend muss dann die geforderte Menge Flüssigkeit im Glas ergänzt werden. Anschließend wird im eigentlichen Zustand geprüft, welche Pumpe innerhalb der Speicherstelle gefordert ist und die entsprechende Pumpe aktiviert.
Der Zustand wartet nun bis die vom Rezept gewünschte Grammzahl abgefüllt wurde. Dabei wird überwacht, ob sich die Menge der Flüssigkeit im Glas überhaupt erhöht. Sollte dem nicht so sein (zum Beispiel weil eine Flasche leer geworden ist), so wechselt der Cocktailmixer in den Fehlerzustand mit dem Fehlercode "NO_FLUID". Dies ist deshalb wichtig, da die Pumpen nicht im Leerlauf laufen sollen.
Zusätzlich wird außerdem überwacht, ob die gemessene Grammzahl der Waage wieder weniger wird. Sollte dies geschehen (zum Beispiel weil ein Gast sein Glas trotz laufender Abfüllung wegzieht), so beendet der Cocktailmixer augenblicklich den Abfüllvorgang.

Nach dem Durchlauf aller Speicherstellen, oder falls das Rezept frühzeitig mit leeren Speicherstellen endet, wechselt die interne Statusmaschine des Zustandes 'cMixing' in den Endzustand 'cFinished'. Dort verharrt der Cocktailmixer, bis der Gast sein Glas vom Teller der Waage nimmt. Der beendete Abfüllvorgang wird dabei von einem grünen Blinken der Waage  signalisiert.

Mit der Wegnahme des Glases wechselt die eigentliche Statusmaschine des Cocktailmixers wieder in den Zustand 'cWait' und ein neuer Abfüllvorgang kann vorgenommen werden.

general.c - Hilfsfunktionen des Cocktailmixers
Das Modul general.c enthält Hilfsfunktionen für die Benutzerein- und ausgabensteuerung des Cocktailmixers. Die Funktionalität umfasst den Starttaster des Cocktailmixers, das Reset-Flag und die Hauptstatus-LED auf der Vorderseite des Mixers. Mithilfe des Moduls lässt sich die LED einstellen oder der Taster, bzw. das RESET-Flag abfragen.
Zur Verwendung des Moduls muss dieses über die beiden Initialisierungsfunktionen "InitKeys" und "InitStatusLED" initialisiert werden.

main.c - Hauptprogramm Cocktailmixer
Abschließend bleibt die main-Funktion des Cocktailmixers zu erwähnen. Diese Funktion befindet sich in der Datei main.c und beinhaltet neben der bereits erwähnten Implementierung der RC5-Auswertung die Aufrufe aller Initialisierungsfunktionen und startet damit den Cocktailmixer durch.
Die folgende Ansicht zeigt den kompletten Start des Cocktailmixers aus der Main-Funktion:

    // Initialisierung der Status-LEDs
    InitStatusLED();

    // Initialisierung der Taster-Eingabe
    InitKeys();

    // Initalisierung der UART-Kommunikation
    UartInit();

    // Initialisierung der Pumpenansteuerung
    PumpInit();

    // Initialisierung der RGB-Beleuchtung
    RGBInit();

    // IR-Fernbedinung initialisieren
    rc5_init();

    // Ausgabe des Intros
    printf("CocktailmaschineV2");

    // Setzen der Status-LEDs
    SetStatusLEDMain(STATUS_ON);

    // Globale Interruptfreigabe
    sei();

    // Initialisierung der Waage
    ScaleError = ScaleInit();

    // Initialisiert die System-Status-Maschine
    if(ScaleError == OK)
    {
        SystemStateMachineInit(cWait, ScaleError, NO_ERROR);
    }
    else
    {
        SystemStateMachineInit(cError, ScaleError, ERROR_SCALE);
    }

    // main-Schleife
    while(1) {...}

    
Ich hoffe die Erläuterungen helfen, den zur Verfügung gestellten Programmcode zu verstehen. Zusätzlich sind auch jede Funktion des Codes und die Module selbst mit einem Header dokumentiert.

Zum Anfang der Seite