Version für den BSW Nottaster - OUT1

Dependencies:   FreescaleIAP MODSERIAL mbed monitor timer0

Fork of 19_Taster_a by Notaus

Revision:
19:f3c41bbc809a
Parent:
18:939d3df56218
Child:
20:b85406f52de3
--- a/main.cpp	Sun Sep 07 12:10:34 2014 +0000
+++ b/main.cpp	Sun May 10 17:59:45 2015 +0000
@@ -1,606 +1,301 @@
-// Version 17 08.08.2014
-// die Ausgabe auf das Format #nr val umgestellt
-// 03.08.14 Monitorbefehle hinzugefügt
-// 08.08.14 Programm um Tropfenerfassung erweitert
-// 30.08.14 die Temperaturbegrenzung bei ausgeschaltert Tropfensteuerung geändert
+// Version 1.0   erstellt am 25.04.2015
+// 01.05.15 den Eingäng 4 auf 2 verlegt
+//          den Eingang 5 auf 1 verlegt
 
 #include "mbed.h"
-#include "ConfigFile.h"
-#include "SDFileSystem.h"
-//#include "DS2482.h"
+#include "main.h"
 #include "timer0.h"
-#include "Buffer.h"
 #include "monitor.h"
-#include "ventiel.h"
 #include "MODSERIAL.h"
 
-#define CR 13
+// timer 2 => optischer Alarm Periode = 500 entspricht Blinkfrequnz von 1 Selunde
+#define OA_PERIODE 500
+// timer 3 => Minimale Zeit für den akustischen Alarm in ms >> soll 10000 entspricht 10 Sekunden
+#define AA_NIN 10000
+// timer 4 => Verzögerung für des Entriegeln des Tasters. In dieser Zeit wird dann kein neuer
+// akustischer Alarm ausgelöst
+#define AA_DELAY 10000
 
-#define SOLL_WERT 32.0          // Sollwert für den Fühler in der Flüssigkeit
-#define R_TEMP_MAX 60.0         // Maximaltermperatur für den Widerstand
-#define R_OFFSET 0.0            // wird bei abgeschaltetert Trofpensteuerung zum Haltetemperatur addiert
-#define OFFSET_0 28330          // AD Wert für 0° Abgleich Kanal 0
-#define OFFSET_1 28560          // AD Wert für 0° Abgleich Kanal 1
-//#define OFFSET 27100          // AD Wert für 0° Abgleich Steuerung Flosrian
-#define GAIN 113                // Digit pro °C  >> 112.3 Steuerung Florian
-//#define GAIN 112.3            // Digit pro °C  >> 112.3 Steuerung Florian
-
-#define BOOL_FMT(bool_expr)  (bool_expr) ? "ein" : "aus"
+#define NEED_CONSOLE_OUTPUT 1   // Set this if you need debug messages on the console
+                                // mit Debug wird die Programmgröße von 32,8k um ca. 300 Byte vergrößert
+                                // dies ist nicht bedeutend, aber auch die Ausführungszeit der Ausgabebefehle
+                                // benötigt CPU Zeit
+#if NEED_CONSOLE_OUTPUT
+  #define DEBUG(...) { pc.printf(__VA_ARGS__); }
+#else
+  #define DEBUG(...)    // nothing
+#endif                  // #if NEED_CONSOLE_OUTPUT 
 
 //------------------------------------------------------------------------------
 // Anlegen von Klassen
 
-SDFileSystem sd(PTD2, PTD3, PTC5, PTD0, "sd");  // The pinout (MOSI, MISO, SCLK, CS)
 timer0 down_timer;                              // Zeitsteuerung
-Serial pc(USBTX, USBRX);                        // tx, rx
-MODSERIAL com(PTC4, PTC3); 
-//MODSERIAL com(PTC4, PTC3);                         
-Buffer <char> buf;                              // Ringbuffer für ankommende Zeichen
-// DS2482 ow(PTE0,PTE1,0x30);                   //        sda, scl, adr
+MODSERIAL pc(USBTX, USBRX);                     // tx, rx
 
-ventiel magnet;                                 // Klasse Ventiele anlegen
-char lcd_text[25];
+monitor mon;
+
 Timer t;                                        // Zeitmessung für Entprellen
 
 //------------------------------------------------------------------------------
 // Zuordnung von Eingängen und Ausgängen
 
