Futterautomat: Unterschied zwischen den Versionen
Zeile 372: | Zeile 372: | ||
* '''Setup''' | * '''Setup''' | ||
Für den Aufbau der Codestruktur wurde der Code von EduArduino [https://www.youtube.com/watch?v=6NVN1Wb9fZw EduArduino Bildschirmcode] als Grundstruktur verwendet und entsprechend unserer Anforderungen angepasst. | |||
Für die Menüsauswahl werden die Integer-Variabeln Number_Menu für die Seitenauswahl und Number_title für die Auswahl des Seitentitels kreiert. | Für die Menüsauswahl werden die Integer-Variabeln Number_Menu für die Seitenauswahl und Number_title für die Auswahl des Seitentitels kreiert. |
Version vom 7. Januar 2021, 12:31 Uhr
Autoren: Katrin Schöne, Maike Lütkewitte
Betreuer:
→ zurück zur Übersicht: WS 20/21: Angewandte Elektrotechnik (BSE)
Einleitung
Die Studierenden des Masterstudiengangs "Business and Systems Engineering" sollen im Rahmen des Praktikums "Angewandte Elektrotechnik" ein Projekt bearbeiten. Das Projekt beinhaltet folgende Ziele:
- Auslesen von Sensordaten
- Verarbeiten der Daten mithilfe eines Mikrocontrollers
- Ansteuerung eines oder mehrerer Aktoren
Als Anwendungsfall für dieses Projekt wird ein Futterautomat für Katzen entwickelt. Dieser soll jedem Tiere eine individuell festgelegte Futtermenge zur Verfügung stellen. Somit kann auch bei Abwesenheit des Besitzers eine regelmäßige Fütterung der Tiere sichergestellt werden.
Anforderungen
Der Futterautomat soll die folgenden Anforderungen erfüllen:
- Erkennung der unmittelbaren Anwesenheit des Tiers am Futterautomaten sowie Unterscheidung mehrere Tiere voneinander
- Ausgeben der richtigen Futtermenge
- Erkennung und Anzeigen des Füllstands des Futterspeichers
- Schutz vor Überfüllung der Futterschale
- Anpassung der Futtereinstellungen (Menge und Häufigkeit) für jedes Tier
Funktionaler Systementwurf/Technischer Systementwurf
Komponentenspezifikation
Pos. | Anz. | Bezeichnung | Artikel/Link | Im Starterbaukasten enthalten (x) |
---|---|---|---|---|
1 | 1 | Arduino UNO R3 | x | |
2 | 1 | Grove 125 KHz RFID Reader | RFID-Reader | |
3 | 3 | RFID Chip mit 125 kHz Transponder | RFID-Chip | |
4 | 2 | TRCT5000 IR Modul | IR Sensor | |
5 | 1 | Servomotor | x | |
6 | 1 | LCD-Display | x | |
7 | 1 | LED rot | x | |
8 | 1 | LED grün | x | |
9 | 3 | Taster (Schließer) | x | |
10 | 3 | Widerstand 1 kΩ | x | |
11 | 2 | Widerstand 330 Ω | x |
Zusätzlich wird ein Kunststoffgehäuse erstellt.
Umsetzung (HW/SW)
Hardware
Die Hardware besteht aus verschiedenen elektrischen sowie mechanischen Komponenten. Eine Stückliste der elektrischen Bauteile ist unter Komponentenspezifikation zu finden. Im Folgenden soll kurz näher auf die verwendeten Sensoren eingegangen werden.
RFID-Sensor
Die verschiedenen Tiere sollen mittels RFID-Chip am Halsband erkannt und unterschieden werden. Dazu wird ein RFID-Reader am Futternapf benötigt. Für den Anwendungsfall werden RFID-Reader und Transponder mit einer Frequenz von 125 kHz gewählt. Der Grove - 125KHz RFID Reader hat einen maximalen Leseabstand von 7 cm[1]. Durch die Verwendung dieses Readers soll gewährleistet werden, dass eine Futterausgabe erfolgen kann, wenn das Tier nahe genug an den Napf herantritt. Eine direkte Berührung ist nicht erforderlich.
Infrarotsensoren
Zur Füllstandserkennung für den Futterbehälter und den Futternapf wird das KY-033 Linienfolger Modul verwendet. Dieses nutz den IR-Sensor TCRT5000 und gibt via Analogausgang eine Spannung aus. Der im Datenblatt[2] gegebene Arbeitsbereich liegt zwischen 0,2 mm und 15 mm. Unter der Annahme, dass das Futter im zu überwachenden Behältnis gleichmäßig verteilt ist, reicht bei einem in der Wand verbauten Sensormodul eine geringe Reichweite von einigen mm aus, um zu detektieren, ob Futter vorhanden oder nicht vorhanden ist.
Schaltplan
Aufbau auf Steckbrett
Aufbau auf Lochrasterplatine
Um einen möglichst platzsparenden und sicheren Einbau der elektrischen Komponenten in den Futterautomaten zu ermöglichen, wird eine Lochrasterplatine verwendet. Auf dieser Lochrasterplatine werden die Widerstände und Schraubklemmen zur Verbindung mit dem Arduino UNO und den extern gelegenen Bauteilen verschaltet. Der Arduino UNO wird an jeder Seite mit einer Schraubklemmleiste versehen. Diese bietet die Möglichkeit einer deutlich stabileren mechanischen Fixierung der Leitungen im Vergleich zu den Steckbuchsen des Arduino UNO. Die elektrischen Komponenten, wie diverse Aktoren und Sensoren werden an den entsprechenden Stellen im Futterautomat verbaut. Durch Lötverbindungen werden sie mit Leitungen verbunden, welche dann an die Klemmen des Arduino UNO bzw. der Lochrasterplatine angeschlossen werden können.
3D-Modell
Der Futterautomat besteht insgesamt sechs Komponenten. Im Folgendem werden diese im Einzelnen beschrieben. Zu Anfang des Projektes wurden 3D-Modelle auf Basis von ersten theoretischen Überlegungen erstellt. Nach dem Testen der gedruckten Komponenten wurde für einige Komponenten eine überarbeitete Version konstruiert, um diese mechanisch zu verbessern. Für die Erstellung der 3D-Modelle wurde Autodesk Fusion 360 verwendet.
- Technikbehälter
Der Technikbehälter dient zur Aufbewahrung der elektrischen Komponenten. Er hat eine Grundfläche von 140mm x 60mm, eine Höhe von 220mm und eine Wandstärke von 2mm. Auf der Vorderseite werden Aussparungen für den Bildschirm, die drei Taster und die beiden LEDs gelassen. An der Seite befindet sich ein kreisrundes Loch für die Kabel. Damit der Füllstand des Futterbehälters erfasst werden kann, ist auf der Rückseite eine rechteckige Aussparung mit den Maßen 11mm x 5,7mm eingefügt. Damit in Zukunft ein Deckel ergänzt werden kann, existieren auf der oberen Kante zwei Ösen zum Öffnen und Schließen des Deckels.
- Futterbehälter
Der Futterbehälter hat eine Grundfläche von 190mm x 60mm, eine Höhe von 220mm und eine Wandstärke von 2mm. Er wird hinter neben dem Technikbehälter angebracht und hat die Funktion das Futter aufzubewahren. An der oberen Kante befinden sich ebenfalls zwei Ösen, um zukünftig einen Deckel anzubringen. Auf einer Seite befindet sich die gleiche rechteckige Aussparung für den IR-Sensor, wie beim Technikgehäuse, zur Füllstandserfassung. Die Unterseite ist leicht abgeschrägt, damit das Futter nachrutschen kann. Zwischen Grundfläche und Futteröffnung befindet sich ein Abstand von 32,311mm. Der Winkel beträgt 7,305°. Die Futteröffnung ist ein ebener Kreis mit Radius 38,118mm, der sich in der Mitte des Behälters befindet und zu einem Drittel geöffnet ist. Durch diese Öffnung kann später das Futter rutschen.
Verbesserung:
Der Winkel der Schräge ist nicht groß genug gewählt, aufgrund dessen rutscht das Futter nicht nach. Zudem ist der Futterbehälter überdimensioniert. Deswegen wird die Breite auf die Hälfte reduziert. Bei der neuen Version ist eine Seite gerade, sodass der IR-Sensor für die Füllstandserkennung platziert werden kann. Aus diesem Grund befindet sich die Futteröffnung nicht mehr zentral unter dem Futterbehälter, sondern an der geraden Seitenfläche. Außerdem wird der Abstand zwischen Öffnung und Grundfläche auf 117,348mm und der Winkel der Abschrägung auf 62,342° erhöht. Zusätzlich wird aus dem Drittel-Kreis der Öffnung ein Rechteck mit den Maßen 29,5mm x 51,5mm.
- Rutsche
Die Rutsche hat die Funktion, dass das Futter vom Futterbehälter in den Futternapf gelangen kann. Sie hat eine Länge von 160,942mm und eine Maximalhöhe von 92,174mm. Die Rutschfläche ist 36mm breit. An den Seiten befinden sich Erhebungen, die verhindern sollen, dass das Futter zu den Seiten hinausläuft. Die beiden vorderen Stützen sind nicht miteinander verbunden, damit der IR-Sensor zur Füllstandserkennung des Futternapfes ggf. an dieser Stelle verbaut werden kann.
Verbesserung:
Die Seitenabgrenzungen wurden an der Futteraustrittsstelle manuell mithilfe von Pappstücken provisorisch erhöht. Dadurch wird ein Überlaufen des Futters minimiert.
- Stützen
Aufgrund der Höhenlage der Rutsche müssen sich die Behälter ca. 100mm über den Boden befinden. Deshalb werden die Behälter von Stützen getragen. In der Konstruktion werden sowohl Eckstützen als auch Seitenstützen kreiert. Jedoch werden nur die Eckstützen gedruckt, weil diese bereits genügend Stabilität bieten. Die Stützen haben eine Höhe von 150mm. Auf der Höhe von 107,5mm befindet sich eine kleine Plattform mit der Grundfläche 21,416mm x 25mm und einer Dicke von 1,5mm. Diese Plattform dient als Ablagefläche für den Technikbehälter. Aufgrund der Trichterform am unteren Ende des Futterbehälters ist an diesen Eckstützen die Plattform nur 2mm lang. Somit kann der Behälter nicht in Schieflage geraten.
- Futternapf
Der Futternapf hat einen Radius von 75mm und eine Randhöhe von 40mm. Die innere Futterfläche ist leicht abgeschrägt. Somit soll das Futter weiter ins Innere rutschen. An einer Seite befindet sich eine Aussparung für den IR-Sensor auf der Höhe von 27,021mm.
- Futterverschluss
Der Verschluss hat einen Radius von 38,118mm und entspricht dem Futteröffnungsradius. Es wird eine Fläche von 141° bedeckt, somit ist diese circa 20° größer als die Futteröffnung.
Verbesserung:
Aufgrund des Gewichtskraft des Futters verbiegt sich der Verschluss, sodass trotz verschlossener Abdeckung Futter auf die Rutsche fällt. Aus diesem Grund wird ein überarbeiteter Kreis mit einem Radius von 44mm erstellt. Der Kreis erhält eine Aussparung von 120°. Damit bildet der neue Entwurf nahezu das Gegenstück zur ursprünglichen Konstruktion.
Wenn die einzelnen Komponenten zusammengefügt werden, entsteht der folgende Futterbehälter.
Software
Die Software wird in der Entwicklungsumgebung Arduino IDE in der Programmiersprache C++ geschrieben. Die Software ist in zwei Bereiche zu unterteilen: Die Software für das LCD Display und die Eingabe über die Buttons wird zunächst getrennt von der Software zur Steuerung des Hauptprogramms betrachtet.
Includes
Zunächst werden die Bibliotheken eingebunden, die für die Ansteuerung des LCD Displays und des Motors sowie das Auslesen des RFID Readers benötigt werden. Weitere Informationen zu diesen Bibliotheken sind hier zu finden:
LiquidCrystal_I2C
Wire
Servo
SoftwareSerial
Zudem wird die selbstgeschriebene Klasse Katze verwendet.
Die Klasse Katze
Die Klasse Katze enthält alle notwendigen Attribute und Methoden, die im Zusammenhang mit der Funktionsweise des Futterautomaten erforderlich sind.
Hauptprogramm
- Programmablaufplan
Das Arduino Programm besteht aus einer Setup-Funktion, welche einmalig zu Beginn aufgerufen wird, und einer Loop-Funktion, welche im Anschluss an die Setup-Funktion dauerhaft wiederholt wird.
- Setup
void setup() { Serial.begin(9600); SoftSerial.begin(9600); //Setup Motor motor.attach(PinDigitalMotor); motor.write(0); delay(100); //Setup IOs pinConfiguration(); fuellstandLEDSetup(); //Speichern der Katzen in Array katzenListe[0] = mimi; katzenListe[1] = miezie; katzenListe[2] = luna; //Setup LCD lcd.init(); lcd.backlight(); Serial.println("Setup abgeschlossen."); }
- Loop
In der Loop wird zunächst die Anzeige auf dem LCD Display erzeugt. Nähere Informationen zum Display folgen in einem späteren Abschnitt. Im Anschluss wird der Status des Futterbehälters geprüft. Nach der Abfrage geht der Futterautomat in den „Normalbetrieb“.
void loop() { Page_Start(); Page_1(); Page_1_1(); Page_1_2(); Page_2(); Page_2_1(); Page_2_2(); Page_3(); Page_3_1(); Page_3_2(); if (abfrageFuellstandFutterbehaelter() == true) { if (statusFuellstandFutterbehaelter == false) { setFuellstandVoll(); } Normalbetrieb(); Serial.println("Futter voll"); } else { if (statusFuellstandFutterbehaelter == true) { setFuellstandLeer(); } Serial.println("Futter leer"); } delay(200); }
Im Normalbetrieb wird zunächst darauf gewartet, dass über den RFID-Reader Daten empfangen werden. Ist dies der Fall, findet das Auslesen und Auswerten der Daten mithilfe der Funktion auslesenRFID statt. Diese Funktion liefert einen Zeiger auf die mittels RFID Nummer erkannte Katze. Ist die Nummer unbekannt oder mehrdeutig wird ein Nullpointer zurückgegeben. Dieser Fall wird im weiteren Programmverlauf abgefangen. Zum Auslesen der RFID-Nr. wird die unter Grove - 125KHz RFID Reader gegebene Implementierung verwendet.
Katze* auslesenRFID() { Serial.println("Auslesen startet"); unsigned char buffer[64]; int count = 0; if (SoftSerial.available() > 0) { while(SoftSerial.available()) { buffer[count++] = SoftSerial.read(); if(count == 64)break; } Serial.write(buffer, count); // Katze herausfinden int anzahlKorrekt = 0; int indexKorrekt = 0; if (count == 14) { bool nummernVgl[anzahlKatzen];//bool Array mit so vielen Feldern wie Katzen for (int k = 0; k < anzahlKatzen; k++) { nummernVgl[k] = true; } for (int i=0; i < (count-1); i++) { for (int k = 0; k < anzahlKatzen; k++) { unsigned char test[14]; katzenListe[k].getRfidNr().toCharArray(test, 14); if (test[i] != buffer[i]) { nummernVgl[k] = false; } } } for (int k = 0; k < anzahlKatzen; k++) { if (nummernVgl[k] == true) { anzahlKorrekt ++; indexKorrekt = k; } } } count = 0; if(anzahlKorrekt == 1) { return &katzenListe[indexKorrekt]; } else { return nullptr; } } }
Sofern kein Nullpointer zurückgegeben wird, muss geprüft werden, ob für das erkannte Tier eine Futterausgabe erfolgen soll. Die Häufigkeit der Futterausgabe ist über Mindestzeitabstände definiert, die zwischen zwei Ausgaben eingehalten werden müssen. Mögliche Zeitzeitabstände sind 1h, 2h, 6h, 12h und 24h. Diese sind in der Klasse Katze definiert. Jede Katze besitzt eine Integer Variable Häufigkeit, welcher einer der fünf möglichen Zahlenwerte hinterlegt ist.
Zudem besitzt jede Katze eine Variable, welche den Zeitpunkt der letzten Fütterung in ms (Zeit relativ zum Start des Programmstarts) anzeigt. Anhand dieser Zeit und der festgelegten Häufigkeit kann der Zeitpunkt der nächstmöglichen Fütterung in ms berechnet werden. Durch einen Vergleich mit dem aktuellen Zeitpunkt, welcher durch die Funktion millis() ermittelt werden kann, wird geprüft, ob eine Futterausgabe erfolgen soll oder nicht.
Die Zeitwerte in ms werden in unsigned long Variablen gespeichert. Der maximal mögliche Wert dieser Variable beträgt 4.294.967.295 ms. Demnach findet alle 4,97 Tage ein Überlauf statt und das Zählen beginnt erneut bei 0. Um die Reaktion auf diesen Überlauf zu definieren, werden die möglichen Stellungen aus aktuellem Zeitpunkt, letztem Fütterungszeitpunkt und mindestens zu erreichendem neuem Fütterungszeitpunkt ausgewertet.
Vergleich der Zeitpunkte | Schlussfolgerung bzgl. Futterausgabe |
---|---|
Letzte Fütterung <= Nächstmögliche Fütterung < Aktueller Zeitpunkt | Futterausgabe |
Letzte Fütterung < Aktueller Zeitpunkt < Nächstmögliche Fütterung | Keine Futterausgabe |
Nächstmögliche Fütterung < Letzte Fütterung < Aktueller Zeitpunkt | Keine Futterausgabe |
Nächstmögliche Fütterung < Aktueller Zeitpunkt < Letzte Fütterung | Futterausgabe |
Aktueller Zeitpunkt < Nächstmögliche Fütterung < Letzte Fütterung | Keine Futterausgabe |
Aktueller Zeitpunkt < Letzte Fütterung < Nächstmögliche Fütterung | Futterausgabe |
if (hungrigeKatze != nullptr) { Serial.print("Katze erkannt: "); Serial.println(hungrigeKatze->getKatzenname()); // Hier Überprüfung einfügen, ob das Tier Futter haben soll unsigned long minMillisFuetterungOk; if (hungrigeKatze->getLetzteFuetterung() == 0) { minMillisFuetterungOk = 0; } else { minMillisFuetterungOk = hungrigeKatze->getLetzteFuetterung() + ((unsigned long)hungrigeKatze->getHaeufigkeit() * (unsigned long)60 * (unsigned long)60 * (unsigned long)1000); } if (((hungrigeKatze->getLetzteFuetterung() <= minMillisFuetterungOk) && (minMillisFuetterungOk < millis())) || ((minMillisFuetterungOk < millis()) && (millis() < hungrigeKatze->getLetzteFuetterung())) || ((millis() < hungrigeKatze->getLetzteFuetterung()) && (hungrigeKatze->getLetzteFuetterung() < minMillisFuetterungOk))) { Serial.println("Katze hungrig"); if (abfrageFuellstandFutternapf() == false) { //Wert der Futtermenge übergeben futterausgabe(hungrigeKatze->getMenge()); hungrigeKatze->setLetzteFuetterung(millis()); Serial.println("Fütterung"); } } else { Serial.println("Katze satt"); } }
Ist die minimale Wartezeit zwischen den Futterausgaben überschritten und ist der Futternapf nicht voll, so erfolgt die Futterausgabe. Dazu wird der Motor um 90° gedreht. Abhängig von der auszugebenden Futtermenge verweilt er eine bestimmte Zeit in dieser Position. Dann dreht er in die Ausgangsposition zurück. Der entsprechende Programmcode ist Servo Write entnommen.
void futterausgabe(int Menge) { motor.write(90); int delaytime = Menge*200 ; delay(delaytime); // Delay ist abhängig von gewünschter Futtermenge motor.write(0); delay(100); }
Bildschirmprogramm
- Programmablaufplan
Der Bildschirm soll zusätzlich zu den beiden LEDs den Füllstand anzeigen. Mit den Buttons Move, Confirm und Back wird durch die einzelnen Menüs navigiert. In der ersten Ebene befinden sich die Füllstandsanzeige und die verschiedenen Katzen. Die Katzen können mit Confirm ausgewählt werden. Daraufhin öffnet sich ein Untermenü, in dem zwischen den Optionen Häufigkeit und Menge unterschieden wird. Wählt der Benutzer eine der beiden Optionen aus, dann kann die Variable mit dem Move-Button verändert werden. Mit dem Back-Button kann zu den Obermenüs zurücknavigiert werden.
- Setup
Für den Aufbau der Codestruktur wurde der Code von EduArduino EduArduino Bildschirmcode als Grundstruktur verwendet und entsprechend unserer Anforderungen angepasst.
Für die Menüsauswahl werden die Integer-Variabeln Number_Menu für die Seitenauswahl und Number_title für die Auswahl des Seitentitels kreiert. Das unten dargestellte Character-Array übergibt die Namen für die Seitentitel, die auf dem Bildschirm angezeigt werden. So muss bspw. bei einer Anpassung der Katzenanzeigenamen nur das Array verändert und in den einzelnen Funktionen keine lcd.prints angepasst werden.
char* title_Menu[] = {"Futterstand", "Katze Mimi", "Katze Miezie", "Katze Simba", "1.1 - Menge", "1.2 - Haeufigkeit", "2.1 - Menge", "2.2 - Haeufigkeit", "3.1 - Menge", "3.2 - Haeufigkeit" };
In der Loop werden die Funktionen für die Tastenaktionen auf den einzelnen Menüseiten abgefragt. Dieser Loop befindet sich im Reiter „Futterautomat“ und im „RFID“. Würde der Loop nicht zusätzlich in „RFID“ liegen, dann kann der Bildschirm nicht verwendet werden, sobald der Futterbehälter gefüllt ist. Der Grund dafür ist, dass sich der Futterautomat so lange im Loop RFID befindet, bis sich eine Katze nähert.
void loop() { Page_Start(); Page_1(); Page_1_1(); Page_1_2(); Page_2(); Page_2_1(); Page_2_2(); Page_3(); Page_3_1(); Page_3_2(); … }
Die Funktion Page_Start bildet das Obermenü. Wenn der Move-Button nicht gedrückt wird, wird automatisch der Startbildschirm angezeigt. Welche Futteranzeige auf dem Bildschirm ausgegeben wird, hängt davon ab, ob die der Futterbehälter voll ist oder nicht.
void Page_Start() { if (Number_Menu == 0) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(title_Menu[0]);
if (statusFuellstandFutterbehaelter == HIGH) { lcd.setCursor(1, 1); lcd.print("Futter ok"); } else if (statusFuellstandFutterbehaelter == LOW) { lcd.setCursor(1, 1); lcd.print("Futter leer"); }
Wenn der Move-Button betätigt wird, dann wird die Zahl des Titels hochgezählt. Und entsprechend ein Cursor vor den Menüüberschriften gesetzt. So kann der Benutzer zwischen Futterzustandsanzeige, Katze 1, Katze 2 und Katze 3 wechseln.
if (digitalRead(PinDigitalMove) == HIGH) { Number_title = Number_title + 1; delay(100); } //Bedingung für das Schreiben der Seitennamen auf die LCD-Anzeige: if (Number_title > 0 & Number_title < 3) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(title_Menu[1]); lcd.setCursor(1, 1); lcd.print(title_Menu[2]); } else if (Number_title > 2 & Number_title < 4) { lcd.clear(); lcd.setCursor(1, 0); lcd.print(title_Menu[3]); } //Bedingung für die Auswahl von Seite 1 und 3: if (Number_title == 1 || Number_title == 3) { lcd.setCursor(0, 0); lcd.print(">"); } //Bedingung für die Auswahl von Seite 2 und 4: else if (Number_title == 2 || Number_title == 4) { lcd.setCursor(0, 1); lcd.print(">"); } //Bedingung für die Tastenaktion auf der Seite: if (digitalRead(PinDigitalMove) == HIGH) { //Bedingung für die Auswahl der Seite: if (Number_title >= 1) { // Ändert den Wert für die Auswahl des Menütitels. Number_title = Number_title + 1; } //Bedingung für die Auswahl der Seite: if (Number_title > 4) { //stand vorher auf 4 Number_title = 0; //stand vorher auf 4 } }
Wenn der Back-Button betätigt wird, wird die Zahl des Titels reduziert und man landet im entsprechenden Obermenü bzw. man springt zur Startseite.
//Bedingung für die Tastenaktion auf der Seite: if (digitalRead(PinDigitalBack) == HIGH) { //Bedingung für die Auswahl der Seite: if (Number_title < 1) { Number_title = 1; } //Bedingung für die Auswahl der Seite: if (Number_title <= 4) { Number_title = Number_title - 1; } }
Mit dem Confirm-Button kann das nächste Untermenü geöffnet werden, wenn eine Katze mit dem Cursor ausgewählt wird.
//Bedingung für die Tastenaktion auf der Seite: if (digitalRead(PinDigitalConfirm) == HIGH) { if (Number_title == 1) { Number_Menu = 1; } else if (Number_title == 2) { Number_title = 5; Number_Menu = 2; } else if (Number_title == 3) { Number_title = 7; Number_Menu = 3; } // else if (Number_title == 4) { //weil wir keine 4. Katze haben // Number_Menu = 4; // } } } }
Die anderen Seiten sind genauso aufgebaut, jedoch werden in
Page_1_1(); Page_1_2();
Page_2_1(); Page_2_2();
Page_3_1(); Page_3_2();
die Menge und Häufigkeit der Fütterung für jede einzelne Katze eingestellt. Sie bilden somit die untersten Seiten der Menüstruktur.
In der ersten Zeile wird der Titel auf dem Bildschirm angezigt, damit kann dem Anwender übersichtlicht dargestellt werden, dass er sich auf der richtigen Menüseite befindet. In der nächsten Zeile wird aus der Klasse die eingestellte Menge abgerufen und auf dem Bildschirm angezeigt.
void Page_1_1() { if (Number_Menu == 5) { lcd.clear(); lcd.setCursor(0, 0); lcd.print(title_Menu[4]); lcd.print(":"); lcd.setCursor(1, 1); lcd.print(katzenListe[0].getMenge());
Danach folgt wie in den Obermenüs die Defintion der Tastenaktion auf dieser Seite.
//Bedingung für die Tastenaktion auf der Seite: if (digitalRead(PinDigitalBack) == HIGH) { Number_Menu = 1; } //Bedingung für die Tastenaktion auf der Seite: if (digitalRead(PinDigitalConfirm) == HIGH) { // Führt keine Aktion aus. }
Jedoch wird an dieser Stelle durch den Move-Button die Menge der ausgewählten Katze geändert. Der Wert kann zwischen eins und fünf eingestellt werden. Der veränderte Wert wird automatisch abgespeichert. Eine Bestätigung durch den Confim-Button ist nicht notwendig.
//Bedingung für die Tastenaktion auf der Seite: if (digitalRead(PinDigitalMove) == HIGH) { if (katzenListe[0].getMenge() == 5) { katzenListe[0].setMenge(1); } //Bedingung für die Auswahl der Seite: else { katzenListe[0].setMenge(katzenListe[0].getMenge() + 1); } } } }
Die Häufigkeitseinstellung der Katzen funktioniert gleichermaßen. Jedoch werden die Auswahlmöglichkeiten mit verschiedenen If-Bedingungen auf die Werte auf 1, 2, 6, 12 und 24 eingegrenzt. Somit kann die Katze alle 1, 2, 6, 12 oder 24 Stunden Futter bekommen.
if (digitalRead(PinDigitalMove) == HIGH) { if (katzenListe[0].getHaeufigkeit() == 24) { katzenListe[0].setHaeufigkeit(1); } else if (katzenListe[0].getHaeufigkeit() == 12) { katzenListe[0].setHaeufigkeit(24); } else if (katzenListe[0].getHaeufigkeit() == 6) { katzenListe[0].setHaeufigkeit(12); } else if (katzenListe[0].getHaeufigkeit() == 2) { katzenListe[0].setHaeufigkeit(6); } else { katzenListe[0].setHaeufigkeit(katzenListe[0].getHaeufigkeit() + 1); } } } }
Komponententest
Nr. | Komponente | Erwartete Funktion | Ergebnis |
---|---|---|---|
1 | IR-Sensoren | Die IR-Sensoren sollen zur Füllstandserkennung verwendet werden. Demnach wird eine deutliche Änderung des analogen Eingangssignals erwartet, wenn sich der Füllstand auf Höhe des jeweiligen Sensors ändert. | Funktion vorhanden. Deutliche Erhöhung des ADC-Wertes von deutlich unter 100 (wenn Futter direkt vor dem Sensor) auf ein Vielfaches von 100 (wenn kein Futter vor dem Sensor). |
2 | RFID Reader | Der RFID Reader soll zur Erkennung und Unterscheidung der Tiere dienen. Bei ausreichender Nähe soll der RFID Chip durch den Reader erkannt und ausgelesen werden. | Funktion vorhanden. Berührungslose Erkennung des Tiers möglich. |
3 | Motor | Der Motor soll zum Öffen/Schließen der Öffnung zur Futterausgabe dienen. Er soll sich um einen vorgegebenen Winkel drehen. | Funktion vorhanden. |
4 | Betrieb des Automaten (Zusammenspiel von Aktoren & Sensoren) | Die erwartete Funktion ist dem Programmablaufplan zu entnehmen. | Funktion vorhanden. |
5 | Taster und LCD-Display | Der Display soll den Füllstand sowie die gespeicherten Katzen mit ihren Futtermengen und Fütterhäufigkeiten anzeigen. Die Menge und Häufigkeit soll vom Benutzer über die Taster angepasst werden können. | Funktion vorhanden.
Teilweise werden sinnlose Zeichen nach dem Hochladen angezeigt. Durch Rausziehen des Arduinos und wieder einstecken kann das Problem gelöst werden. |
Ergebnis
Zusammenfassung
Lessons Learned
Projektunterlagen
Projektplan
Projektdurchführung
YouTube Video
Weblinks
Literatur
→ zurück zur Übersicht: WS 20/21: Angewandte Elektrotechnik (BSE)