Weighturtemp: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
 
(15 dazwischenliegende Versionen von einem anderen Benutzer werden nicht angezeigt)
Zeile 26: Zeile 26:


Dabei bietet die Anlage durch kontinuierliche Prozessüberwachung (Ausgabe von '''temp'''orären Daten) und einfacher Bedienung dem Anwender einen besonderen Komfort. So können aktuelle Werte zu der gemischten Masse, der aktuell auftretenden Trübung, sowie zu den Füllständen der beiden Behälter abgefragt werden.
Dabei bietet die Anlage durch kontinuierliche Prozessüberwachung (Ausgabe von '''temp'''orären Daten) und einfacher Bedienung dem Anwender einen besonderen Komfort. So können aktuelle Werte zu der gemischten Masse, der aktuell auftretenden Trübung, sowie zu den Füllständen der beiden Behälter abgefragt werden.
<br><br>
Anwendung finden Anlagen dieser Art z.B. in der Bierherstellung, bei der naturtrübes Bier zu kristallklarem Bier hinzugemischt wird, bis der gewünschte Trübungsgrad erreicht ist. So kann eine dauerhaft gleichmäßige Qualität
gewährleistet werden. Weiterhin ist dieses Verfahren in der gesamte Getränkebranche vertreten, aber auch in der Aufbereitung von Abwässern wird dieses Verfahren angewendet.
<br>
<br>
<br>
<br>
Zeile 66: Zeile 69:
   Bild:Füllstandsmessung mit Ultraschall.jpg|Füllstandsmessung mit Ultraschall
   Bild:Füllstandsmessung mit Ultraschall.jpg|Füllstandsmessung mit Ultraschall
   Bild:Wäägezelle.jpg|Wäägezelle
   Bild:Wäägezelle.jpg|Wäägezelle
   Bild:Bedienpanel.jpg|Bedienpanel
   Bild:Bedienpanel_mit_Beschriftung.jpg|Bedienpanel mit Beschriftung
   Bild:Innere des Schaltschranks.jpg|Schaltschrank innen
   Bild:Innere des Schaltschranks.jpg|Schaltschrank innen
    
    
Zeile 128: Zeile 131:


==== Schaltschrank ====
==== Schaltschrank ====
Der Schaltschrank wurde ebenfalls vor der Montage angepasst. In den Deckel wurden verschiedene Bohrungen für die Status LEDs und die Drucktaster gebohrt. Eine rechteckige Aussparung für das LCD-Display wurde ausgesägt. Die Taster und LEDs wurden in dem Schaltschrankdeckel verklebt und verdrahtet. Innerhalb des Schaltschrankes wurden Elemente von einer Hutschiene mit Reihenklemmleisten verschraubt. Dies ermöglichte eine übersichtliche Platzierung der einzelnen elektrischen Komponenten, wie dem Arduino Mega 2560 und den Relais, sowie eine ordentliche Verdrahtung über die Klemmleiste. Über Schrauben und Hammermuttern wurde der Schaltschrank direkt am Gestell montiert.  
Der Schaltschrank wurde ebenfalls vor der Montage angepasst. In den Deckel wurden verschiedene Bohrungen für die Status LEDs und die Drucktaster gebohrt. Eine rechteckige Aussparung für das LCD-Display wurde ausgesägt. Die Taster und LEDs wurden in dem Schaltschrankdeckel verklebt und verdrahtet. Innerhalb des Schaltschrankes wurden Elemente von einer Hutschiene mit Reihenklemmleisten verschraubt. Dies ermöglichte eine übersichtliche Platzierung der einzelnen elektrischen Komponenten, wie dem Arduino Mega 2560 und den Relais, sowie eine ordentliche Verdrahtung über die Klemmleiste. Ein (unten beigefügter) Klemmenplan vereinfachte die Übersichtlichkeit und Nachverfolgung der Leitungen, z.B. bei der Fehlersuche. Über Schrauben und Hammermuttern wurde der Schaltschrank direkt am Gestell montiert.


==== Verdrahtung ====
==== Verdrahtung ====
Nachdem alle Komponenten auf dem Gestell montiert worden sind, wurden diese verdrahtet und im Schaltschrank zusammengeführt. Der Motor und die beiden Ventile wurden über einfache Steckkontakte verbunden. Die Kontakte der Ultraschallsensoren wurden an vieradrige Mantelleitungen gelötet und von unten in den Schaltschrank eingeführt. Alle Anschlussleitungen die von außerhalb kommen, wurden auf die Unterseite der Klemmleiste gelegt. Von den oberen Kontakten der Klemmleiste wurden der Arduino Mega 2560, sowie die Relais und die Komponenten auf dem Schaltschrankdeckel untereinander verdrahtet.
Nachdem alle Komponenten auf dem Gestell montiert worden sind, wurden diese verdrahtet und im Schaltschrank zusammengeführt. Der Motor und die beiden Ventile wurden über einfache Steckkontakte verbunden. Die Kontakte der Ultraschallsensoren wurden an vieradrige Mantelleitungen gelötet und von unten in den Schaltschrank eingeführt. Alle Anschlussleitungen die von außerhalb kommen, wurden auf die Unterseite der Klemmleiste gelegt. Von den oberen Kontakten der Klemmleiste wurden der Arduino Mega 2560, sowie die Relais und die Komponenten auf dem Schaltschrankdeckel untereinander verdrahtet. Der Arduino Mega wird mit einem 9V DC-Netzteil versorgt. Dabei stehen an den Steckplätzen des Arduinos 5V für die meisten messtechnischen und visualisierten Anforderungen zur Verfügung. Die Ventile benötigen allerdings für deren Ansteuerung eine Gleichspannung von 12V. Um nicht ein weiteres externes Netzteil zu benötigen, ist ein 12V-Akkupack entworfen worden, welches die geringe Leistung der zwei Ventile liefern kann.


