Programmcodes Einzelblattstapelbildung / Mbed 2 deprecated Bahnkantenregelung_Julian

Dependencies:   TextLCD mbed

Files at this revision

API Documentation at this revision

Comitter:
Jules20
Date:
Tue May 31 03:06:27 2016 +0000
Commit message:
Committed May 2016

Changed in this revision

TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
auto_func.cpp Show annotated file Show diff for this revision Revisions of this file
auto_func.h Show annotated file Show diff for this revision Revisions of this file
edge_func.cpp Show annotated file Show diff for this revision Revisions of this file
edge_func.h Show annotated file Show diff for this revision Revisions of this file
hand_func.cpp Show annotated file Show diff for this revision Revisions of this file
hand_func.h Show annotated file Show diff for this revision Revisions of this file
interface.cpp Show annotated file Show diff for this revision Revisions of this file
interface.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
mtr_func.cpp Show annotated file Show diff for this revision Revisions of this file
mtr_func.h Show annotated file Show diff for this revision Revisions of this file
regler.cpp Show annotated file Show diff for this revision Revisions of this file
regler.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r b72d86a7b005 TextLCD.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.lib	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/TextLCD/#308d188a2d3a
diff -r 000000000000 -r b72d86a7b005 auto_func.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/auto_func.cpp	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,173 @@
+/**
+*Funktionen fuer den Autmatikbetrieb
+*
+*CPP-Datei auto_func.cpp
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#include "auto_func.h"
+#include "mbed.h"
+//Variablen fuer Automatikbetrieb
+float TA=0.04; //Abtastzeit[s], entspricht Abtastrate 25 Hz
+//Bereich, indem das Kantenpixel zum Start des Automatikbetriebs sein muss
+int minPx=30;
+int maxPx=100;
+Timer t;// Timer der Uebergang zu Automatikbetrieb bei Fehler abbricht
+int maxt=1; // Maximale zulaessige Zeit fuer Uebergang zu Automatikbetrieb
+
+//Variablen fuer auto_sens_ctr()
+int cnt_Err; //Zaehler fuer aufeinanderfolgende Fehler bei der Kantendetektion
+int allow_Err=10; //zulaessige Anzahl aufeinanderfolgender Fehler bei der Kantendetektion
+int auto_curPx; //Wert des aktuellen Kantenpixel
+int auto_forPx; //Wert des vorhergehenden Kantenpixel
+int threshDiff=15; //zulaessige Abweichung zu vorhergehendem Kantenpixel in Anzahl Pixel
+Ticker tickerReg; //Ticker, der das Auslesen des Sensors und die Reglung taktet
+
+
+//Variablen fuer auto_sollPx_set()
+int auto_sollPx; //zwischenspeichern des Sollwertes
+//Variablen fuer auto_kp_set()
+float main_kp; //zwischenschpeichern von kp
+
+void auto_setup()
+{
+    cnt_Err=0;
+    t.reset();
+    t.start();
+
+    while(1) { //Finde Kante in Toleranzbereich
+        auto_curPx=edgePx_get();//Sensor auslesen
+        if(auto_curPx>minPx && auto_curPx<maxPx) {
+
+            t.stop();
+            regler_setup();
+            lcd.cls();
+            lcd.locate(0,0);
+            lcd.printf("Auto   SOLL=%i",regler_sollPx_get());
+            lcd.locate(0,1);
+            lcd.printf(">kp >soll  >hand");
+            //Ticker fuer Taktung der Reglung mit Funktion verknuepfen,Abtastrate TA
+            
+            tickerReg.attach(&auto_sens_ctr,TA);
+            
+            break;
+        } else {
+            lcd.cls();
+            lcd.locate(0,0);
+            lcd.printf("Detektion nicht moeglich.");
+            
+        }
+    }
+
+
+}
+
+void auto_end()
+{
+    tickerReg.detach();//Ticker fuer Taktung der Reglung beenden
+    regler_end();//Reglerparameter in Datei speichern
+}
+
+void auto_sens_ctr()
+{
+    auto_forPx=auto_curPx; 
+    auto_curPx=edgePx_get();//Sensor auslesen
+   
+    if(auto_curPx<0) {
+        //Fehler bei Kantendetektion
+        cnt_Err++;
+        //nehme vorhergehenden Wert an, solange bis cnt_Err Grenzwert erreicht
+        auto_curPx=auto_forPx;
+    } else if(abs(auto_forPx-auto_curPx)>threshDiff) {
+        //Differenz zu vorhergendem Wert zu gross
+        cnt_Err++;
+        //nehme vorherhegenden an, solange bis cnt_Err Grenzwert erreicht
+        auto_curPx=auto_forPx;
+    } else { //Kantendetektion erfolgreich
+        cnt_Err=0; //setze zul. Fehler auf 0
+    }
+
+    if(cnt_Err<allow_Err) {
+        //fuehre Regelungalgorithmus aus
+        control(auto_curPx);
+    } else {
+        //NOTAUS, schalte Motor bewegungslos, keine Meldung auf Display
+        mtr_period_set(0); //Motor bewegungslos schalten
+    }
+
+    //fuehre Regelungalgorithmus aus
+    control(auto_curPx);
+}
+
+void auto_sollPx_set() 
+{
+    auto_sollPx=regler_sollPx_get();
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("SOLL=%i", auto_sollPx);
+    lcd.locate(0,1);
+    lcd.printf(">+    >-   >auto");
+    while(1) {
+        if(butLe==1 && debLe.read_ms()>500) {
+            //erhoehe sollwert
+            debLe.reset();
+            auto_sollPx=auto_sollPx+1;
+            regler_sollPx_set(auto_sollPx);
+            lcd.locate(0,0);
+            lcd.printf("SOLL=%i", auto_sollPx);
+        } else if(butMi==1 && debMi.read_ms()>500) {
+            //erhoehe sollwert
+            debMi.reset();
+            auto_sollPx=auto_sollPx-1;
+            regler_sollPx_set(auto_sollPx);
+            lcd.locate(0,0);
+            lcd.printf("SOLL=%i", auto_sollPx);
+        } else if(butRi==1 && debRi.read_ms()>500) {
+            //verlasse while schleife zum aendern von soll
+            debRi.reset();
+            lcd.cls();
+            lcd.locate(0,0);
+            lcd.printf("Auto   SOLL=%i",regler_sollPx_get());
+            lcd.locate(0,1);
+            lcd.printf(">kp >soll  >hand");
+            break;
+        }
+    }
+}
+void auto_kp_set()
+{
+    main_kp=regler_kp_get();
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("kp=%.1f", main_kp);
+    lcd.locate(0,1);
+    lcd.printf(">+    >-   >auto");
+    while(1) {
+        if(butLe==1 && debLe.read_ms()>500) {
+            //erhoehe kp
+            debLe.reset();
+            main_kp=main_kp+0.1;
+            regler_kp_set(main_kp);
+            lcd.locate(0,0);
+            lcd.printf("kp=%.1f", main_kp);
+        } else if(butMi==1 && debMi.read_ms()>500) {
+            //verringere kp
+            debMi.reset();
+            main_kp=main_kp-0.1;
+            regler_kp_set(main_kp);
+            lcd.locate(0,0);
+            lcd.printf("kp=%.1f", main_kp);
+        } else if(butRi==1 && debRi.read_ms()>500) {
+            //verlasse while schleife zum aendern kp
+            debRi.reset();
+            lcd.cls();
+            lcd.locate(0,0);
+            lcd.printf("Auto   SOLL=%i",regler_sollPx_get());
+            lcd.locate(0,1);
+            lcd.printf(">kp >soll  >hand");
+            break;
+        }
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 auto_func.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/auto_func.h	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,41 @@
+/**
+*Funktionen fuer den Autmatikbetrieb
+*
+*Headerdatei auto_func.h
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#ifndef AUTO_FUNC_H
+#define AUTO_FUNC_H
+
+#include "mbed.h"
+#include "edge_func.h"
+#include "regler.h"
+#include "TextLCD.h"
+#include "mtr_func.h"
+
+/**
+ * Funktion initialisiert die Werte fuer Variablen muss beim Start des Automatikbetriebs aufgerufen werden
+*/
+void auto_setup();
+/**
+ * Funktion muss zum beenden des Automatikbetriebs aufgerufen werden
+*/
+void auto_end();
+/**
+ * Funktion liest Sensor aus und reglt Kante auf das Soll Pixel, muss zyklisch aufgerufen werden
+*/
+void auto_sens_ctr();
+/**
+ * Funktion zum aendern des Soll-Pixels
+ * ueber die Taster
+*/
+void auto_sollPx_set();
+/**
+ * Funktion zum Aendern des Proportionalitaetswertes kp des Reglers
+ * ueber die Taster
+*/
+void auto_kp_set(); 
+#endif
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 edge_func.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/edge_func.cpp	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,283 @@
+/**
+*Funktionen zum Auslesen der Linienkamera und zur Detektion der Kante
+*
+*CPP-Datei edge_func.cpp
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#include "edge_func.h"
+
+//Definiton zur Anzeige von Fehlern
+DigitalOut errorLED(LED1); //zeigt an, dass Fehler auftritt
+
+// Definition der Pins des Sensors
+DigitalOut clk(p18); //Clock Pin
+DigitalOut si(p19); //SI Pin
+//analoger Eingang Wertebereich [0..1] mit ao.read()
+// misst die Spannung die am Sensorausgang anliegt
+AnalogIn ao(p20); 
+
+//Variablen fuer alle Funktionen der Datei
+const int numPx =128; // Anzahl der Pixel
+const int leftbound = 8; // linker Randbereich des Sensors, nicht betrachtet
+const int rightbound = numPx - leftbound; //rechter Randbereich des Sensors, nicht betrachtet
+queue<int> possEdgePx; //enthaelt die Pixel die als Kante in Frage kommen
+int tmpPossEdgePx; //temporaeres moegliches Kantenpixel
+int numPossEdgePx; //Anzahl der moeglichen Kantenpixel
+
+//Variablen fuer read()
+float currentVal[numPx]; //Werte der Pixel einer Messung
+const int numMeas =3; //Werte werden ueber numMeas Messungen gemittelt
+float meanVal[numPx]; //Mittelwerte jedes Pixels ueber die (NumMeas) Messungen
+float currentPx;
+int delay=2; //Verzoegerung zum Einstellen der Belichtungszeit in [10⁻³ s]
+//Variablen zur Detektion einer Fehlfunktion des Sensors
+const float epsilon=0.01; //minimal zulaessiger Wert eines Pixels
+int cntZero; //Anzahl ungueltiger Pixel(<epsilion)
+const int zeroMax=5; //maximale Anzahl ungueltiger Pixel pro Messung
+bool validMeas; //zeigt ob eine Messungen gueltig ist
+
+//Variablen fuer gaussian_calc()
+float gaussian[numPx]; //gauss gefilterte Grauwerte
+
+//Variablen fuer gradient_calc()
+float gradient[numPx]; //Gradienten der Pixel
+
+//Variablen fuer nonMaxSupr()
+//Gradienten liegt in [-1.0,1.0]
+// relevant ist nur [-1.0,0.0]
+// Anzahl der Quanten in Intervall=numQuant+1 
+const int numQuant=15;
+float quantStepSize=1.0/numQuant; // Schrittweite eines Quants
+float quantStep[numQuant]; //Quantenstufen
+float quant[numPx]; //quantisierte Werte des Gradienten
+
+//Variablen fuer plausible()
+float meanLeft; //Mittelwert der Pixel links eines moeglichen Kantenpixels
+float meanRight; //Mittelwert der Pixel rechts eines moeglichen Kantenpixels
+const float threshBlack=0.4; //Grenzwert definiert Beschichtung
+const float threshFoil=0.7; //Grenzwert definiert Metallfolie
+
+//Variablen fuer edge_calc()
+float gradmin; //minimaler Gradient
+int edgePx; //gefundenes Kantenpixel Wertebereich [leftbound..rightbound]
+
+void clockPulse()
+{
+    clk=1;
+    clk=0;
+}
+
+void siClkPulse()
+{
+    si=1;
+    clockPulse();
+    si=0;
+}
+
+void sens_setup()
+{
+    errorLED=0;
+    edgePx=-1;
+    clk=0;
+    si=0;
+
+    //linker und rechter Randbereich werden nicht betrachtet
+    for (int i = 0; i < leftbound - 1; i++) {
+        gaussian[i]= 0.0;
+        gradient[i]= 0.0;
+        quant[i]= 0.0;
+    }
+    for (int i = rightbound + 1; i < numPx; i++) {
+        gaussian[i]= 0.0;
+        gradient[i]= 0.0;
+        quant[i]= 0.0;
+    }
+
+    //QuantenStufen zur Quantisierung des Gradienten
+    for(int k=0; k<numQuant; k++) {
+        quantStep[k]=-(k+1)*quantStepSize;
+    }
+}
+
+void read()
+{
+    
+    edgePx=-10; //Fehler in Algorithmus wenn Wert -10 bleibt
+    for(int j=0; j<numMeas; j++) {
+        validMeas=1; // setze Messung gueltig
+        cntZero=0;  // setze Anzahl ungueltiger Pixel=0
+        
+        siClkPulse(); //stoppt Belichtung der Pixel und startet sie erneut
+        for(int k = 0; k < 130; k++) {
+            //neue Belichtung der Pixel beginnt bei k=18
+            //jeder clock-Puls eliminiert den alten Wert eines Pixels
+            clockPulse();
+        }
+
+        wait_ms(delay); // Verzoegerung um die Belichtungszeit zu vergroessern
+        siClkPulse(); //stoppt Belichtung der Pixel und startet sie erneut
+
+        //Auslesen und Speichern der Werte der Pixel
+        //jeder Clock Puls legt an ao den Wert(Spannung) des naechsten Pixels an
+        for(int i=0; i < numPx; i++) {
+            wait_us(5);//Verzoegerung um den analogen Ausgang des Sensors zu stabilisieren
+            currentPx= ao.read(); //einlesen des Wertes
+            if(currentPx < epsilon) {
+                cntZero++; //zaehlen der ungueltigen Pixel
+            }
+            currentVal[i]=currentPx;
+            clockPulse();
+
+            //ueberpruefen ob Messung noch gueltig ist
+            if (cntZero > zeroMax) {
+                errorLED=!errorLED;
+                edgePx= -1; //Fehler Nummer 1
+                validMeas=0; // setze Messung fehlerhaft
+                break; //stoppt Auslesen des Sensors, startet neue Belichtung
+            }
+        }
+
+        //Mittelung der Werte mit vorherigen Messungen wenn neue Messung gueltig
+        if(validMeas) {
+            if(j>0) {
+                for(int i=0; i<numPx; i++) {
+                    meanVal[i]=(meanVal[i]+currentVal[i])/2;
+                }
+            } else { //j==0
+                for(int i=0; i<numPx; i++) {
+                    meanVal[i]=currentVal[i];
+                }
+            }
+        }
+    }
+}
+
+void gaussian_calc()
+{
+    //Gauß Filter sigma=2, k=5, G(x,sigma)=1/113*[1,3,7,14,20,23,20,14,7,3,1]
+    for (int i = leftbound - 1; i < rightbound + 1; i++) {
+        gaussian[i] = (meanVal[i-5]+meanVal[i-4]*3
+                       +meanVal[i-3]*7+meanVal[i-2]*14
+                       + meanVal[i-1]*20+meanVal[i]*23
+                       + meanVal[i+1]*20+meanVal[i+2]*14
+                       + meanVal[i+3]*7+meanVal[i+4]*3+
+                       meanVal[i+5])/113;
+    }
+
+}
+
+void gradient_calc()
+{
+    for (int i = leftbound; i < rightbound; i++) {
+        gradient[i] = (meanVal[i-1]- meanVal[i+1]) / 2;
+    }
+
+}
+
+
+void nonMaxSupr()
+{
+    //Quantisierung des Gradienten
+    for(int i=leftbound; i<rightbound; i++) {
+        if(gradient[i]> quantStep[0]) {
+            quant[i]=0.0;//keine Kante
+        } else {
+            for(int k=1; k<numQuant; k++) {
+                if(gradient[i]> quantStep[k]) {
+                    quant[i]=quantStep[k-1];
+                    possEdgePx.push(i); //moegliche Kante
+                    break;
+                }
+            }
+        }
+    }
+
+    //Non-Maxima-Supression
+
+    numPossEdgePx=possEdgePx.size();
+
+    for (int i=0; i<numPossEdgePx; i++) {
+        tmpPossEdgePx=possEdgePx.front();
+        possEdgePx.pop();
+        //Bedingung fuer Kante if(quant[tmpPossEdgePx]<=quant[tmpPossEdgePx-1] && quant[tmpPossEdgePx]<=quant[tmpPossEdgePx+1] )
+        //negiert damit Gleichheit zwischen Float nicht ueberprüft werden muss
+        if(!(quant[tmpPossEdgePx]>quant[tmpPossEdgePx-1] || quant[tmpPossEdgePx]>quant[tmpPossEdgePx+1]))  {
+            possEdgePx.push(tmpPossEdgePx); //moegliche Kante
+        }
+    }
+}
+
+void plausible()
+{
+//Plausibilitaetspruefung
+    if(possEdgePx.empty()) {
+        errorLED=!errorLED;
+        edgePx=-2; // Fehler Nummer 2
+    }
+
+    //Plausibilitaetspruefung: ueberpruefe die Umgebung jedes moeglichen Kantenpixels
+    // die Pixel links davon muessen im Mittelwert < threshblack
+    // die Pixel rechts davon >threshfoil
+    numPossEdgePx=possEdgePx.size();
+
+    for (int j=0; j<numPossEdgePx; j++) {
+        tmpPossEdgePx=possEdgePx.front();
+        possEdgePx.pop();
+        meanLeft=0.0;
+        meanRight=0.0;
+        for(int i=1; i<6; i++) {
+            meanLeft+=meanVal[tmpPossEdgePx-i];
+            meanRight+=meanVal[tmpPossEdgePx+i];
+        }
+        meanLeft=meanLeft/5;
+        meanRight=meanRight/5;
+
+        if(meanLeft < threshBlack && meanRight> threshFoil) {
+            possEdgePx.push(tmpPossEdgePx);
+        }
+    }
+
+}
+
+void edgePx_calc()
+{
+    if(possEdgePx.empty()) {
+        errorLED=!errorLED;
+        edgePx=-3; //Fehler Nummer 3
+    } else if (possEdgePx.size()==1) {
+        //nur ein moegliches Kantenpixel uebrig
+        edgePx=possEdgePx.front();
+        possEdgePx.pop();
+    } else {
+        //mehrere moegliche Kantenpixel;
+        //bei richtig eingestelltem Sensor sollten hier durch die Plausibilitaetspruefung
+        //nur noch Nachbarpixel mit gleich großem quantisiertem Gradient uebrig sein
+        //waehle Pixel mit minimalem Gradient(float)
+        gradmin = 0.0;
+        numPossEdgePx = possEdgePx.size();
+        for (int i = 0; i < numPossEdgePx; i++) {
+            tmpPossEdgePx=possEdgePx.front();
+            possEdgePx.pop();
+            if ( gradient[tmpPossEdgePx]< gradmin) {
+                gradmin=gradient[tmpPossEdgePx];
+                edgePx=tmpPossEdgePx;//gefundenes Kantenpixel, Algorithmus erfolgreich
+                errorLED=0;
+            }
+        }
+    }
+}
+
+int edgePx_get()
+{
+    read();
+    gaussian_calc();
+    gradient_calc();
+    nonMaxSupr();
+    plausible();
+    edgePx_calc();
+    return edgePx;
+}
+
diff -r 000000000000 -r b72d86a7b005 edge_func.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/edge_func.h	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,76 @@
+/**
+*Funktionen zum Auslesen der Linienkamera und zur Detektion der Kante
+*
+*Headerdatei edge_func.h
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+#ifndef EDGE_FUNC_H
+#define EDGE_FUNC_H
+
+#include "mbed.h"
+#include "interface.h"
+#include<queue>
+
+/**
+ * Funktion initialisiert die Werte fuer Variablen
+ * muss vor der Verwendung der Kamera ausgefuehrt werden
+
+*/
+void sens_setup();
+/**
+ * Funktion erzeugt einen Puls auf dem ClockPin
+*/
+void clockPulse(); 
+
+/**
+ * Funktion erzeugt einen Puls auf dem SI- und auf dem ClockPin
+*/
+void siClkPulse();
+
+/**
+ * Funktion liest den Sensor aus
+ * berechnet den Mittelwert der Grauwerte aus mehreren (numMeas) Messungen
+ * speichert die Werte in meanVal
+ * der Wertebereich eines Pixels ist [0,1]
+ * kontrolliert ob eine Messung fehlerhaft ist (Fehlfunktion des Sensors)
+*/
+void read(); 
+
+/**
+ * Funktion glaettet die in meanVal gespeicherten Grauwerte mit einem Gaußfilter
+*/
+void gaussian_calc();
+
+/**
+ * Funktion berechnet den Gradienten der Gauss gefilterten Grauwerte
+*/
+void gradient_calc();
+
+/**
+ * Funktion fuehrt Non-Maxima-Supression aus
+ * quantisiert den Gradienten und berechnet lokale Maxima
+ * d.h. Pixel die als Kante in Frage kommen
+ * die anderen Pixel werden "unterdrueckt"
+*/
+void nonMaxSupr();//
+
+/**
+ * Funktion fuehrt Plausibilitaetspruefung fuer moegliche Kantenpixel aus
+*/
+void plausible();
+
+/**
+ * Funktion berechnet Kantenpixel
+ * waehlt Pixel mit minimalem Gradient aus den moeglichen Kantenpixeln
+*/
+void edgePx_calc();
+
+/**
+ * Funktion berechnet Position (Pixel) der Kante und gibt diese zurück
+ * @return Kantenpixel
+*/
+int edgePx_get();
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 hand_func.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hand_func.cpp	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,44 @@
+/**
+*Funktionen fuer den Handbetrieb
+*
+*CPP-Datei hand_func.cpp
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#include "hand_func.h"
+#include "edge_func.h"
+
+//Variablen fuer Handbetrieb
+int hand_curPx;
+Ticker tickerDispPx; //Ticker zum Aktualisieren der Kantenposition auf dem Display im Handbetrieb
+
+
+void hand_setup()
+{
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("Hand");
+    lcd.locate(0,1);
+    lcd.printf("Pos Px=    >auto");
+    //aktualisiere Kantenposition auf dem Display jede 0.5 Sekunden
+    tickerDispPx.attach(&dispPx,0.5);
+}
+
+void hand_end()
+{
+    tickerDispPx.detach();
+}
+
+void dispPx()
+{
+    hand_curPx=edgePx_get();
+    if(hand_curPx<0) { //Fehlermeldung anzeigen
+        lcd.locate(0,1);
+        lcd.printf("ERROR Nr.%i  ",hand_curPx);
+    } else {
+        lcd.locate(0,1);
+        lcd.printf("Pos Px=%i  ",hand_curPx);
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 hand_func.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hand_func.h	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,32 @@
+/**
+*Funktionen fuer den Handbetrieb
+*
+*Headerdatei edge_func.h
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#ifndef HAND_FUNC_H
+#define HAND_FUNC_H
+
+#include "mbed.h"
+#include "TextLCD.h"
+
+/**
+ * Funktion muss beim Start des Handbetriebs aufgerufen werden
+ * initialisiert die Werte fuer Variablen
+ */
+void hand_setup();
+
+/**
+ * Funktion muss beim Verlassen des Handbetriebs aufgerufen werden
+ */
+void hand_end();
+
+/**
+ * Funktion aktualisiert Kantenposition auf dem Display 
+ */
+void dispPx();
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 interface.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/interface.cpp	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,22 @@
+/**
+*Definition globaler Schnittstellen
+*
+*CPP-Datei interface.cpp
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#include "interface.h"
+
+//Taster
+DigitalIn butLe(p7);//Linker Taster
+DigitalIn butMi(p6);//Mittlerer Taster
+DigitalIn butRi(p5);//Rechter Taster
+//Timer zum Entprellen (debounce) der Taster
+Timer debLe;
+Timer debMi;
+Timer debRi;
+
+//LCD-Display; pin Reihenfolge: rs, e, d0, d1, d2, d3
+TextLCD lcd(p24, p25, p26, p27, p28, p29); 
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 interface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/interface.h	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,28 @@
+/**
+*Definition globaler Schnittstellen
+*
+*Headerdatei interface.h
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include "mbed.h"
+#include "TextLCD.h" 
+
+//Taster
+extern DigitalIn butLe;//Linker Taster
+extern DigitalIn butMi;//Mittlerer Taster
+extern DigitalIn butRi;//Rechter Taster
+//Timer zum Entprellen (debounce) der Taster
+extern Timer debLe;
+extern Timer debMi;
+extern Timer debRi;
+
+extern TextLCD lcd; //LCD-Display
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,108 @@
+/**
+*Zustansautomat zur Lageregelung der Beschichtungskante einer Elektrodenbahn für ein Feinstanz-Maschinenmoduls in der
+* Lithium-Ionen-Zellen Fertigung.
+*
+*Der Zustandsautomat enthält einen Handbetrieb und einen Automatikbetrieb.
+*Im Handbetrieb kann der Tisch mit der Abwickeleinheit für die Elktrodenbahn manuell in (+/-) y-Richtung bewegt werden.
+*Im Automatikbetrieb wird ein als P-Regler zur regelung der Position der Beschichtungskante ausgeführt.
+*
+*CPP-Datei main.cpp
+*
+*@version: 01.11.2015
+*@author: Gustav Grether & Julian Mueller
+*/
+#include "mbed.h"
+#include "edge_func.h"
+#include "auto_func.h"
+#include "hand_func.h"
+#include "mtr_func.h"
+#include "regler.h"
+
+
+int main()
+{
+    sens_setup(); //setup des Sensors
+    //Timer für Schalterentprellung starten
+    debLe.start();
+    debMi.start();
+    debRi.start();
+
+//Zustandsautomat
+    while(1) {
+         //
+        //Automatikbetrieb -> direktes Starten im Auto-Betrieb
+        //
+        mtr_en_set(1); //Motor einschalten
+        mtr_period_set(0);//Motor bewegungslos
+        
+        auto_setup();//startet getaktetes Sensorauslesen und Reglung
+        while(1) {
+            if(butLe==1 && debLe.read_ms()>500) {//aendere kp Proportionalverstaerkung
+                debLe.reset();
+                auto_kp_set();
+                regler_end();
+            }            else if(butMi==1 && debMi.read_ms()>500) {//aendere Sollwert
+                debMi.reset();
+                auto_sollPx_set();
+                regler_end();
+            } else if(butRi==1 && debRi.read_ms()>500) {
+                debLe.reset();
+                debMi.reset();
+                debRi.reset();
+                //wechsle in Handbetrieb
+                auto_end();//Automatikbetrieb beenden, Reglerparameter speichern
+                break;
+            }
+        }
+        //
+        //Handbetrieb
+        //
+        hand_setup();//aktualisiert Kantenposition auf Display
+        mtr_en_set(1); //Motor einschalten
+        mtr_period_set(0);//Motor bewegungslos
+
+        while(1) {
+            if(butLe==1 && debLe.read_ms()>500) {
+
+                if(mtr_period_get()==0) { //Motor steht, Fahre nach +y
+                    mtr_dir_set(1);
+                    mtr_period_set(1000);//Periodendauer PWM T=1000 us
+                    lcd.locate(7,0);
+                    lcd.printf("MTR +y  ");
+                } else { //Motor bewegt sich
+                    mtr_period_set(0);//halte Motor an
+                    lcd.locate(7,0);
+                    lcd.printf("MTR stop");
+                }
+                debLe.reset();
+                debMi.reset();
+                debRi.reset();
+
+            } else if(butMi==1 && debMi.read_ms()>500)  {
+                if(mtr_period_get()==0) { //Motor steht, Fahre nach -y
+                    mtr_dir_set(0);
+                    mtr_period_set(1000);//Periodendauer PWM T=1500 us
+                    lcd.locate(7,0);
+                    lcd.printf("MTR -y  ");
+                } else { //Motor bewegt sich
+                    mtr_period_set(0);//halte Motor an
+                    lcd.locate(7,0);
+                    lcd.printf("MTR stop");
+                }
+                debLe.reset();
+                debMi.reset();
+                debRi.reset();
+            }
+
+            else if(butRi==1 && debRi.read_ms()>500) { //wechsle in Automatikbetrieb
+                mtr_period_set(0);//Motor bewegungslos
+                debLe.reset();
+                debMi.reset();
+                debRi.reset();
+                break;
+            }
+        }
+        hand_end();
+     
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/487b796308b0
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 mtr_func.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtr_func.cpp	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,45 @@
+/**
+*Funktionen zur Ansteuerung des Steppermotors
+*
+*CPP-Datei mtr_func.cpp
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#include "mtr_func.h"
+
+//Ausgaenge Mikrocontroller
+DigitalOut mtr_en(p21); //Digital Ausgang: EN
+DigitalOut mtr_dir(p22); //Digital Ausgang: DIR
+PwmOut mtr_pwm(p23); //PWM-Ausgang: STEP
+
+
+//Variablen fuer mtr_pwm_set()
+int mtr_period=0; //Periodendauer der PWM
+
+void mtr_en_set(int state)
+{
+    //Einschaltzustand setzen.
+    //1 = Motor wird mit Strom versorgt.
+    //0 = Motor ist stromlos
+    mtr_en = state;
+}
+
+void mtr_dir_set(int dir)
+{
+    // Drehrichtung setzen
+    //1 = in +y fahren
+    //0 = in -y fahren
+    mtr_dir = dir;
+}
+
+int mtr_period_get(){
+    return mtr_period;
+}
+void mtr_period_set(int period)
+{
+    mtr_period=period;
+    mtr_pwm.period_us(mtr_period);
+    mtr_pwm.write(0.5);//PWM-Tastverhaeltnis setzen
+}
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 mtr_func.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtr_func.h	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,40 @@
+/**
+*Funktionen zur Ansteuerung des Steppermotors
+*
+*Headerdatei mtr_func.h
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#ifndef MTR_FUNC_H
+#define MTR_FUNC_H
+
+#include "mbed.h"
+
+/**
+* Funktion zum Setzen des Einschaltzustandes des Schrittmotors.
+* @param einschaltzustand: mtr_state = 0 = aus, mtr_state = 1 = an
+*/
+void mtr_en_set(int mtr_state);
+
+/**
+* Funktion zum Setzen der Drehrichtung des Schrittmotors.
+* @param drehrichtung: 0 = Tisch in -y fahren , 1 = +y fahren
+*/
+void mtr_dir_set(int drehrichtung);
+
+/**
+ * Funktion gibt Periodendauer der PWM [us] zurueck
+ *@return Periodendauer der PWM [us]
+ */
+int mtr_period_get();//
+
+
+/**
+ * Funktion setzt Periodendauer der PWM [us]
+ *@param Periodendauer der PWM [us]
+ */
+void mtr_period_set(int period); 
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 regler.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/regler.cpp	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,116 @@
+/**
+*Funktionen des P-Regleralgorithmus
+*
+*CPP-Datei regler_func.cpp
+*
+*@version: 01.11.2015
+*@author: Gustav Grether & Julian Mueller
+*/
+
+
+#include "regler.h"
+
+//Dateisystem zum speichern der Reglerparameter
+LocalFileSystem local("local");
+
+int regler_sollPx=64; //Sollwerte fuer Kantenpixel
+int e;//Regeldifferenz
+float regler_kp=1.0; //zwischenspeichern Proportinalverstaerkung Regler
+float k0=250.0;//Proportionalverstaerkung Regler bei kp=1.0
+
+float f;//Stellgroesse in Frequenz [Hz]
+float fmax=2500.0; //max. Frequenz [Hz], Stellgroessenbegrenzung
+
+int T;//Stellgroesse als Periodendauer [us]
+int Tmin=floor(1.0/fmax*1000000.0); //Stellgroessenbegrenzung als Periodendauer
+
+void regler_setup()
+{
+    //Einlesen der Reglerparamter aus Dateien
+    //Einlesen des Soll Pixels
+    FILE* inFileSoll = fopen ("/local/sollwert.txt","r");
+    if(inFileSoll!=NULL) {//Datei geoeffnet
+        regler_sollPx = fgetc(inFileSoll);
+    } else {//Datei konnte nicht geoeffnet werden
+        regler_sollPx=64;
+    }
+    if(regler_sollPx<40 || regler_sollPx>90) {
+        //SollPx nicht in realistischem Bereich, evtl. Fehler in Datei
+        regler_sollPx=64;
+    }
+    fclose(inFileSoll);
+
+    //Einlesen von kp
+    FILE* inFilekp = fopen ("/local/kp.txt","r");
+    if(inFileSoll!=NULL) {//Datei geoeffnet
+    fscanf (inFilekp, "%f", &regler_kp);}
+    else {//Datei konnte nicht geoeffnet werden
+        regler_kp=1.0;
+    }
+    if(regler_kp<0.4 || regler_kp>3.0) {
+        //kp nicht in realistischem Bereich, evtl. Fehler in Datei
+        regler_kp=1.0;
+    }
+    
+    fclose(inFilekp);
+}
+
+void regler_end()
+{
+    FILE* outFileSoll = fopen("/local/sollwert.txt","w");
+    fputc(regler_sollPx, outFileSoll);
+    fclose(outFileSoll);
+
+    FILE* outFilekp = fopen("/local/kp.txt","w");
+    fprintf(outFilekp,"%.1f",regler_kp);
+    fclose(outFilekp);
+}
+
+void regler_sollPx_set(int sollPx)
+{
+    regler_sollPx=sollPx;
+}
+
+int regler_sollPx_get()
+{
+    return regler_sollPx;
+}
+
+void regler_kp_set(float kp)
+{
+    regler_kp=kp;
+}
+
+float regler_kp_get()
+{
+    return regler_kp;
+}
+
+
+void control(int edgePx)
+{
+    e=regler_sollPx-edgePx;
+
+    if(e==0) {//keine Motorbewegung
+        if(mtr_period_get()!=0) {
+            T=0;
+            mtr_period_set(T);
+        }
+
+    } else {
+        if(e<0) { //fahre in +y
+            mtr_dir_set(1);
+        } else if(e>0) { //fahre in -y
+            mtr_dir_set(0);
+        }
+        f=k0*regler_kp*abs(e);//Stellgroesse in [Hz]
+
+        if(f>fmax) { //Stellgroessenbegrenzung,maximale Geschwindigkeit
+            T=Tmin;//Stellgroesse in [us]
+            lcd.locate(0,1);
+        } else {
+            T=floor(1.0/f*1000000.0); //Stellgroesse in [us]
+        }
+        mtr_period_set(T);
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r b72d86a7b005 regler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/regler.h	Tue May 31 03:06:27 2016 +0000
@@ -0,0 +1,61 @@
+/**
+*Funktionen des P-Regeleralgorithmus
+*
+*Headerdatei regler_func.h
+*
+*@version: 01.11.2015
+*@author: Gustav Grether
+*/
+
+#ifndef REGLER_H
+#define REGLER_H
+
+#include "mbed.h"
+
+#include "mtr_func.h"
+#include "interface.h"
+
+/**
+ * Funktion muss vor start des Reglers ausgefuehrt werden
+ * liest Reglerparamter aus files aus
+ */
+void regler_setup();
+
+/**
+ * Funktion muss beim beenden des Reglers ausgefuehrt werden
+ * schreibt Reglerparameter in files
+ */
+void regler_end();
+
+/**
+ * Funktion
+ */
+void regler_sollPx_set(int sollPx); //setzt Sollgroesse
+
+/**
+ * Funktion gibt Soll-Pixel zurueck
+ * @return Soll-Pixel
+ */
+int regler_sollPx_get();
+
+/**
+ * Funktion setzt Proportionalitätsfakter kp des Reglers
+ * @param Proportionalitätsfakter kp
+ */
+void regler_kp_set(float kp);
+
+/**
+ * Funktion gibt Proportionalitätsfakter kp des Reglers zurueck
+ * @return Proportionalitätsfakter kp
+ */
+float regler_kp_get();
+
+/**
+ * Funktion berechnet Stellgroesse(Periodendauer PWM) aus dem aktuellen Kantepixel
+ * @param aktuelles Kantenpixel
+ */
+void control(int Px);
+
+
+
+#endif
\ No newline at end of file