-DigitalIn in1(PTA16);
-InterruptIn tropfen(PTA16);                     // Eingang für Tropfensensor >> nur Port A und D
-
-PwmOut heizung(PTA13);                          // Ausgang für den PWM der die Heizung steuert
-
-DigitalOut r(LED_RED);
-DigitalOut g(LED_GREEN);
-DigitalOut b(LED_BLUE);
-
-DigitalOut led1(LED1);
-//DigitalOut LED2(PTA2);
-DigitalOut LED5(PTA4);
-DigitalOut LED_4(PTA12);
-DigitalOut LED6(PTA5);
-
-// Schalter 4051 weden in der Andwendung nicht benötigt           
-DigitalOut DC_A(PTE2);
-DigitalOut DC_B(PTE3);
-DigitalOut DC_C(PTE4);
-DigitalOut DC_EN(PTE5);
+DigitalOut LED(PTE30);
 
-// PT1000 Karte 1 >> Analogeingänge auf der Grundkarte
-AnalogIn an1(PTC0);
-AnalogIn an2(PTB1);
-AnalogIn an3(PTB2);
-AnalogIn an4(PTB3);
-AnalogIn an5(PTC2);
-AnalogIn an6(PTD5);
-
-// 0 bis 5V 
-// AnalogIn an13(PTD6);
+DigitalOut OUT1(PTC6);      // nicht belegt
+DigitalOut OUT2(PTC5);      // LED Rot
+DigitalOut OUT3(PTC4);      // LED Grün
+DigitalOut OUT4(PTC3);      // LED Gelb
+DigitalOut OUT5(PTC2);      // Summer
+DigitalOut OUT6(PTC1);      // Relais
 
-// Analog pins
-/*
-1   PTE20, ADC0_SE0,  0}, k2.2
-2   PTE22, ADC0_SE3,  0}, k2.3
-3   PTE21, ADC0_SE4a, 0},
-4   PTE29, ADC0_SE4b, 0}, k2,4
-5   PTE30, ADC0_SE23, 0}, k2.5
-6   PTE23, ADC0_SE7a, 0},
-7   PTB0,  ADC0_SE8,  0}, k2.1
-8   PTB1,  ADC0_SE9,  0}, k1.2
-9   PTB2,  ADC0_SE12, 0}, k1.3
-10  PTB3,  ADC0_SE13, 0}, k1.4
-11  PTC0,  ADC0_SE14, 0}, k1.1
-12  PTC1,  ADC0_SE15, 0}, k2.6
-13  PTC2,  ADC0_SE11, 0}, k1.5
-14  PTD1,  ADC0_SE5b, 0},
-15  PTD5,  ADC0_SE6b, 0}, k1.6
-16  PTD6,  ADC0_SE7b, 0}, k3.1
-*/
+DigitalIn IN1(PTC7);        // Notaus, schaltet gegen 24V =>            24V oder 1 ist der Ruhezustand
+DigitalIn IN2(PTD4);        // Sabotageschalter, schaltet gegen 24V =>  24V oder 1 ist Ruhezustand
+DigitalIn IN3(PTD5);        // KABA Türöffner Signal =>                 24V oder 1 ist Ruheezustand
+DigitalIn IN4(PTD6);        // nicht belegt                             
+DigitalIn IN5(PTD7);        // nicht belegt 
 
+DigitalInOut rst(PTA4);     //Connect this to the reset pin
 
 //------------------------------------------------------------------------------
 // Globale Variablen
 
-float temp1, temp_mw, temp_r_max, temp_r_ist;
-uint16_t temp_word;
-uint8_t n, y, status, ds1820_status;
-
-int tropfen_anz = 10;       // zulässige Anzahl Tropfen pro Periode
-int tropfperiode = 60;      // in Sekunden
-bool send_flag = true;
-
-float temp_float, temp_diff, temp_neu, esum, temp_soll, regelwert;
-
-
-//------------------------------------------------------------------------------
-// Definitionen und Variablen für das Config File
-ConfigFile cfg;
-char value[BUFSIZ];         // Variablen für das Config file 
-
-bool t_flag = true;         // Heizung aus / ein
-bool f_flag = true;         // Tropfen sperren / freigeben
-
-int drops = 10;             // Anzahl Tropfen pro Zeiteinheit
-
-//float offset = 0.0;
-float soll_wert = 27.0;     // Sollwert für den Temperaturfühler in der Flüssigkeit
-float korr_wert = R_OFFSET; // Korrekturwert bei abgeschalteter Heizung
+bool in;
 