<gallery widths="200" heights="200">   
<gallery widths="200" heights="200">   
Zeile 177: Zeile 180:
ließen sich einfacher auslesen und in dem Programm implementieren als gedacht. Allerdings konnten die Sensorwerte erst nicht korrekt auf dem LCD-Display dargestellt werden. Gelöst wurde dies durch eine Umwandlung in ein char-array.  
ließen sich einfacher auslesen und in dem Programm implementieren als gedacht. Allerdings konnten die Sensorwerte erst nicht korrekt auf dem LCD-Display dargestellt werden. Gelöst wurde dies durch eine Umwandlung in ein char-array.  


Als Verbesserung wären größere Schläuche zur schnelleren Regelung und für größere Durchsatzmengen angebracht. Desweiteren wären Pumpen anstatt zwei Ventile zu empfehlen.
Als Verbesserung wären größere Schläuche zur schnelleren Regelung und für größere Durchsatzmengen angebracht. Desweiteren wären Pumpen anstatt zwei Ventile zu empfehlen. Aber dieses Projekt soll ja eher eine modellhafte
Betrachtung sein, im Vergleich zu ausgereiften Industieanlagen.
<br>
<br>


Zeile 987: Zeile 991:
}
}
</pre>
</pre>
 
</div>
<br><br><br><br><br><br><br><br><br><br><br>


== YouTube Video ==
== YouTube Video ==


