Weizen Eingießanlage: Unterschied zwischen den Versionen
(15 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 65: | Zeile 65: | ||
Datei:Technischer Systementwurf Weizen Eingiesanlage.png | Technischer Systementwurf | Datei:Technischer Systementwurf Weizen Eingiesanlage.png | Technischer Systementwurf | ||
Datei: RegelKreis_Weizenglas.png| Weizen Eingießanlage Regelkreis | Datei: RegelKreis_Weizenglas.png| Weizen Eingießanlage Regelkreis | ||
</gallery> | |||
'''Ansatz zur Herleitung der Übertragungsfunktion:''' | |||
<gallery widths="500" heights="500"> | |||
Datei:ÜbertragungsfunktionHerleitungAnsatz.png | Ansatz zur Herleitung der Übertragungsfunktion | |||
</gallery> | </gallery> | ||
<!-- Füllen Sie Ihre Projektskizze bis hierher aus. Fügen Sie einen Projektplan unten ein. --> | <!-- Füllen Sie Ihre Projektskizze bis hierher aus. Fügen Sie einen Projektplan unten ein. --> | ||
Zeile 84: | Zeile 90: | ||
|- | |- | ||
| 2 | | 2 | ||
| | | DM442 Motortreiber | ||
| | | | ||
* Vollschritt Einstellung | * Vollschritt Einstellung | ||
Zeile 95: | Zeile 101: | ||
* Versorgungsspannung 5V | * Versorgungsspannung 5V | ||
* Messbereich: bis zu 5Kg | * Messbereich: bis zu 5Kg | ||
* 24 Bit ADC | |||
|- | |- | ||
| 4.1 | | 4.1 | ||
Zeile 126: | Zeile 133: | ||
Die Konstruktion der Halterung ist auf den ersten Blick sehr simpel. Dennoch galt es für uns die Kosten sowie das Gewicht niedrig zu halten. Daher belaufen sich fast alle Komponenten auf Holz und Kunststoff. Für die meisten Komponenten konnten wir auf unser Betriebsinternes Lager zurückgreifen lediglich die Holzplatte und die Halterungen für Flasche und Glas waren noch nicht vorhanden. Die Halterungen für Glas und Flasche wurden durch einen 3D-Kunststoffdruck gefertigt. Zudem mussten wir uns überlegen wie wir die Flasche in der Halterung befestigen. Um auch hier eine günstige, einfache und leichte Lösung zu erreichen, setzen wir auf die Spannkraft zweier Gummis, welche die Flasche im Halter halten. | Die Konstruktion der Halterung ist auf den ersten Blick sehr simpel. Dennoch galt es für uns die Kosten sowie das Gewicht niedrig zu halten. Daher belaufen sich fast alle Komponenten auf Holz und Kunststoff. Für die meisten Komponenten konnten wir auf unser Betriebsinternes Lager zurückgreifen lediglich die Holzplatte und die Halterungen für Flasche und Glas waren noch nicht vorhanden. Die Halterungen für Glas und Flasche wurden durch einen 3D-Kunststoffdruck gefertigt. Zudem mussten wir uns überlegen wie wir die Flasche in der Halterung befestigen. Um auch hier eine günstige, einfache und leichte Lösung zu erreichen, setzen wir auf die Spannkraft zweier Gummis, welche die Flasche im Halter halten. | ||
'''Wägezelle HX711:''' | '''Wägezelle HX711:''' | ||
Messprinzip: Durch das zu messende Gewicht wird die Wägezelle leicht gebogen. An der Seite befinden sich 4 Dehnungsmesstreifen, welche als Wheatsstone Brücke angeordnet sind. Der Widerstand der Messstreifen ändert sich mit dem Dehnungsgrad. Somit ändert sich bei einer Last der Widerstand und damit auch der Spannungsabfall der Brückenschaltung. Der Spannungsabfall zwischen den Punkten A und B wird mit einem A/D Wandler ausgewertet. | |||
<gallery widths="500" heights="500"> | |||
Datei:Messschaltung HX711 DMS.png | - Messchaltungsaufbau | |||
</gallery> | |||
Da die Wägezelle über die physikalische Kraft der Gewichtskraft funktioniert, war es eine Herausforderung in unserem drehenden System die korrekten Werte für den Füllstand zu erhalten. Dies war deshalb so schwierig weil sich die Wägezelle immer in einem anderen Winkel zur Gewichtskraft des Füllstandes befindet. Aus diesem Grund mussten wir die Messwerte noch einmal mit dem cos des Winkels multiplizierten um die korrekte Gewichtskraft zu erhalten. Wir verwenden außerdem einen Look-up-Table um uns die Verarbeitung der Messdaten zu vereinfachen. Konkret subtrahieren wir unseren gemessenen wert mit dem Wert aus dem Look-up-Table an der gleichen Winkelstellung. Somit Erhalten wir die korrekte Gewichtskraft des Pegelstandes des Glases. Dies ist dann dementsprechend unser IST-Wert. | Da die Wägezelle über die physikalische Kraft der Gewichtskraft funktioniert, war es eine Herausforderung in unserem drehenden System die korrekten Werte für den Füllstand zu erhalten. Dies war deshalb so schwierig weil sich die Wägezelle immer in einem anderen Winkel zur Gewichtskraft des Füllstandes befindet. Aus diesem Grund mussten wir die Messwerte noch einmal mit dem cos des Winkels multiplizierten um die korrekte Gewichtskraft zu erhalten. Wir verwenden außerdem einen Look-up-Table um uns die Verarbeitung der Messdaten zu vereinfachen. Konkret subtrahieren wir unseren gemessenen wert mit dem Wert aus dem Look-up-Table an der gleichen Winkelstellung. Somit Erhalten wir die korrekte Gewichtskraft des Pegelstandes des Glases. Dies ist dann dementsprechend unser IST-Wert. | ||
Zeile 132: | Zeile 145: | ||
'''PI-Regler:''' | '''PI-Regler:''' | ||
Der IST-Wert wird nun mit dem SOLL-Wert von 500 (500ml/Kg) subtrahiert. Somit erhalten wir unsere Regelabweichung welche wir weiterhin mit dem PI-Regler verarbeiten. Aufgrund dessen, dass 1-Motorschritt in 0,39 Grad am äußeren Umfang der Holzplatte entspricht benötigen wir eine sehr schnelle Regulierung der Motorschritte, sobald Flüssgkeit in das Glas läuft. Daher benötigen wir eine möglichst schnelle Sprungantwort und somit einen großen P-Anteil in unserem Regler. Für unser System haben sich die Werte Kp=0, | Der IST-Wert wird nun mit dem SOLL-Wert von 500 (500ml/Kg) subtrahiert. Somit erhalten wir unsere Regelabweichung welche wir weiterhin mit dem PI-Regler verarbeiten. Aufgrund dessen, dass 1-Motorschritt in 0,39 Grad am äußeren Umfang der Holzplatte entspricht, benötigen wir eine sehr schnelle Regulierung der Motorschritte, sobald Flüssgkeit in das Glas läuft. Daher benötigen wir eine möglichst schnelle Sprungantwort und somit einen großen P-Anteil in unserem Regler. Für unser System haben sich die Werte Kp=0,014 und Ki=0,00675 als praktikabel erwiesen. Die Stellgröße des Reglers wird direkt als Ansteuerung für den Motor genutzt. | ||
'''Motoransteuerung:''' | '''Motoransteuerung:''' | ||
Zeile 149: | Zeile 162: | ||
Datei:Verdrahtungsplan Eingießanlage.png| Verdrahtungsplan Eingießanlage - [[Datei:Verdrahtungsplan Hopfomat.zip|mini]] | Datei:Verdrahtungsplan Eingießanlage.png| Verdrahtungsplan Eingießanlage - [[Datei:Verdrahtungsplan Hopfomat.zip|mini]] | ||
</gallery> | </gallery> | ||
=== Software === | === Software === | ||
Zeile 155: | Zeile 167: | ||
[[Datei:Berechnung Regelabweichung.png|mini]] | [[Datei:Berechnung Regelabweichung.png|mini]] | ||
<gallery widths="500" heights="500"> | <gallery widths="500" heights="500"> | ||
Datei: | Datei:Hopfomat PAP.png| Programmablaufplan - [[Datei:HopfomatPAP.zip|mini]] | ||
</gallery> | </gallery> | ||
Zeile 183: | Zeile 195: | ||
#define LEFT (bool) false | #define LEFT (bool) false | ||
/ | //Motor Driver Leadshine DM442 | ||
class DM442 | class DM442 | ||
{ | { | ||
Zeile 197: | Zeile 204: | ||
//Use the defines for setting the direction | //Use the defines for setting the direction | ||
void setDirection(bool direction); | void setDirection(bool direction); //sets the rotating direction | ||
void setFrequency(int stepsPerSecond); | void setFrequency(int stepsPerSecond); //sets the speed | ||
void setDutyCycle(int percent); | void setDutyCycle(int percent); //sets the torque | ||
void resetSteps(); | void resetSteps(); //Reset of counted steps | ||
void singleStep(); | void singleStep(); //Drive one step | ||
void driveSteps(int steps); | void driveSteps(int steps); //Drive many steps | ||
long getSteps(); | long getSteps(); //Get driven steps | ||
private: | private: | ||
Zeile 307: | Zeile 314: | ||
#include "HX711.h" | #include "HX711.h" | ||
#define OFFSET 66981 | #define OFFSET 66981 //Calibration Value | ||
#define SCALE (float) (145173 - OFFSET) / 200 | #define SCALE (float) (145173 - OFFSET) / 200 //Scaling factor of raw Values | ||
HX711 loadCell; | HX711 loadCell; | ||
Zeile 325: | Zeile 332: | ||
/* Start_BEGIN */ | /* Start_BEGIN */ | ||
#ifndef MATLAB_MEX_FILE | #ifndef MATLAB_MEX_FILE | ||
//Initialisation of LoadCell | |||
loadCell.begin((int) DOUT[0], (int) SCK[0]); | |||
loadCell.set_offset(OFFSET); | |||
loadCell.set_scale(SCALE); | |||
#endif | #endif | ||
/* Start_END */ | /* Start_END */ | ||
Zeile 340: | Zeile 347: | ||
/* Output_BEGIN */ | /* Output_BEGIN */ | ||
#ifndef MATLAB_MEX_FILE | #ifndef MATLAB_MEX_FILE | ||
//Read force | |||
float f = loadCell.get_units(10); | float f = loadCell.get_units(10); | ||
force[0] = (double) f; | force[0] = (double) f; | ||
#endif | #endif | ||
/* Output_END */ | /* Output_END */ | ||
Zeile 396: | Zeile 402: | ||
/* Start_BEGIN */ | /* Start_BEGIN */ | ||
#ifndef MATLAB_MEX_FILE | #ifndef MATLAB_MEX_FILE | ||
//Initialise and start Steppermotor | |||
stepper.begin(DIR[0], ENA[0], PUL[0]); | stepper.begin(DIR[0], ENA[0], PUL[0]); | ||
stepper.setDirection(RIGHT); | stepper.setDirection(RIGHT); | ||
stepper.setFrequency(30); | stepper.setFrequency(30); | ||
stepper.start(); | stepper.start(); | ||
#endif | #endif | ||
/* Start_END */ | /* Start_END */ | ||
} | } | ||
void drive_Steps_Outputs_wrapper( | void drive_Steps_Outputs_wrapper(const uint16_T *stepsToDrive, | ||
uint16_T *stepsDriven, | uint16_T *stepsDriven, | ||
const real_T *xD, | const real_T *xD, | ||
Zeile 415: | Zeile 420: | ||
/* Output_BEGIN */ | /* Output_BEGIN */ | ||
#ifndef MATLAB_MEX_FILE | #ifndef MATLAB_MEX_FILE | ||
//Drive x-Steps in 1 second | |||
stepper.setFrequency(stepsToDrive[0]); | |||
stepper.driveSteps(stepsToDrive[0]); | |||
long steps = stepper.getSteps(); | |||
stepsDriven[0] = steps; | |||
#endif | #endif | ||
/* Output_END */ | /* Output_END */ | ||
} | } | ||
void drive_Steps_Update_wrapper( | void drive_Steps_Update_wrapper(const uint16_T *stepsToDrive, | ||
uint16_T *stepsDriven, | uint16_T *stepsDriven, | ||
real_T *xD, | real_T *xD, | ||
Zeile 459: | Zeile 462: | ||
#include "DM442.h" | #include "DM442.h" | ||
//Debug Funktionen | |||
//#define DEBUG | //#define DEBUG | ||
//#define DEBUG_PID | //#define DEBUG_PID | ||
// Definitionen für die Konfiguration | |||
#define OFFSET 66981 | #define OFFSET 66981 | ||
#define SCALE (float) (145173 - OFFSET) / 200 | #define SCALE (float) (145173 - OFFSET) / 200 | ||
Zeile 480: | Zeile 485: | ||
int arrayLength = 50; | int arrayLength = 50; | ||
//Daten für Lookuptable | |||
float forceArray[50] = {-590.41, -574.05, -554.12, -534.25, -514.57, -494.57, -474.99, -455.52, -436.21, -417.06, -389.06, -379.36, -360.83, -342.52, -324.58, -306.87, -289.52, -272.52, -255.77, -239.32, -223.36, -207.89, -192.75, -178.08, -162.85, -150.12, -136.92, -124.11, -111.74, -99.90, -88.64, -77.87, -67.81, -58.80, -49.67, -41.64, -34.24, -27.44, -21.46, -15.85, -11.08, -7.04, -3.68, -0.94, 1.15, 2.47, 3.17}; | float forceArray[50] = {-590.41, -574.05, -554.12, -534.25, -514.57, -494.57, -474.99, -455.52, -436.21, -417.06, -389.06, -379.36, -360.83, -342.52, -324.58, -306.87, -289.52, -272.52, -255.77, -239.32, -223.36, -207.89, -192.75, -178.08, -162.85, -150.12, -136.92, -124.11, -111.74, -99.90, -88.64, -77.87, -67.81, -58.80, -49.67, -41.64, -34.24, -27.44, -21.46, -15.85, -11.08, -7.04, -3.68, -0.94, 1.15, 2.47, 3.17}; | ||
double angleArray[50] = {90, 88.05, 86.10, 84.15, 82.20, 80.25, 78.30, 76.35, 74.40, 72.45, 70.50, 68.55, 66.60, 64.65, 62.70, 60.75, 58.80, 56.85, 54.90, 52.95, 51.00, 49.05, 47.10, 45.15, 43.20, 41.25, 39.30, 37.35, 35.40, 33.45, 31.50, 29.55, 27.60, 25.65, 23.70, 21.75, 19.80, 17.85, 15.90, 13.95, 12.00, 10.05, 8.10, 6.15, 4.20, 2.25, 0.30, 0}; | double angleArray[50] = {90, 88.05, 86.10, 84.15, 82.20, 80.25, 78.30, 76.35, 74.40, 72.45, 70.50, 68.55, 66.60, 64.65, 62.70, 60.75, 58.80, 56.85, 54.90, 52.95, 51.00, 49.05, 47.10, 45.15, 43.20, 41.25, 39.30, 37.35, 35.40, 33.45, 31.50, 29.55, 27.60, 25.65, 23.70, 21.75, 19.80, 17.85, 15.90, 13.95, 12.00, 10.05, 8.10, 6.15, 4.20, 2.25, 0.30, 0}; | ||
// Initialisierung der Lastzelle | |||
void setupHX711() { | void setupHX711() { | ||
loadCell.begin(8, 9); | loadCell.begin(8, 9); | ||
Zeile 489: | Zeile 496: | ||
} | } | ||
// Initialisierung des Schrittmotors | |||
void setupDM442() { | void setupDM442() { | ||
stepper.begin(3, 4, 5); | stepper.begin(3, 4, 5); | ||
Zeile 496: | Zeile 504: | ||
} | } | ||
// Aufruf der Setup-Funktionen und Initialisierung des seriellen Ports | |||
void setup() { | void setup() { | ||
setupDM442(); | setupDM442(); | ||
Zeile 510: | Zeile 519: | ||
static float angle = 90; | static float angle = 90; | ||
//Schalter AUS resette das Programm | |||
if(digitalRead(START_SWITCH) != 0) { | if(digitalRead(START_SWITCH) != 0) { | ||
angle = 90; | angle = 90; | ||
Zeile 523: | Zeile 533: | ||
Serial.print(","); | Serial.print(","); | ||
#endif | #endif | ||
//Messe die anliegende Kraft | |||
float force = loadCell.get_units(10); | float force = loadCell.get_units(10); | ||
#ifdef DEBUG | #ifdef DEBUG | ||
Zeile 530: | Zeile 541: | ||
#endif | #endif | ||
double cosVal = cos(angle * 3.14 / 180); | double cosVal = cos(angle * 3.14 / 180); | ||
//Durch Lookuptable die genullte Kraft bestimmen | |||
double zeroForce = interpolateY(angleArray, forceArray, arrayLength, angle); | double zeroForce = interpolateY(angleArray, forceArray, arrayLength, angle); | ||
#ifdef DEBUG | #ifdef DEBUG | ||
Zeile 536: | Zeile 548: | ||
Serial.print(","); | Serial.print(","); | ||
#endif | #endif | ||
//Die Kraft differenz zwischen Nullkraft und anliegender Kraft | |||
double dF = force - zeroForce; | double dF = force - zeroForce; | ||
#ifdef DEBUG | #ifdef DEBUG | ||
Zeile 542: | Zeile 555: | ||
Serial.print(","); | Serial.print(","); | ||
#endif | #endif | ||
//Berechne die senkrechte Kraft -> Füllstand | |||
double fillLevel = cosVal * dF; | double fillLevel = cosVal * dF; | ||
#if defined(DEBUG) || defined(DEBUG_PID) | #if defined(DEBUG) || defined(DEBUG_PID) | ||
Zeile 548: | Zeile 562: | ||
Serial.print(","); | Serial.print(","); | ||
#endif | #endif | ||
//Berechne die Differenz zum vollen Glas | |||
double error = MAX_FILL_LEVEL - fillLevel; | double error = MAX_FILL_LEVEL - fillLevel; | ||
#ifdef DEBUG_PID | #ifdef DEBUG_PID | ||
Zeile 554: | Zeile 569: | ||
Serial.print(","); | Serial.print(","); | ||
#endif | #endif | ||
//Benutze PID-Regler um Schritte für Motor zu ermitteln | |||
int steps = (int) pid(error, false); | int steps = (int) pid(error, false); | ||
#ifdef DEBUG_PID | #ifdef DEBUG_PID | ||
Zeile 560: | Zeile 576: | ||
Serial.print(","); | Serial.print(","); | ||
#endif | #endif | ||
//Fahre in einer Sekunde die vorgegebenen Schritte | |||
stepper.setFrequency(steps); | stepper.setFrequency(steps); | ||
stepper.driveSteps(steps); | stepper.driveSteps(steps); | ||
//Speichere die insgesamt gefahrenen Schritte abe | |||
unsigned long drivenSteps = stepper.getSteps(); | unsigned long drivenSteps = stepper.getSteps(); | ||
Zeile 568: | Zeile 586: | ||
Serial.print(drivenSteps); | Serial.print(drivenSteps); | ||
#endif | #endif | ||
//Ziehe vom Startwinkel den insgesamt gefahrenen Winkel ab | |||
angle = 90 - drivenSteps * ANGLE_PER_STEP; | angle = 90 - drivenSteps * ANGLE_PER_STEP; | ||
Serial.println(); | Serial.println(); | ||
} | } | ||
//Umsetzung eines PID-Reglers | |||
int pid(double error, bool reset) { | int pid(double error, bool reset) { | ||
static unsigned long startMillis = 0; | static unsigned long startMillis = 0; | ||
Zeile 601: | Zeile 621: | ||
} | } | ||
//Interpolationsfunktion als Look-up Table | |||
float interpolateY(double X[], float Y[], int n, double X_interpolated) { | float interpolateY(double X[], float Y[], int n, double X_interpolated) { | ||
for (int i = 0; i < n - 1; i++) { | for (int i = 0; i < n - 1; i++) { | ||
Zeile 614: | Zeile 635: | ||
} | } | ||
//Rundet nicht bei 0.5 sondern bei 0.1 | |||
int roundTo(float x) { | int roundTo(float x) { | ||
float diff = x - (int) x; | float diff = x - (int) x; | ||
Zeile 692: | Zeile 714: | ||
Dieses Projekt ist Teil des Moduls GET-Fachpraktikum. Dieses Projekt konzentriert sich auf die Regelung und Ansteuerung eines Motors zur Füllstandsregelung eines 0,5 Liter Glases. | Dieses Projekt ist Teil des Moduls GET-Fachpraktikum. Dieses Projekt konzentriert sich auf die Regelung und Ansteuerung eines Motors zur Füllstandsregelung eines 0,5 Liter Glases. | ||
Zu Beginn des Projektes ging es vorwiegend um die Konzeptplanung und die damit verbundenen benötigten Bauteile. Als nächstes wurden die benötigten Bauteile beschafft und auf ihre Eignung geprüft. Des Weiteren wurden die einzelnen Komponenten zu einem Gesamtsystem zusammengebaut und die Funktion des Motors getestet. Dabei fiel auf, dass wir einen stärkeren Motor für unser System benötigten. Nach Einbindung des neuen Motors in das System begannen wir damit die Messwerte zu klassifizieren und den Regler auszulegen. Abschließend legten wir diese Dokumentation im HSHL Wiki an. | Zu Beginn des Projektes ging es vorwiegend um die Konzeptplanung und die damit verbundenen benötigten Bauteile. Als nächstes wurden die benötigten Bauteile beschafft und auf ihre Eignung geprüft. Des Weiteren wurden die einzelnen Komponenten zu einem Gesamtsystem zusammengebaut und die Funktion des Motors getestet. Dabei fiel auf, dass wir einen stärkeren Motor für unser System benötigten. Nach Einbindung des neuen Motors in das System begannen wir damit die Messwerte zu klassifizieren und den Regler auszulegen. Abschließend legten wir diese Dokumentation im HSHL Wiki an. | ||
=== Projektdaten === | |||
ZIP-Archiv: [[Datei:165 Weizen Eingiessanlage.zip|mini]] <br clear="all"> | |||
== YouTube Video == | == YouTube Video == |
Aktuelle Version vom 18. Januar 2024, 00:34 Uhr
Autor: Philipp Sander, Dennis Fleer
Betreuer: Prof. Dr. Mirek Göbel
Einleitung
Dieser Artikel beschreibt den Aufbau und die Funktion einer Weizenglas-Eingießanlage. Hierbei gibt es eine Halterung für die Flasche und eine für ein Glas. Beide sind jeweils an einer rotierenden Holzplatte montiert. Diese Holzplatte wird mittels Elektromotor rotiert. Über einem Drucksensor wird der Füllstand des Weizenglases ermittelt und eine optimale Einfüllung des Glases erreicht.
Anforderungen
Nr. | Beschreibung | Bereich | Zuständig |
---|---|---|---|
1 | Die Halterungen müssen an der Holzplatte befestigt werden. | Hardware | Dennis Fleer, Philipp Sander |
2 | Der Motor muss die Holzplatte drehen können. | Hardware | Dennis Fleer, Philipp Sander |
3 | Die Elektrik muss eingebaut und verkabelt werden. | Hardware | Dennis Fleer, Philipp Sander |
4 | Die Regelung muss durch den Kraftsensor erfolgen. | Software | Dennis Fleer, Philipp Sander |
5 | Der Motor muss mittels Regler angesteuert werden. | Software | Dennis Fleer, Philipp Sander |
Funktionaler Systementwurf/Technischer Systementwurf
Im folgenden Systementwurf wird das Projekt in Systemkomponenten unterteilt:
- Arduino: In Matlab Simulink programmierte Ansteuerung des Motors und Regelung.
- Motor: Drehbewegung der Holzplattform
- Drucksensor: Kraftmessung für die Füllstandserkennung
- Regler: Füllstandsregelung des Weizenglases
-
Weizen Eingießanlage Schematisch - Skizze
-
Technischer Systementwurf
-
Weizen Eingießanlage Regelkreis
Ansatz zur Herleitung der Übertragungsfunktion:
-
Ansatz zur Herleitung der Übertragungsfunktion
Komponentenspezifikation
Nr. | Bauteil | Beschreibung |
---|---|---|
1 | Arduino MEGA 2560 |
|
2 | DM442 Motortreiber |
|
3 | HX711 Wägezelle |
|
4.1 | Schrittmotor ... |
|
Umsetzung (HW/SW)
Hardware
Projektübersicht:
In unserem Projekt liegen die Anforderung vorrangig darin eine motorbetriebene drehbare Holzplatte zu konstruieren und dieses System mit einer geeigneten Motoransteuerung zu betreiben. In bezug auf Kosten und Gewicht haben wir uns daher für eine Holzkonstruktion entschieden. Die Holzplatte, an welcher die Halterungen für die Bierflasche und Weizenflasche sowie der Sensor befestigt ist, wird von einer Massivholzwelle getragen. Diese Welle wird mittels Lageraufständen auf einer Holzgrundplatte befestigt. Die Welle wird durch eine Riemenübersetzung mit dem Schrittmotor angetrieben.
3D Ansicht:
Baugruppen Model
-
Eingießanlage - SolidWorks - Datei:MaschineBaugrp.sldasm
Motor:
Wir wollten zunächst den Motor des Arduino-Mega-Sets verwenden. Allerdings ist uns nach einer kleinen Testfahrt aufgefallen dass dieser zu wenig Haltedrehmoment aufweist. Daher haben wir auf einen ausgediehnten Motor aus unsere Partnerfirma "Diebold-Nixdorf Inc." gesetzt. Dieser Motor war nun auch in der Lage unsere Anforderungen zu erfüllen. Um diesen Motor zu betreiben wählten wir einen Motortreiber welchen wir ebenfalls in einem ausgediehnten Geldautomaten-System fanden.
Konstruktion:
Die Konstruktion der Halterung ist auf den ersten Blick sehr simpel. Dennoch galt es für uns die Kosten sowie das Gewicht niedrig zu halten. Daher belaufen sich fast alle Komponenten auf Holz und Kunststoff. Für die meisten Komponenten konnten wir auf unser Betriebsinternes Lager zurückgreifen lediglich die Holzplatte und die Halterungen für Flasche und Glas waren noch nicht vorhanden. Die Halterungen für Glas und Flasche wurden durch einen 3D-Kunststoffdruck gefertigt. Zudem mussten wir uns überlegen wie wir die Flasche in der Halterung befestigen. Um auch hier eine günstige, einfache und leichte Lösung zu erreichen, setzen wir auf die Spannkraft zweier Gummis, welche die Flasche im Halter halten.
Wägezelle HX711:
Messprinzip: Durch das zu messende Gewicht wird die Wägezelle leicht gebogen. An der Seite befinden sich 4 Dehnungsmesstreifen, welche als Wheatsstone Brücke angeordnet sind. Der Widerstand der Messstreifen ändert sich mit dem Dehnungsgrad. Somit ändert sich bei einer Last der Widerstand und damit auch der Spannungsabfall der Brückenschaltung. Der Spannungsabfall zwischen den Punkten A und B wird mit einem A/D Wandler ausgewertet.
-
- Messchaltungsaufbau
Da die Wägezelle über die physikalische Kraft der Gewichtskraft funktioniert, war es eine Herausforderung in unserem drehenden System die korrekten Werte für den Füllstand zu erhalten. Dies war deshalb so schwierig weil sich die Wägezelle immer in einem anderen Winkel zur Gewichtskraft des Füllstandes befindet. Aus diesem Grund mussten wir die Messwerte noch einmal mit dem cos des Winkels multiplizierten um die korrekte Gewichtskraft zu erhalten. Wir verwenden außerdem einen Look-up-Table um uns die Verarbeitung der Messdaten zu vereinfachen. Konkret subtrahieren wir unseren gemessenen wert mit dem Wert aus dem Look-up-Table an der gleichen Winkelstellung. Somit Erhalten wir die korrekte Gewichtskraft des Pegelstandes des Glases. Dies ist dann dementsprechend unser IST-Wert.
PI-Regler:
Der IST-Wert wird nun mit dem SOLL-Wert von 500 (500ml/Kg) subtrahiert. Somit erhalten wir unsere Regelabweichung welche wir weiterhin mit dem PI-Regler verarbeiten. Aufgrund dessen, dass 1-Motorschritt in 0,39 Grad am äußeren Umfang der Holzplatte entspricht, benötigen wir eine sehr schnelle Regulierung der Motorschritte, sobald Flüssgkeit in das Glas läuft. Daher benötigen wir eine möglichst schnelle Sprungantwort und somit einen großen P-Anteil in unserem Regler. Für unser System haben sich die Werte Kp=0,014 und Ki=0,00675 als praktikabel erwiesen. Die Stellgröße des Reglers wird direkt als Ansteuerung für den Motor genutzt.
Motoransteuerung:
Die Motoransteuerung erfolgt über den Motortreiber DM441 dieser braucht eine externe Versorgungsspannung von 24V. Außerdem werden zur Steuerung drei Pins angeschlossen.
- ENA: Sorgt für das Starten des Motors und zusätzlich auch für einen Haltestrom.
- DIR: Gibt die Richtung, in die der Motor fahren soll.
- PUL: Über diesen Pin wird ein PWM-Signal gesendet, welches das Drehmoment und die Geschwindigkeit bestimmt.
Verdrahtungsplan:
-
Verdrahtungsplan Eingießanlage - Datei:Verdrahtungsplan Hopfomat.zip
Software
Programmablaufplan:
-
Programmablaufplan - Datei:HopfomatPAP.zip
Simulink Regler Model:
DM442.h:
DM442.cpp:
read_HX711 S-Function:
drive_Steps S-Function:
Arduino Regler:
Komponententest
Nr. | Beschreibung | Testmethode | Zuständigkeit | Testergebnis |
---|---|---|---|---|
1 | Die Halterungen müssen an der Holzplatte befestigt werden. | Die Halterungen wurden korrekt befestigt und halten dem Gewicht und der Rotation stand. | Fleer, Sander | Bestanden |
2 | Der Motor muss die Holzplatte drehen können. | Der Motor kann sowohl beide Gewichte als auch nur die Flasche ohne Probleme heben und halten. | Fleer, Sander | Bestanden |
3 | Die Elektrik muss eingebaut und verkabelt werden. | Die Verdrahtung der Bauteile wurde korrekt durchgeführt und nochmals mittels Durchgangsprüfung geprüft. | Fleer, Sander | Bestanden |
4 | Die Regelung muss durch den Kraftsensor erfolgen. | Die Wägezelle misst jede Sekunde die Gewichtskraft des Inhalts. Dieser Ist-Wert wird mit dem Soll-Wert subtrahiert und geht als Regelfehler in unseren Regler. | Fleer, Sander | Bestanden |
5 | Der Motor muss mittels Regler angesteuert werden | Die Ansteuerung erfolgt softwareseitig durch die Stellgröße unseres Reglers. | Fleer, Sander | Bestanden |
Ergebnis
Das Projekt zur Füllstandsregelung eines Bierglases an der HSHL im Fachgebiet der Mechatronik führte zu einem positiven Ergebnis. Die Anlage ist in der Lage durch umlegen eines Schalters ein 0,5Liter Bierglas einzuschenken. Zu Beginn des Einfüllvorgangs werden die maximalen Motorschritte gefahren. Sobald der Füllstand erkannt wird, werden, je nach Füllstand, weniger Schritte gefahren.
-
Frontansicht der Weizeneingießanlage
-
Rückansicht der Weizeneingießanlage
Zusammenfassung
Lessons Learned
Wir haben am Anfang viele Überlegungen getroffen. Aufgrund von Berechnungsfehlern oder falschen Datenblättern haben wir viele Rükschläge erleiden müssen. Schlussendlich konnten wir unseren Anfangs geplanten Ablauf nicht in die Tat umsetzen und sind ziehmlich in Zeitstress gekommen. Daraus haben wir gelernt jedes Datenblatt zweimal zu überprüfen und Berechnungen auch in der Realität auszuprobieren und nicht auf theoretische Annahmen zu vertrauen.
Auch die Programmierung mit Simulink war eine Tortur. Aufgrund unseres Zeitdrucks haben wir uns dann dazu entschieden erstmal ein Arduino Programm zu entwickeln, womit wir immerhin schonmal alles testen konnten und weiter kamen. Später haben wir dann die Reglereinstellungen und Ansteuerungen für Sensor und Aktor in S-Function-Blöcke übernommen und so ein lauffähiges Simulink Modell kreiert. Die Schlüsse die wir hier raus gezogen haben, sind erstmal den vertrauten einfachen Weg gehen und später erst den unkonventionellen Weg nehmen. Auch haben wir gelernt nie wieder auf Matlab Simulink etwas für einen Arduino zu programmieren, da dies um ein viel faches schwieriger ist als ein sauber aufgebautes Arduino Projekt.
In der Programmierung gab es noch ein weiteres Problem. Für den HX711 gab es eine lauffähige Bibliothek schon zur Verfügung. Da wir nicht auf den Anfangs geplanten Motor von Funduino zurück greifen konnten mussten wir einen anderen Motor nehmen. Da dieser Motor eine Anfertigung für die Firma Diebold Nixdorf ist gibt es keine öffentlichen Bibliotheken zur Steuerung. Somit musste hier eine eigene Bibliothek zur Steuerung programmiert werden. Diese musste dann auch wieder getestet und Fehler behoben werden. Auch hier wäre mit mehr Zeit es einfacher gewesen einen Motor zu beschaffen der schon eine fertige Bibliothek öffentlich verfügbar hat.
Projektunterlagen
Projektplan
-
Projektplan
Projektdurchführung
Dieses Projekt ist Teil des Moduls GET-Fachpraktikum. Dieses Projekt konzentriert sich auf die Regelung und Ansteuerung eines Motors zur Füllstandsregelung eines 0,5 Liter Glases. Zu Beginn des Projektes ging es vorwiegend um die Konzeptplanung und die damit verbundenen benötigten Bauteile. Als nächstes wurden die benötigten Bauteile beschafft und auf ihre Eignung geprüft. Des Weiteren wurden die einzelnen Komponenten zu einem Gesamtsystem zusammengebaut und die Funktion des Motors getestet. Dabei fiel auf, dass wir einen stärkeren Motor für unser System benötigten. Nach Einbindung des neuen Motors in das System begannen wir damit die Messwerte zu klassifizieren und den Regler auszulegen. Abschließend legten wir diese Dokumentation im HSHL Wiki an.
Projektdaten
ZIP-Archiv: Datei:165 Weizen Eingiessanlage.zip
YouTube Video
In dem folgenden Youtube Video YouTube-Video werden die Funktionen Funktion der Weizeneingießanlage gezeigt.
Weblinks
Literatur
→ zurück zur Übersicht: WS 22/23: Angewandte Elektrotechnik (BSE)