-//------------------------------------------------------------------------------
-// Interruptroutine wird bei jedem Tropfen aufgerufen
-// Pulse die in einem Abstand kleine 1ms sind werden nicht gezählt
-//
-void tropfen_handler()
-{
-    if(t.read_us() > 10000) //falls Tropfen weniger als 1 ms Lichtschranke blockiert, wird er nicht gewertet.
-    {
-        if (in1 == 0)
-        {
-            tropfen_anz++;
-        }
-    }
-    t.reset();
-    t.start();    
-}
-    
-//------------------------------------------------------------------------------
-// Interruptroutine wird bei jedem ankommenden Zeichen aufgerufen
-void rx_handler(void)
-{
-    // Note: you need to actually read from the serial to clear the RX interrupt
-    
-    char ch;
-    
-    while (pc.readable()) 
-    {   
-      ch = pc.getc();
-      buf.put(ch);
-    }
-}
-
-//------------------------------------------------------------------------------
-// lesen der PT1000 AD-Werte
-//
-// Um Störungen zu reduzieren werden 16 Werte gelesen und daraus wird der
-// Mittelwert berechnet. Eine Messung dauert ca. 30µs. Somit wird für eine Messung
-// ca. eine Zeit von 0,5ms benötigt.
-//
-int read_mw(uint8_t pos)
-{
-    uint8_t n;
-    
-    int val = 0;
-    int mw = 0;
-    
-    LED_4 = 0;
-    
-    // 16 Messungen für eine bessere Mittelung durchführen
-    
-    for (n = 0; n < 16; n++)
-    {
-         switch (pos)
-         {      
-            // PT1000 Karte 1
-            case 0:  val = an1.read_u16(); break;
-            case 1:  val = an2.read_u16(); break;
-            case 2:  val = an3.read_u16(); break;
-            case 3:  val = an4.read_u16(); break;
-            case 4:  val = an5.read_u16(); break;
-            case 5:  val = an6.read_u16(); break;         
-         }
-         mw += val;
-    } // end for
-    
-    // Temperatur berechnen
-    // Wert durch 16 teilen
-    
-    mw = mw >> 4;
-    
-    LED_4 = 1;
-    
-    return mw;
-}
+struct di_struct in1;      // Eingang 1
+struct di_struct in2;      // Eingang 2
+struct di_struct in3;      // Eingang 3
 
 //------------------------------------------------------------------------------
 //
 