- folgt noch -
Hier geht es zu unserem [https://www.youtube.com/watch?v=BDIVNam_XbA&ab_channel=NHBE4 Youtube-Video (bitte anklicken)].


== Weblinks ==
== Weblinks ==
Zeile 1.009: Zeile 1.012:
<!-- Fügen Sie diesen Footer hinzu.  -->
<!-- Fügen Sie diesen Footer hinzu.  -->
----
----
→ zurück zur Übersicht: [[:Kategorie:ProjekteET_MTR_BSE_WS2018|WS 20/21: Fachpraktikum Elektrotechnik (MTR)]]
→ zurück zur Übersicht: [[:Kategorie:ProjekteET_MTR_BSE_WS2020|WS 20/21: Fachpraktikum Elektrotechnik (MTR)]]

Aktuelle Version vom 13. März 2021, 16:06 Uhr


Werbeplakat des Weighturtemp[1]
fertiges Projekt

Autoren: Stefan Großecoßmann, Nils Hartmann
Betreuer: Prof. Göbel


→ zurück zur Übersicht: WS 20/21: Fachpraktikum Elektrotechnik (MTR)


Einleitung

Dieses Projekt ist im Rahmen des GET-Fachpraktikums im 5. Semester im Mechatronik-Studiengang entstanden. Hier sollen die Grundlagen und Kenntnisse aus der Mess- und Regelungstechnik-Vorlesung erprobt und vertieft werden. Zudem wird Wert auf eigene Planung und Projektmanagement, sowie der Durchführung in Eigeninitiative gelegt. Von der Planung bis zum fertigen Ergebnis wird so ein kompletter Entwicklungsprozess einer Anlage durchlaufen. Bei folgendem Projekt wird besonders das Zusammenspiel aus Mechanik, elektrotechnischer Komponenten und dem ausführenden Programm deutlich.

Das Projekt wurde am 11.10.2020 bewertet und genehmigt. Ausstellung und Präsentation erfolgt am 21. Januar 2021 in einer Online-Projektmesse.

Weightturtemp ist eine mechatronische Anlage, die zur universellen Mischung von Flüssigkeiten angewendet werden kann. Sie kann aus zwei Behältnissen nach 2 Parametern Mischungsverhältnisse realisieren:

  1. Masse (Weight)
  2. Trübung (Turbidity)

Dabei bietet die Anlage durch kontinuierliche Prozessüberwachung (Ausgabe von temporären Daten) und einfacher Bedienung dem Anwender einen besonderen Komfort. So können aktuelle Werte zu der gemischten Masse, der aktuell auftretenden Trübung, sowie zu den Füllständen der beiden Behälter abgefragt werden.

Anwendung finden Anlagen dieser Art z.B. in der Bierherstellung, bei der naturtrübes Bier zu kristallklarem Bier hinzugemischt wird, bis der gewünschte Trübungsgrad erreicht ist. So kann eine dauerhaft gleichmäßige Qualität gewährleistet werden. Weiterhin ist dieses Verfahren in der gesamte Getränkebranche vertreten, aber auch in der Aufbereitung von Abwässern wird dieses Verfahren angewendet.

Anforderungen

Die Anlage soll folgende Funktionalitäten aufweisen:

  1. Mischung von 2 Flüssigkeiten in Mengen von einigen hundert bis über 1000ml
  2. Mischungskriterien sind Masse und Trübung
  3. Erfassen der Füllstände
  4. Erfassen der Trübung des Gemisches
  5. Erfassen der Masse des Gemisches
  6. Kommunikation mit dem Benutzer durch Taster/Stellglieder und optische Signale
  7. Menüstruktur mit LCD-Display zu leichten Steuerung
  8. Schutz des Anwenders vor Verletzungen


Funktionaler Systementwurf/Technischer Systementwurf

Nach der ersten Ideenfindung wurden alle Anforderungen und zentralen Bauteile in einem Blockplan zusammengefasst. Danach wurde mithilfe eines online-Diagrammeditors ein Fließschema erstellt. Dort sind die wesentlichen Komponenten und die Fließrichtung des Mediums eingezeichnet.


Galerie des fertigen Projekts

Komponentenspezifikation

Mechanische Komponenten

  • Gerüst: Aluminium-Profile 30x30 (ca. 2,10m)
  • T-Nutensteine M4 (ca. 60 Stk.)
  • M4x12 Schrauben (ca. 60 Stk.)
  • Winkel aus PVC (26 Stk.)
  • Kabelkanäle aus Edelstahl
  • Aluminiumbehälter 1x groß, 2x klein
  • Schlauchtüllen aus Edelstahl G1/4" (4x)
  • Kugelhahn G1/2"
  • Dichtungen (versch. Größen)
  • Anlagenfüße aus PVC (4x)
  • Kunststoffschlauch (6mm-Innendurchmesser)
  • Rührstab vom Mixer
  • eigene Konstruktion zum Befestigen der Kabelkanäle
  • eigene Konstruktion zum Befestigen des Motors


Elektrische Komponenten

  • Arduino Mega 2560
  • Reihenklemmleiste mit Hutschiene (31 Klemmen)
  • Schaltschrank
  • Relaismodul (8 Relais)
  • 12V-Akkupack
  • 9V-Netzteil für Arduino
  • 5V-Motor
  • 12V Ventile 6mm (2x)
  • Aderleitungen 0,75mm²
  • 4-adrige PVC-Mantelleitung 1,5mm² (ca. 1,5m)
  • 2-adrige PVC-Mantelleitung 0,75mm² (1,5m)
  • Aderendhülsen 0,75mm²/1,5mm², Kabelschuhe, Schrumpfschlauch
  • KEYESTUDIO Trübungssensor
  • Funduino Waage bis 10kg
  • Funduino Ultraschallsensoren (2x)
  • Taster (2 Öffner, 3 Schließer)
  • Potentiometer
  • LCD-Display mit I²C-Anschlussmöglichkeit
  • verschieden farbige LEDs

Einige der verwendeten Bauteile können mit den unter "Weblinks" angegebenen Webseiten käuflich erworben werden. Das Arduino-Basisset stammt von Funduino.

Umsetzung (HW/SW)

Umsetzung der Hardware

Nachdem der Funktionsumfang des Systems eingegrenzt und eine Aufbauskizze angefertigt wurde, begann die hardwareseitige Umsetzung des Aufbaus.

Grundgestell

Als Material für das Grundgestell wurden passend abgelängte Aluminiumsystemprofile 30mm x 30mm Nut 8 gewählt. Die Aluminiumsystemprofile bot gegenüber Schweißkonstruktionen den Vorteil, dass diese keine permanente Verbindung darstellen und je nach Bedarf wieder gelöst und neu montiert werden können. Die Befestigung untereinander geschah dabei über Kunststoffwinkel, welche mit Hilfe von M4-Schrauben und M4-Hammermuttern, einzelne Profilelemente verbinden. Um in einer späteren Phase des Aufbaus die Anschlussleitungen für die elektrischen Komponenten zu befestigen, sind Edelstahlgitterkanäle auf den Profilen montiert worden.

Behälter mit Anschlüssen

Um die Flüssigkeiten in dem System zu lagern, wurden Aluminiumgussbehählter benutzt. Damit die Behälter untereinander verbunden und mit Sensoren ausgestattet werden konnten, wurden verschiedene Bohrungen angefertigt. In die beiden oberen Behälter wurden jeweils Bohrungen für die Ultraschallsensoren und Schlauchtüllen und in den unteren Behälter Bohrungen für den Kugelhahn, die Schlauchtüllen, den Mixerstab und den Trübungssensor gebohrt. In die angefertigten Bohrungen wurden die Bauteile eingesetzt. Um Dichtheit der Behälter zu gewährleiten, wurden Dichtringe unter den Schlauchtüllen und dem Kugelhahn verwendet. Der Trübungssensor wurde dicht eingeklebt.

Rühreinrichtung und Verschlauchung

Nachdem die Behälter montiert waren, wurde eine Halterung für eine Rühreinrichtung aus Blech gefertigt. Durch mehrfaches Biegen und Bohren entstand eine Vorrichtung, in der der Motor untergebracht war und der Rührstab in seinem Lauf fixiert wurde. Der Rührstab wurde mit dem DC-Motor über eine flexible Kupplung, die einen Axial- und Winkelversatz ausgleichen konnte, verbunden. Zudem konnten die Ventile mit den Behältern verschlaucht werden.

Schaltschrank

Der Schaltschrank wurde ebenfalls vor der Montage angepasst. In den Deckel wurden verschiedene Bohrungen für die Status LEDs und die Drucktaster gebohrt. Eine rechteckige Aussparung für das LCD-Display wurde ausgesägt. Die Taster und LEDs wurden in dem Schaltschrankdeckel verklebt und verdrahtet. Innerhalb des Schaltschrankes wurden Elemente von einer Hutschiene mit Reihenklemmleisten verschraubt. Dies ermöglichte eine übersichtliche Platzierung der einzelnen elektrischen Komponenten, wie dem Arduino Mega 2560 und den Relais, sowie eine ordentliche Verdrahtung über die Klemmleiste. Ein (unten beigefügter) Klemmenplan vereinfachte die Übersichtlichkeit und Nachverfolgung der Leitungen, z.B. bei der Fehlersuche. Über Schrauben und Hammermuttern wurde der Schaltschrank direkt am Gestell montiert.

Verdrahtung

Nachdem alle Komponenten auf dem Gestell montiert worden sind, wurden diese verdrahtet und im Schaltschrank zusammengeführt. Der Motor und die beiden Ventile wurden über einfache Steckkontakte verbunden. Die Kontakte der Ultraschallsensoren wurden an vieradrige Mantelleitungen gelötet und von unten in den Schaltschrank eingeführt. Alle Anschlussleitungen die von außerhalb kommen, wurden auf die Unterseite der Klemmleiste gelegt. Von den oberen Kontakten der Klemmleiste wurden der Arduino Mega 2560, sowie die Relais und die Komponenten auf dem Schaltschrankdeckel untereinander verdrahtet. Der Arduino Mega wird mit einem 9V DC-Netzteil versorgt. Dabei stehen an den Steckplätzen des Arduinos 5V für die meisten messtechnischen und visualisierten Anforderungen zur Verfügung. Die Ventile benötigen allerdings für deren Ansteuerung eine Gleichspannung von 12V. Um nicht ein weiteres externes Netzteil zu benötigen, ist ein 12V-Akkupack entworfen worden, welches die geringe Leistung der zwei Ventile liefern kann.

Umsetzung der Software

Die gesamte Programmierung der Software wurde in der Arduino IDE vorgenommen. Zum Beginn der softwareseitigen Umsetzung der Systemsteuerung wurden die einzelnen Komponenten mit einfachen Programmen einzeln ausgetestet. Dadurch wurde es ermöglicht, das Verhalten der einzelnen Komponenten, wie Waage, Trübungssensor etc., zu verstehen. In diesem Schritt fand der serielle Monitor der Arduino IDE eine umfassende Anwendung. In ihm können in Echtzeit Werte von beliebige Variablen angezeigt werden. Dies half vor allem in der Suche von Fehlern innerhalb des Quellcodes. Nachdem die einzelnen Programme für die Komponenten ausgetestet und optimiert wurden, wurden diese schrittweise in ein Gesamtprogramm zusammengefügt. Für eine verbesserte Übersichtlichkeit der Programmbauteile wurden häufig wiederkehrende Programmabschnitte in einzelne Funktionen ausgelagert.

Die verschiedenen Funktionalitäten des Systems wurden in einem Menü, welches mehrere Submenüs besitzt, eingebunden. Als Funktionen stehen dort eine automatische und manuelle Mischung, sowie eine Übersicht über die Prozessparameter, wie aktuelle Trübung, Gewicht und Füllstände, zur Verfügung.

Funktionsweise

Alle Funktionen die das System besitzt können durch ein Menü, welches auf dem LCD-Display dargestellt ist, genutzt werden. Mittels der Up- und Down-Buttons kann durch die einzelnen Menüeinträge navigiert werden. Durch Betätigung des Select-Buttons können einzelne Submenüeinträge ausgewählt werden. Der Return-Button ermöglicht es aus einem Submenü in das Hauptmenü zu gelangen. Die Drehgeschwindigkeit des Motors kann über ein Potentiometer am Schaltschrank verändert werden.

Das Hauptmenü weist vier Einträge auf. Dies sind der automatische Betrieb, der manuelle Betrieb, eine Übersicht über aktuelle Prozessdaten und ein Impressum.

Innerhalb des automatischen Betriebes kann ein Trübungsverhältnis zwischen 25% und 90% eingestellt werden. Durch Betätigung des Start-Buttons wird der Mischprozess gestartet. Während des automatischen Betriebes misst der Trübungssensor kontinuierlich die Trübung des Gemisches. Basierend auf der aktuellen Trübung werden die Ventile angesteuert und der Rührmotor betätigt. Dies geschieht solange bis das gewünschte Trübungsverhältnis erreicht wurde oder die Flüssigkeitsstände kritische Stände erreichen.

Der Hauptmenüpunkt manueller Betrieb beinhaltet die einzelne Ansteuerung der beiden Ventile und des Motors. Über den Up- und Down-Button können die Ventile durchgeschaltet werden und durch Betätigung des Start-Buttons beginnt der Motor für fünf Sekunden zu drehen.

Im Menüpunkt Prozessdaten werden die aktuellen Prozessdaten Trübung in Prozent, Gewicht des Gemisches in Gramm und die beiden Füllstände der oberen Behälter in Zentimeter aufgelistet.

Im Impressum sind Informationen über die Personen, die am Projekt beteiligt waren, aufgeführt.

Neben der Menüdarstellung auf dem LCD-Display sind verschiedene Status-LEDs auf dem Schaltschrankdeckel angebracht.

  • grüne LED zeigt an, dass das System betriebsbereit ist
  • zwei blaue LEDs zeigen den aktuellen Betriebszustand der Ventile an
  • weiße LED zeigt Betriebszustand des Motors an
  • drei rote LEDs geben Warnungen über das Gewicht und die beiden Füllstände bekannt


Ergebnis

Das Projekt wurde erfolgreich beendet. Die oben genannten Anforderungen wurden gänzlich erfüllt. Zwei Flüssigkeiten werden automatisch gemischt, sodass sich ein Gemisch mit der gewünschten Trübung ergibt. Der Genauigkeitsgrad liegt bei +/- 1,5%. Auch die Steuerung mit den Tastern und dem LCD-Panel funktionierte zum Schluss reibungslos. Bei der Programmierung sind wir zwar immer wieder auf Hindernisse gestoßen, die uns zu neuen Überlegungen und Recherchen angeregt haben, jedoch konnten wir die Probleme selbständig lösen. So haben wir unser Projekt kontinuierlich verbessert.
Eine große Herausforderung war die Material- und Werkzeugbeschaffung für die Hardware. Aufgrund des Lockdowns waren alle Baumärkte mit Material und Werkzeug geschlossen. Somit wurde das Material aus online-shops beschafft und das Werkzeug für z.B. größere Bohrungen wurde ausgeliehen. Desweiteren haben sich bei der Programmierung immer wieder Probleme aufgetan. So gestaltete sich die Menüstruktur mit mehreren Untermenüs als herausfordernd. Aber nach etwas Recherche und einigen Testläufen funktionierte auch dies. Ganz im Gegenteil verhielt sich dagegen das Auslesen der Sensoren. Sowohl der Trübungs- als auch die Masse- und Ultraschallsensoren ließen sich einfacher auslesen und in dem Programm implementieren als gedacht. Allerdings konnten die Sensorwerte erst nicht korrekt auf dem LCD-Display dargestellt werden. Gelöst wurde dies durch eine Umwandlung in ein char-array.

Als Verbesserung wären größere Schläuche zur schnelleren Regelung und für größere Durchsatzmengen angebracht. Desweiteren wären Pumpen anstatt zwei Ventile zu empfehlen. Aber dieses Projekt soll ja eher eine modellhafte Betrachtung sein, im Vergleich zu ausgereiften Industieanlagen.

Zusammenfassung

Lessons Learned

Ziel des GET-Fachpraktikums war es ein mechatronisches System zu realisieren. Dabei wurden alle Schritte von der Projektfindung, über die praktische Umsetzung, bis hin zur abschließenden Dokumentation durchlaufen. Die Projektdurchführung zeigte nicht nur die offensichtliche Bedeutung von Hardskills, wie die Programmierung von Mikrocontrollern oder mechanische Bearbeitung von Bauteilen, sondern auch die Wichtigkeit von Softskills, wie dem projektorientierten Arbeiten und, bedingt durch die Corona-Pandemie, die Nutzung von alternativen Arbeitsmethoden und Kommunikationswegen. Während des Bearbeitungszeitraum wurden bereits vorhandene Kenntnisse der Mess- und Regelungstechnik, Elektrotechnik, Informatik und Mechanik vertieft und in einigen Bereichen neues Wissen erlangt. Das Projekt und dessen Durchführung zeigte die praktische Seite von verschiedenen Inhalten, die in den Lehrveranstaltungen vermittelt wurden.

Projektunterlagen

Projektplan

Projektplan - Zeitleiste



























Projektdurchführung

Programmcode

/*GET-Fachpraktikum WiSe 2020/21 5. Semester
Autoren: N. Hartmann, S. Großecoßmann
Projekt: Weighturtemp
Betreuer: Prof. Göbel
*/


// include ----------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <HX711_ADC.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <math.h> 
#include <NewPing.h>

#define ATRIG_PIN 7
#define AECHO_PIN 6
#define BTRIG_PIN 52
#define BECHO_PIN 50
#define MAX_DIST 30
NewPing sonar1(ATRIG_PIN, AECHO_PIN, MAX_DIST);
NewPing sonar2(BTRIG_PIN, BECHO_PIN, MAX_DIST);


//pins festlegen: 
int upButton = 12;
int downButton = 11;
int selectButton = 10;
int returnButton = 9;
int startButton = 8;

int relaisin6 = 22;
int relaisin7 = 2;
int relaisin8 = 3;

// led_betrieb =  betriebsbereit (grün)
// led_motor =    Motor an (weiß)
// led_V1 =       Ventil 1 an (blau)
// led_V2 =       Ventil 2 an (blau)
// led_F1 =       Fehler Behälter 1 Ultraschall (rot) 
// led_F2 =       Fehler Behälter 2 Ultraschall (rot)
// led_F3 =       Fehler Bottig Waage (rot)
    
int led_betrieb = 36; 
int led_motor = 38;
int led_V1 = 42;
int led_V2 = 40;
int led_F1 = 34;
int led_F2 = 32;
int led_F3 = 30;

int atrig = 7;
int aecho = 6;
int btrig = 52;
int becho = 50;

const int HX711_dout = 4;                                        //mcu > HX711 dout pin
const int HX711_sck = 5;                                         //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);


// Variablen definieren --------------------
int menu = 1;
int submenu = 1;

int submenu1 = 1;
int submenu2 = 1;
int submenu3 = 1;
int submenu4 = 1;

bool selectmain = true;
bool selectsub = false;
bool selectsubsub = false;


long t;
bool F1 = 0;
bool F2 = 0;
bool F3 = 0;
float trp = 0;

char T[5];                                                        // Anzahl = Zahlen vor dem Komma + . + Zahlen hinter dem Komma + 1
char G[7];

int test = 1;

int fuellstand1;
int fuellstand2;

//---------------------- void setup ----------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  lcd.clear();
  
  lcd.init();                                                     // bei manchen arduino-Versionen: lcd.begin()
  lcd.backlight();
  lcd.print("Welcome");
  delay(3000);

  pinMode(startButton, INPUT_PULLUP);
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(selectButton, INPUT_PULLUP);
  pinMode(returnButton, INPUT_PULLUP);
  pinMode(2, OUTPUT); // Setzt den Digitalpin 2 als Outputpin
  pinMode(3, OUTPUT); // Setzt den Digitalpin 3 als Outputpin
  pinMode(22, OUTPUT); // Setzt den Digitalpin 22 als Outputpin
  pinMode(30, OUTPUT); // Setzt den Digitalpin 30 als Outputpin
  pinMode(32, OUTPUT); // Setzt den Digitalpin 32 als Outputpin
  pinMode(34, OUTPUT); // Setzt den Digitalpin 34 als Outputpin
  pinMode(36, OUTPUT); // Setzt den Digitalpin 36 als Outputpin
  pinMode(38, OUTPUT); // Setzt den Digitalpin 38 als Outputpin
  pinMode(40, OUTPUT); // Setzt den Digitalpin 40 als Outputpin  
  pinMode(42, OUTPUT); // Setzt den Digitalpin 42 als Outputpin
  
  updateMenu();


  Serial.begin(9600); delay(10);                                  //Baudrate einstellen
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  float calibrationValue;                         
  calibrationValue = 243.65;                                      // Kalibrierwert einstellen

  long stabilizingtime = 2000;                                    // Stabilisierungszeit einstellen (nicht kleiner als 2000!)
  boolean _tare = true;                                           // Tara nach dem Start (false setzen, wenn keine Nullung beim Start erwünscht)
                  
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue);      // Kalibrierwert setzen
    Serial.println("Hochfahren beendet, System ist betriebsbereit");
  }
}


//---------------------- void loop ----------------------------------------------------------------------------------
void loop() {

Waage_u_Truebung();
Tara();
buttons();
Betriebszustand();
behaelter1();
behaelter2();
}


//---------------------- Funktionen ----------------------------------------------------------------------------------

void buttons(){
    //Runter-button
  if (!digitalRead(downButton)){
      if(selectmain == true){
      menu++;
      submenu = menu;
      updateMenu();
      delay(150);
      while (!digitalRead(downButton));
    }
    if(selectsub == true){
      if(submenu == 1){
        submenu1++;
        updateSubmenu1();
        delay(150);
        while (!digitalRead(downButton));
      }
      if(submenu == 2){
        submenu2++;
        updateSubmenu2();
        delay(150);
        while (!digitalRead(downButton));       
      }
      if(submenu == 3){
        submenu3++;
        updateSubmenu3();
        delay(150);
        while (!digitalRead(downButton));        
      }
      if(submenu == 4){
        submenu4++;
        updateSubmenu4();
        delay(150);
        while (!digitalRead(downButton));       
      }
    }
  }

  //Hoch-button
  if (!digitalRead(upButton)){
      if(selectmain == true){
      menu--;
      updateMenu();
      delay(100);
      while (!digitalRead(upButton));
    }
    if(selectsub == true){
      if(submenu == 1){
        submenu1--;
        updateSubmenu1();
        delay(100);
        while (!digitalRead(upButton));
      }
      if(submenu == 2){
        submenu2--;
        updateSubmenu2();
        delay(100);
        while (!digitalRead(upButton));       
      }
      if(submenu == 3){
        submenu3--;
        updateSubmenu3();
        delay(100);
        while (!digitalRead(upButton));        
      }
      if(submenu == 4){
        submenu4--;
        updateSubmenu4();
        delay(100);
        while (!digitalRead(upButton));       
      }
    }
  }

  //Select-button
  if (digitalRead(selectButton)){
      selectmain = false;
      selectsub = true;
      executeSubmenu();
      if(selectmain == true){
      if(submenu == 1){
        lcd.clear();
        updateSubmenu1();
      }
      if(submenu == 2){
        lcd.clear();
        updateSubmenu2();
      }
      if(submenu == 3){
        lcd.clear();
        updateSubmenu3();
      }
      if(submenu == 4){
        lcd.clear();
        updateSubmenu4();
      }
      delay(100);
      while (digitalRead(selectButton));
    }
    if(digitalRead(selectButton)){
      delay(500);
      selectsubsub = true;
      delay(200);
    }
    
  }

  //back-button
    if (digitalRead(returnButton)){
    selectmain = true;
    selectsub = false;
    submenu1 = 1;
    submenu2 = 1;
    submenu3 = 1;
    submenu4 = 1;
    updateMenu();
    delay(100);
    while (digitalRead(returnButton));
  }


  //start-button
    if (!digitalRead(startButton)){

      if(!digitalRead(startButton) && submenu == 2){
        MotorON();
        delay(5000);
        MotorOFF();
      }

      
      if(!digitalRead(startButton) && selectsubsub == true){
      delay(200);
      if(submenu == 1){
        switch(submenu1){
          case 1:
            Auto(25);
          break;
          
          case 2:
            Auto(30);
          break;
          
          case 3:
            Auto(35);
          break;
          
          case 4:
            Auto(40);
          break;

          case 5:
            Auto(45);
          break;
          
          case 6:
            Auto(50);
          break;
          
          case 7:
            Auto(55);
          break;
          
          case 8:
            Auto(60);
          break;

          case 9:
            Auto(65);
          break;
          
          case 10:
            Auto(70);
          break;
          
          case 11:
            Auto(75);
          break;
          
          case 12:
            Auto(80);
          break;
          
          case 13:
            Auto(85);
          break;
          
          case 14:
            Auto(90);
          break;
        }
      }
    }
    selectsubsub = false;
    delay(100);
    while (!digitalRead(startButton));
  }
}