-int main() 
+int main()
 {
-    //------------------------------------------------------------------------------
-    
-    heizung.period(0.020);          //  requires a 20ms period
-    heizung.pulsewidth(0.005);
-    esum = 0.0;
-    
-    tropfen.fall(&tropfen_handler);
-    t.reset();
-    t.start();
+    rst.input();     // SW watchdog ist derzeit nicht erforderlich
     
     //------------------------------------------------------------------------------
     // RS232 Schnittstellt welche auf den CMSIS-DAP (USB Port) weitergeleitet wird
     //
-    pc.baud(57600);
-    pc.attach(&rx_handler, Serial::RxIrq);
-    pc.printf("\n V08 was compiled on %s  %s \n", __DATE__,__TIME__);
+    pc.baud(115200);
+    pc.printf("\n N1380 V1.0 was compiled on %s  %s \n", __DATE__,__TIME__);
 
-    mon_init();
+
+    //--------------------------------------------------------------------
+    //  Anfangswerte setzen
 
-    //------------------------------------------------------------------------------
-    // RS232 Schnittstellt zum Ansteuern der Magnetventile
-    //
-    com.baud(57600);
-    //com.printf("\n V08 was compiled on %s  %s \n", __DATE__,__TIME__);
-        
-    //------------------------------------------------------------------------------
-    // Timer für die Zeitsteuerung
-    //
-    down_timer.SetCountdownTimer(0,1,50);  // Timer für die LED
-    down_timer.SetCountdownTimer(1,1,500); // Timer für die Tropfensteuerung
-    down_timer.SetCountdownTimer(2,1,1000);// Timer für die Ausgabe der Daten
-    down_timer.SetCountdownTimer(3,1,100); // Timer für Taster
+    in1.old = 1;        // 1 im Ruhezustand
+    in1.aktiv = 0;      
+    in1.filter = 0;
+    in1.optischer_alarm = 0;
+    in1.summer = 0;
     
-    r = g = b = 1;                          // RGB LED ausschalten
+    in2.old = 1;        // 1 im Ruhezustand
+    in2.aktiv = 0;      
+    in2.filter = 0;
+    in2.optischer_alarm = 0;
+    in2.summer = 0;
+
+    in3.old = 1;        // 1 im Ruhezustand
+    in3.aktiv = 0;      
+    in3.filter = 0;
     
     //--------------------------------------------------------------------
-    // Variablen von der SD Karte initialisieren
-    
-    cfg.read("/sd/input.cfg");
- 
-    if (cfg.getValue("t_flag", &value[0], sizeof(value))) 
-    {
-        if (atoi(value) == 1)
-        {
-            t_flag = true;
-            pc.printf("\nHeizung aktiviert");    
-        }
-        else
-        {
-            t_flag = false;
-            pc.printf("\nHeizung deaktiviert");             
-        }
-    }
+    // Softwaretimer für die Zeitsteuerung anlegen
 
-    if (cfg.getValue("f_flag", &value[0], sizeof(value))) 
-    {
-        if (atoi(value) == 1)
-        {
-            f_flag = true;
-            pc.printf("\nTrofen aktiviert");    
-        }
-        else
-        {
-            f_flag = false;
-            pc.printf("\nTropfen deaktiviert");             
-        }
-    }
-
-    if (cfg.getValue("drops", &value[0], sizeof(value))) 
-    {
-        drops = atoi(value);
-        pc.printf("\nAnzahl Tropfen = %d", drops); 
-    }
-
-    if (cfg.getValue("cycle", &value[0], sizeof(value))) 
-    {
-        tropfperiode = atoi(value);
-        pc.printf("\nPeriodenzeit fuer die Tropfen = %d", tropfperiode); 
-    } 
-                     
-    if (cfg.getValue("soll", &value[0], sizeof(value))) 
-    {
-        soll_wert = atof(value);
-        pc.printf("\nsoll_wert = %f", soll_wert); 
-    }
-
-    if (cfg.getValue("korr", &value[0], sizeof(value))) 
-    {
-        korr_wert = atof(value);
-        pc.printf("\nkorrektur_wert = %f\n", korr_wert); 
-    }    
-    //--------------------------------------------------------------------
-    // Anfangswert bestimmen
-    
-    temp_mw = read_mw(0);
-    
+    down_timer.SetCountdownTimer(0,1,500);      // 1 ms Timer * 500 => ergibt 500 ms
+    down_timer.SetCountdownTimer(1,1,10);       // 1 ms Timer * 10 => ergibt 10 ms
+    down_timer.SetCountdownTimer(2,1,0);        // 1 ms Timer => reserviert für optischen Alarm
+    down_timer.SetCountdownTimer(3,1,0);        // 1 ms Timer => reserviert für akustischen Alarm
+    down_timer.SetCountdownTimer(4,1,0);        // 1 ms Timer => reserviert für nach Entriegelung
     
     //--------------------------------------------------------------------
     // Schleife fuer die Datenerfassung
-    
+
     while(1) 
     {
-       //-------------------------------------------
-       // Prüfen ob Zeichen eingegeben wurden
-       
-       get_line();
- 
-       //-------------------------------------------
-       // Prüfen ob Tropfenzahl erreicht
-       
-       
-       if (f_flag)
-       {
-           if (tropfen_anz >= drops){
-           
-                // mit einer 9 die Tropfen sperren
-                if(send_flag){   
-                    // com.putc('9');       // Trofensteuerung wird ausgeschaltet
-                    magnet.reset(0);
-                    send_flag = false;      // Flag zur Programmsteuerung
-                    LED6 = 1;               // zeigt Status Tropfensteuerung aus
-                }
-            }
-       }
-                 
-       //-------------------------------------------
-       // timer 0 steuert die LED
-       
-       if (down_timer.GetTimerStatus(0) == 0)
-       {
-          down_timer.SetCountdownTimer(0,1,500);
-          LED5 = !LED5;
-       }
-       
-       //-------------------------------------------
-       // Tropfensteuerung freigeben
-       // down
-       
-       if (down_timer.GetTimerStatus(1) == 0)
-       {
-          //down_timer.SetCountdownTimer(timer nr,Zeiteinheit: 1 = ms o. 2 = s,tropfperiode);
-          down_timer.SetCountdownTimer(1,2,tropfperiode);
-          
-          //-------------------------------------------
-          // nur freigeben, wenn nicht über monitor gesperrt
-          if (f_flag)
-          {
-              tropfen_anz = 0;
-              
-              // mit einer 1 die Tropfen freigeben
-              if (~send_flag){ 
-                //com.putc('1');         // Tropfensteuerung freigeben von Magnetventil 1
-                magnet.set(0);
-                send_flag=true;          // Flag zum Status der Tropfensteuerung
-                LED6 = 0;                // Anzeige zum Status der Tropfensteuerung
-              }
-          }
-       }
-       
-       //-------------------------------------------
-       // timer 2 steuert das Messen der Temperaturen und gibt die Leistung für
-       // die Heizung vor
-       
-       if (down_timer.GetTimerStatus(2) == 0)
-       {
-            down_timer.SetCountdownTimer(2,1,1000);
+        //-------------------------------------------
+        // Prüfen ob Zeichen eingegeben wurden
+        // wird in der aktiven Version ausgeblendet, ist nur zum Testen
+        
+        mon.get_line();
+
+        //-------------------------------------------
+        // timer 0 steuert die LED auf dem Board mit der Takrate 0,5 Sekunden
+
+        if (down_timer.GetTimerStatus(0) == 0) {
+            down_timer.SetCountdownTimer(0,1,500);
+            LED = !LED;
+            
+        }
+
+        //-------------------------------------------
+        // Eingänge abfragen und Aktionen ableiten
+        // down
+
+        if (down_timer.GetTimerStatus(1) == 0) 
+        {
+            //down_timer 1 mit 10 ms gesetzt
+            down_timer.SetCountdownTimer(1,1,10);
 
-            //------------------------------------------------------
-            // PT1000 Kanal 1 ( Fühler in Flüssigkeit) lesen und die Temperatur berechnen
+            //------------------------------------------------
+            // IN1  Nottaster auswerten, null im Ruhezustand
+            // wird mit der negativen Flanke aktiviert
+            // das Signal muss mindestens 10ms anliegen, damit es akzeptiert wird
         
-           
-           temp_word = read_mw(1);
-           temp_soll = (temp_word - OFFSET_1);
-           temp_soll /= GAIN;
- 
-            //pc.printf("%d;",temp_word);                           // Rohwert ausgeben
-            pc.printf("Soll %2.2f; Soll ist %2.2f;",soll_wert, temp_soll);                     // Temperaturwert soll Flüssigkeit   
+            in = IN1;
             
-            //------------------------------------------------------
-            // PT1000 Kanal 0 ( Fühler am Heizwiderstand ) lesen und die Temperatur berechnen       
             
-            temp_word = read_mw(0);
-            temp_float = (temp_word - OFFSET_0);
-            temp_r_ist = temp_float / GAIN;  
-            
-            //pc.printf("%d;",temp_word);                           // Rohwert ausgeben
-            pc.printf("Temp-R %0.2f; ",temp_r_ist);                     
-            
-            // die Temperaturregelung ist nur bei aktiver Tropfensteuerung eingeschaltet
-            //
-            if (f_flag)
+            if(!in && in1.old)       // Öffner im Ruhezustand 24 V >> durch Drücken wird eine neg. Flanke erzeugt
             {
-                //------------------------------------------------------
-                // Regelabweichung berechnen
-                
-                temp_diff = (soll_wert - temp_soll);
+                in1.old = 0;
+                in1.aktiv = 1;       // Taster ist betätigt
+                in1.optischer_alarm = 1;
+                in1.summer = 1;
+                down_timer.SetCountdownTimer(3,1,AA_NIN);  // Zeit für Softtimer auf 10 Sekunden setzen
+                DEBUG("\n negative Flanke IN1 \n");
+            }
+
+            if (in && !in1.old) {     // Öffner im Ruhenzustand 24 V >> durch Rückstellen enteht eine pos. Flanke
+                in1.old = 1;
+                in1.aktiv = 0;        // Taster ist zurückgesetzt
                 
-                //------------------------------------------------------
-                // Begrenzen der Eingangsgröße
-                         
-                if(temp_diff > soll_wert)temp_diff = soll_wert;
-                    
-                //temp_neu = ((temp_diff*0.0005) + (temp_alt*0.9));
-     
-                //------------------------------------------------------
-                // bei geringen Abweichungen ein I-Anteil berechnen, damit Regelabweichung
-                // auf 0 gefahren werden 
-                if(temp_diff < 3){
-                    esum += temp_diff * 0.00001;
-                }
-                
-                //------------------------------------------------------
-                // berechnen der Steuergröße
-                
-                temp_neu = (temp_diff*0.0005) + esum;
-                
-                //------------------------------------------------------
-                // Regler nach oben begrezen
-                
-                if(temp_neu > 0.02){
-                    temp_neu = 0.02;
-                }            
-     
-                //------------------------------------------------------
-                // Regler nach unten begrezen       
-                
-                if(temp_soll > soll_wert){
-                    temp_neu = 0.0;
-                    esum = 0.0;
-                }
-                
+                in1.summer = 0;
+                down_timer.SetCountdownTimer(4,1,AA_DELAY);  // Zeit für Entriegelung, Haube innerhalb von 10 Sekunden schließen
+                DEBUG("\n positve Flanke IN1 \n");
             }
             
-            regelwert = temp_neu;
-            
-            //------------------------------------------------------
-            // Zulässige Temperatur für den Heizwiderstand begrezen            
-            // bei eingeschalteter Trofensteuerung wird die Temperatur 
-            // auf T_TEMP_MAX und bei ausgeschalteter Tropfensteuerung 
-            // auf soll_wert begrenzt
-            if (f_flag)
-            {
-                temp_r_max = R_TEMP_MAX;
-            }
-            else
-            {                
-                temp_r_max = soll_wert + korr_wert;
-            }                
-                
-            if(temp_float > temp_r_max)
+            // optischer Alarm ausschalten, wenn IN3 wieder 0 bekommt ==> Quittierung
+
+            if (in1.optischer_alarm && in3.aktiv) 
             {
-                    regelwert = 0.0;
-                    esum = 0.0;
-            }
- 
-            //------------------------------------------------------
-            // Heizwiederstand ansteuern >> 0,02 entspricht 100%
-            
-            if (t_flag)
-            {
-                heizung.pulsewidth(0.0001 + regelwert);
-                //pc.printf("%0.4f;",temp_alt);
-            }
-            else
-            {
-                heizung.pulsewidth(0.000000);      
-            }
-            pc.printf("%0.4f; ",temp_neu); 
-            if(t_flag)
-            pc.printf("on;");
-            else
-            pc.printf("off;");
-            pc.printf(" %d; Magnete :", tropfen_anz);
-            
-            for (uint8_t n = 0; n < 8; n++)
-            {
-                if(magnet.get(n)) pc.putc('1');
-                else              pc.putc('0');              
+                in1.optischer_alarm = 0;
+                DEBUG("\n IN1 mit IN3 quittiert \n");
             }
 
-            pc.printf("; verbleibende Zeit %02d; ",down_timer.GetTimerZeit(1));
-            
-            if(f_flag)
-            pc.printf("on;");
-            else
-            pc.printf("off;");
-            
-            pc.printf("\n");
+
+            //------------------------------------------------
+            // IN2 Sabotageschalter, 24V ist Ruhezustand
+            // wird mit der negativen Flanke aktiviert
+            // das Signal muss mindestens 10ms anliegen, damit es akzeptiert wird
             
-            // LCD String zusammensetzen und ausgeben
-            for (int i = 0; i < 25; i++) lcd_text[i] = 0;
-                            //01234567890123456789
-            sprintf(lcd_text,"TR   %3.1f  /  %3.1f ",temp_r_ist,temp_r_max);
-            //sprintf(lcd_text,"erste Zeile");
-            uint8_t len = strlen(lcd_text);
-            uint8_t anz = len + 3;
-            com.printf(":AA%02x020000",anz);    //Zeile 1 Temps
-            for (int i = 0; i < len; i++)
-            {
-               com.printf("%02x",lcd_text[i]); 
-            }
-            com.printf("A5\n");
-            //wait_ms(100);
+            in = IN2;
             
             
-            for (int i = 0; i < 25; i++) lcd_text[i] = 0;
-                            //01234567890123456789
-            sprintf(lcd_text,"TK   %3.1f  /  %3.1f ",temp_soll,soll_wert);
-            //sprintf(lcd_text,"Heizung         %s " ,BOOL_FMT(t_flag));
-            len = strlen(lcd_text);
-            anz = len + 3;
-            com.printf(":AA%02x020001",anz);    //Zeile 2 Heizung (ein/aus)
-            for (int i = 0; i < len; i++)
-            {
-               com.printf("%02x",lcd_text[i]); 
+            if(!in && in2.old)          // Eingang neg. Flanke
+            {    
+                in2.old = 0;            // 0 im aktivierten Modus
+                in2.aktiv = 1;          // Eingang ist aktiv
+                in2.optischer_alarm = 1;
+                in2.summer = 1;
+                down_timer.SetCountdownTimer(3,1,AA_NIN);  // Zeit für Softtimer auf 10 Sekunden setzen
+                DEBUG("\n negative Flanke IN2 \n");
             }
-            com.printf("A5\n");
-            //wait_ms(100);
-             
-            for (int i = 0; i < 25; i++) lcd_text[i] = 0;
-                            //01234567890123456789
-            sprintf(lcd_text,"temp. %s  flow %s ",BOOL_FMT(t_flag) ,BOOL_FMT(f_flag));
-            len = strlen(lcd_text);
-            anz = len + 3;
-            com.printf(":AA%02x020002",anz);    //Zeile 3 Tropfensteuerung (ein/aus)
-            for (int i = 0; i < len; i++)
-            {
-               com.printf("%02x",lcd_text[i]); 
+
+            if (in && !in2.old)         // Eingang mit pos. Flanke
+            {    
+                in2.old = 1;            // 1 im Ruhezustand   
+                in2.aktiv = 0;          // Eingang ist inaktiv
+                in2.summer = 0;
+                DEBUG("\n positve Flanke IN2 \n");
             }
-            com.printf("A5\n");
-            //wait_ms(100);
-            
-            for (int i = 0; i < 25; i++) lcd_text[i] = 0;
-                            //01234567890123456789
-            sprintf(lcd_text,"Zeit %3d Tropfen %3d" ,down_timer.GetTimerZeit(1),tropfen_anz);
-            len = strlen(lcd_text);
-            anz = len + 3;
-            com.printf(":AA%02x020003",anz);    //Zeile 4 Anz. Zeit+Tropfen
-            for (int i = 0; i < len; i++)
+
+            if (in2.aktiv && !in2.summer && !in1.summer && (down_timer.GetTimerStatus(4) == 0))
             {
-               com.printf("%02x",lcd_text[i]); 
+                in2.summer = 1; 
+                down_timer.SetCountdownTimer(3,1,AA_NIN);  // Zeit für Softtimer auf 10 Sekunden setzen ( zum Testen auf 2 Sek. gesetzt )  
+                DEBUG("\n IN2 Summer aktiviert \n");
             }
-            com.printf("A5\n");
-            //wait_ms(100);
-            
-       } // end if(down_timer ...
             
-    
-    // timer 3
-       
+            // nur zurückschalten, wenn IN3 wieder 1 ==> Quittierung
+
+            if (in2.optischer_alarm && in3.aktiv) {
+                in2.optischer_alarm = 0;
+                DEBUG("\n IN2 mit IN3 quittiert \n");
+            }
 
-       
-            if (com.readable()) {
-            
-            int ch = com.getc();
-            // pc.printf("\nzeichen=%c %x",ch,ch);
-            
-            switch (ch){
-                case '1': magnet.toggle (0);
-                break;
-                case '2': magnet.toggle (1);
-                break;
-                case '3': magnet.toggle (2);
-                break;
-                case '4': magnet.toggle (3);
-                break;
-                case '5': if (t_flag)
-                {
-                     t_flag = false; 
-                     pc.printf("\nHeizung durch externen Taster deaktiviert\n");
-                }    
-                else 
-                {
-                    t_flag = true;
-                    pc.printf("\nHeizung durch externen Tastet aktiviert\n");
-                }
-                break;
-                case '6': if (f_flag)
-                {
-                     f_flag = false;
-                     pc.printf("\nTropfensteuerung durch externen Taster deaktiviert\n");
-                }
-                      else
-                {     
-                       f_flag = true;
-                       pc.printf("\nTropfensteuerung durch externen Taster aktiviert\n");
-                }
-                break;
-                }
+            //------------------------------------------------
+            // IN3 Signalstation, Öffner => 1 ist Ruheezustand
+
+            in = IN3;
+
+            if(in && !in3.old)        // Eingang pos. Flanke
+            {   
+                in3.old = 1;
+                in3.aktiv = 0;        // Eingang ist Ruhezustand
                 
             }
+
+            if (!in && in3.old)       // Eingang mit neg Flanke
+            {
+                in3.old = 0;
+                in3.aktiv = 1;        // Eingang ist aktiv    
+            }
+
+
+            //---------------------------------------------------------------------------------------------------------------------------------------
+            // Die Eingänge sind nun gelesen, jetzt kommt das Steuern der Ausgaänge
+            //
             
-       
-       
-                           
+            //------------------------------------------------
+            // Rot/Grüne LED (verriegelt/entriegelt):
+            // rot      Tor ist verriegelt
+            // grün     Tor ist entriegelt
+
+            //  1. IN3 auf 1 = OUT2 ein und OUT3 aus   Rot an / Grün aus   (verriegelt)
+            
+            if(!in3.aktiv) {   
+                OUT2 = LED_EIN;
+                OUT3 = LED_AUS;
+            } 
+            
+            //  2. IN3 auf 0 = OUT2 aus und OUT3 ein   Rot aus / Grün an   (entriegelt)
+            //  3. IN1 auf 1 = OUT2 aus und OUT3 ein   Rot aus / Grün an   (entriegelt)
+            
+            if (in3.aktiv || in1.aktiv) {          
+                OUT2 = LED_AUS;
+                OUT3 = LED_EIN;
+            }
+            
+            //------------------------------------------------
+            //  Gelbe LED (optischer Alarm):
+
+            if (in1.optischer_alarm || in2.optischer_alarm)  // sobald der optische Alarm aus Eingang 1 oder Eingang 2 akiviert wurde, diesen in Blinkmode schalten
+            {    
+                if (down_timer.GetTimerStatus(2) == 0) 
+                {
+                    down_timer.SetCountdownTimer(2,1,OA_PERIODE);  // Zeit für Softtimer auf eine Sekunde setzen
+                    OUT4 = !OUT4;
+                }
+            } 
+            else 
+            {
+                OUT4 = LED_AUS;
+            }
+
+            //------------------------------------------------
+            // Summer (OUT5 +24V)
+
+            if (in1.summer || in2.summer || (down_timer.GetTimerStatus(3) != 0))  // sobald der Eingang 1 oder Eingang 2 akiviert ist oder der Timer
+            {                                                                     // noch aktiv ist, den Summer aktivieren
+                OUT5 = 1;
+            } 
+            else 
+            {
+                OUT5 = 0;
+            }
+            
+            //------------------------------------------------
+            // Relais K1:
+            // Der Kontakt des Nottasters wird weitergegeben
+
+            if (in1.aktiv) {  // 1.  IN1 auf 0 = OUT6 (K1) ein
+                OUT6 = 0;
+            } else {          // 2.  IN1 auf 1 = OUT6 aus
+                OUT6 = 1;
+            }
+
+        } // end if (downtimer ...
+        
     } // end while
-}
 
+} // end main
+