void updateMenu() {
  switch (menu) {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print(">Auto Befuellung");
      lcd.setCursor(0, 1);
      lcd.print(" Manu Befuellung");
      break;
    case 2:
      lcd.clear();
      lcd.print(" Auto Befuellung");
      lcd.setCursor(0, 1);
      lcd.print(">Manu Befuellung");
      break;
    case 3:
      lcd.clear();
      lcd.print(">Prozessdaten");
      lcd.setCursor(0, 1);
      lcd.print(" Impressum");
      break;
    case 4:
      lcd.clear();
      lcd.print(" Prozessdaten");
      lcd.setCursor(0, 1);
      lcd.print(">Impressum");
      break;
    case 5:
      menu = 4;
      break;
  }
}

void updateSubmenu1(){
    switch (submenu1) {
    case 0:
      submenu1 = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print(">25%");
      lcd.setCursor(0, 1);
      lcd.print(" 30%");
      break;
    case 2:
      lcd.clear();
      lcd.print(" 25%");
      lcd.setCursor(0, 1);
      lcd.print(">30%");
      break;
    case 3:
      lcd.clear();
      lcd.print(">35%");
      lcd.setCursor(0, 1);
      lcd.print(" 40%");
      break;
    case 4:
      lcd.clear();
      lcd.print(" 35%");
      lcd.setCursor(0, 1);
      lcd.print(">40%");
      break;
    case 5:
      lcd.clear();
      lcd.print(">45%");
      lcd.setCursor(0, 1);
      lcd.print(" 50%");
      break;
    case 6:
      lcd.clear();
      lcd.print(" 45%");
      lcd.setCursor(0, 1);
      lcd.print(">50%");
      break;
    case 7:
      lcd.clear();
      lcd.print(">55%");
      lcd.setCursor(0, 1);
      lcd.print(" 60%");
      break;
    case 8:
      lcd.clear();
      lcd.print(" 55%");
      lcd.setCursor(0, 1);
      lcd.print(">60%");
      break;
    case 9:
      lcd.clear();
      lcd.print(">65%");
      lcd.setCursor(0, 1);
      lcd.print(" 70%");
      break;
    case 10:
      lcd.clear();
      lcd.print(" 65%");
      lcd.setCursor(0, 1);
      lcd.print(">70%");
      break;
    case 11:
      lcd.clear();
      lcd.print(">75%");
      lcd.setCursor(0, 1);
      lcd.print(" 80%");
      break;
    case 12:
      lcd.clear();
      lcd.print(" 75%");
      lcd.setCursor(0, 1);
      lcd.print(">80%");
      break;
    case 13:
      lcd.clear();
      lcd.print(">85%");
      lcd.setCursor(0, 1);
      lcd.print(" 90%");
      break;
    case 14:
      lcd.clear();
      lcd.print(" 85%");
      lcd.setCursor(0, 1);
      lcd.print(">90%");
      break;  
    case 15:
      submenu1 = 14;
      break;                                       
  }
}
void updateSubmenu2(){
      lcd.clear();
      lcd.print("V1'klar' -> Down");
      lcd.setCursor(0, 1);
      lcd.print("V2'trueb'->   Up");



      do{
        while(!digitalRead(upButton)){
          digitalWrite(relaisin8, HIGH);
          digitalWrite(led_V2, HIGH);
          delay(100);
        }
        while(!digitalRead(downButton)){
          digitalWrite(relaisin7, HIGH);
          digitalWrite(led_V1, HIGH);
          delay(100); 
        }
        
      
      }while(digitalRead(returnButton));

      digitalWrite(led_motor, LOW);
      digitalWrite(relaisin7, LOW);
      digitalWrite(relaisin8, LOW);
      digitalWrite(led_V1, LOW);
      digitalWrite(led_V2, LOW);
}

void updateSubmenu3(){
  switch(submenu3){
    case 0:
      submenu3 = 1;
      break;
    case 1:
      lcd.clear();
      do{
      Waage_u_Truebung();
      Betriebszustand();
      LCD_Prozessdaten1();
      } while (!digitalRead(returnButton) && digitalRead(upButton) && digitalRead(downButton));
      break;
    case 2:
      lcd.clear();
      do{
      behaelter1();
      behaelter2();
      Betriebszustand();
      LCD_Prozessdaten2();
      } while (!digitalRead(returnButton) && digitalRead(upButton) && digitalRead(downButton));
      break;
    case 3:
      submenu3 = 2;
      break;   
  }
}

void updateSubmenu4(){
  switch(submenu4){
    case 0:
      submenu4 = 0;
      break; 
    case 1:
      lcd.clear();
      lcd.print("S.Grossecossmann");
      lcd.setCursor(0, 1);
      lcd.print("N.Hartmann");
      break;
    case 2:
      submenu4 = 1;
      break;    
  }
}


void executeSubmenu() {
  switch (menu) {
    case 1:
      submenu = 1;
      updateSubmenu1();
      break;
    case 2:
      submenu = 2;
      updateSubmenu2();
      break;
    case 3:
      submenu = 3;
      updateSubmenu3();
      break;
    case 4:
      submenu = 4;
      updateSubmenu4();
      break;
  }
}


void Waage_u_Truebung() {
  static boolean newDataReady = 0;                            // true, wenn neuer Wert kommt
  const int serialPrintInterval = 1000;                       // Intervall der Ausgabe der Werte

  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) {
    if (millis() > t + serialPrintInterval) {
      float i = LoadCell.getData();                           // in i sind die aktuellen Werte gespeichert!!

      if (i > 2000){
        digitalWrite(led_F3, HIGH);
        F3=1;
      }
      if (i < 2000){
        digitalWrite(led_F3, LOW);
        F3=0;
      }
      
      if (i < 1.0){
        i = 0.001;
      }
      dtostrf(abs(i),5,1,G);
      Serial.print("Aktuelles Gewicht: ");
      Serial.println(i,1);

      float trW = analogRead (A0);                          // trW = Eingangwerte
      float trV;                                            // trV = Truebung-Spannungswert
      float tr;                                             // tr = Truebung in %
      const int serialPrintInterval = 1000;                 // Intervall der Ausgabe der Werte
  
      trV = (trW * (5.0/1024.0));
      tr = 100-((trV/5)*100);
      trp = tr;                        
      dtostrf(tr,2,1,T);

      Serial.print("Aktuelle Truebung: ");
      Serial.print(tr,2);                                   // tr, 2 = Anzahl der Nachkommastellen
      Serial.println("%");   

      
      newDataReady = 0;
      t = millis();

    }
  }
}



void Tara() {
  // -- Tara-Operation --------
  // receive command from serial terminal, send 't' to initiate tare operation:
  if (Serial.available() > 0) {
    float i;
    char inByte = Serial.read();
    if (inByte == 't') LoadCell.tareNoDelay();
  }

  // check if last tare operation is complete:
  if (LoadCell.getTareStatus() == true) {
    Serial.println("Tare complete");
  }
 }

void Auto(int prozent){
int timer=0;

while(timer <= 3){
  digitalWrite(relaisin7, HIGH);
  digitalWrite(led_V1, HIGH);
  delay(1000);
  timer++;
}
  digitalWrite(relaisin7, LOW);
  digitalWrite(led_V1, LOW);
  timer=0;

  while(trp <= prozent){
   digitalWrite(relaisin8, HIGH);
   digitalWrite(led_V2, HIGH);
   MotorON();
   delay(1500);
   digitalWrite(relaisin8, LOW);
   digitalWrite(led_V2, LOW);
   delay(3000); 
   MotorOFF();
   delay(2000);
   Waage_u_Truebung();
  }
  

}

void LCD_Prozessdaten1(){
  lcd.setCursor(0, 0);                                         //Hier wird die Position des ersten Zeichens festgelegt. In diesem Fall bedeutet (0,0) das erste Zeichen in der ersten Zeile. 
  lcd.print("Gewicht:"); 
  lcd.setCursor(10, 0);                                        // In diesem Fall bedeutet (0,1) das erste Zeichen in der zweiten Zeile. 
  lcd.print(G);
  
  lcd.setCursor(0, 1);
  lcd.print("Truebung:"); 
  lcd.setCursor(11, 1);
  lcd.print(T);
  lcd.setCursor(15, 1);
  lcd.print("%");
}

void LCD_Prozessdaten2(){
  lcd.setCursor(0, 0);
  lcd.print("F-Stand 1:"); 
  lcd.setCursor(12, 0); 
  lcd.print(behaelter1());
  lcd.setCursor(13, 0);
  lcd.print(" cm");
  
  lcd.setCursor(0, 1);
  lcd.print("F-Stand 2:"); 
  lcd.setCursor(12, 1);
  lcd.print(behaelter2());
  lcd.setCursor(13, 1);
  lcd.print(" cm");
}


void MotorON(){
  digitalWrite(led_motor, HIGH);
  digitalWrite(relaisin6, HIGH);
}

void MotorOFF(){
  digitalWrite(led_motor, LOW);
  digitalWrite(relaisin6, LOW);
}


void Betriebszustand(){
  if(F1 == false && F2 == false && F3 == false){
  digitalWrite(led_betrieb, HIGH);
}

if(F1 == true || F2 == true || F3 == true){
  digitalWrite(led_betrieb, LOW);
}
}

int behaelter1(){
  delay(50);
  fuellstand1 = sonar1.ping_cm();
  if(fuellstand1 >= 5){
    digitalWrite(led_F1, HIGH);
    F1 = 1;
  }
  if(fuellstand1 < 5){
    digitalWrite(led_F1, LOW);
    F1 = 0;
  }
  return fuellstand1;
}

int behaelter2(){
  delay(50);
  fuellstand2 = sonar2.ping_cm();
    if(fuellstand2 >= 5){
    digitalWrite(led_F2, HIGH);
    F2 = 1;
  }
  if(fuellstand2 < 5){
    digitalWrite(led_F2, LOW);    
    F2 = 0;
  }
  return fuellstand2;
}

YouTube Video

Hier geht es zu unserem Youtube-Video (bitte anklicken).

Weblinks

Literatur


→ zurück zur Übersicht: WS 20/21: Fachpraktikum Elektrotechnik (MTR)

  1. Eigenes Dokument