[Code] Prozessüberwachung mit Controller

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von $-K!NG, 16. Dezember 2008 .

Schlagworte:
  1. 16. Dezember 2008
    Prozessüberwachung mit Controller

    Hey Leute, könnt ihr mir bei einem kleinen Problem helfen?
    Ich habe folgendes Problem:
    Eine Prozessüberwachung soll mit einem Controller überwacht werden. Sie hat insgesammt vier Eingänge, je Eingang eine Meldegruppe, welche eine Störung mittels LED's ausgibt.
    So, nun muss der Controller so programmiert werden, dass es die Störung auf einem Display ausgibt.
    Wenn auf den Meldern keine Störung vorliegt, soll der Controller eine Ruhe Meldung ausgeben. Sobald jedoch eine Störung anliegt. Soll es die Meldegruppe anzeigen und eine Handlung anweisen, solange bis die Störung nicht behoben wurde und eine "Reset"-Taste gedrückt worden ist.
    Die Eingänge werden über einen Port des Controllers abgefragt, welches über eine Switch-Case-Funktion geschieht.
    Gibt es eine Möglichkeit, ohne schleifen, sondern nur mit if-Bedingungen ein Festhalten in einer Case zu definieren?
    Hier ist der Auszug der Switch-Case-Funktion, welche schon einigermassen funktioniert, jedoch glaube ich, dass es auch eine einfachere Lösung gibt.
    Gibt es hier paar Spezies, welche ahnung von solchen Dingen haben und mir eine kleinen Rat geben könnten, es einfacher gestalten zu können?


    Code:
    switch (aktDatenwort) //Einlesen des PORTs
    {
     case 0x00: lcd_cls();
     lcd_PrintText(1,1,"Schnittstellenfehler");
     break;
     
     //Meldung, wenn kein Fehler vorliegt
     case 0x41: if (!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     }
     break;
     
     case 0x42: if (!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     }
     break;
     
     case 0x44: if (!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     }
     break;
     
     case 0x48: if (!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     }
     break;
    
     //Alarmmeldungen bei Überlast
     case 0x21: aktAlarmStatus=aktAlarmStatus|0x01;
     if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 1 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
     
     case 0x22: aktAlarmStatus=aktAlarmStatus|0x02;
     if(!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 2 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
    
     case 0x24: aktAlarmStatus=aktAlarmStatus|0x04;
     if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 3 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
    
     case 0x28: aktAlarmStatus=aktAlarmStatus|0x08;
     if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x01))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 4 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
     }
    }
     
  2. 16. Dezember 2008
    AW: Prozessüberwachung mit Controller

    So, nu denn:

    • Was ist denn "aktDatenwort"?
    • Was ist "aktAlarmStatus" ?
    • Sollen wir nur den Code vereinfachen? Oder bei was sollen wir dir denn genau helfen?

    jaja, ich weiß... ich frage gerne tiefer nach.

    - - -
    Tanya
     
  3. 16. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Also:
    • aktDatenwort ist die Variable, die abgefragt wird, für das Einlesen vom PORT, an welchem die Prozessüberwachung die Daten hin schickt.
    • aktAlarmStatus wird als Variable für die If genutzt, welche Maskiert wird, damit die If bei einer bestimmten Bedingung aus der Case rausgeht und in einer Case bleibt.
    • Es währe nett, wenn ihr mir die If bedingung vereinfachen oder mir eine möglichkeit nennen könntet, ohne eine schleife, also do oder while, damit er die Case so lange hält, bis eine Taste gedrückt wird.
    Die genaue Taste habe ich in der Main definiert. Ich brauche nur einen Halter mit einer If Funktion...
     
  4. 16. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Ich möchte anmerken, dass dieser Satz keinen Sinn ergibt.

    Des Weiteren möchte ich dich Fragen, ob wir nun aus der Case rausgehen, oder doch drinnen bleiben?! (-> Sinn!!)

    WÄRE bitte ohne H!
    Du musst auf jeden Fall eine Schleife einbauen, da eine Eingabe nur für kurze Zeit kommt - und dein Programm ein "wenig" schneller sein wird. Ich gehe jetzt einfach einmal davon aus, dass der CODE hier nur eine Unterfunktion ist, die aufgerufen wird wenn eine Taste gedrückt wurde.
    Code:
    while(true)
    {
     leseEingabe();
     sleep( einigeZeit );
    }
    
    Mit IF kannst du nichts anhalten! Wenn dein Programm bei der IF-Abfrage ankommt, dann werden die Daten dementsprechend abgefragt, verglichen und es wird ein Ergebnis gefällt (true, false). Dann geht's sofort mit dem nächsten Codefragment weiter (!).



    Soweit ich das jetzt verstanden habe:
    1. Es wird eine Taste gedrückt
    2. Du prüfst den Wert dieser Taste (wenn korrekt, dann wird etwas getan)
    3. Dann wird der Status der Prozessüberwachung abgefragt
    4. Und dementsprechend eine Displayausgabe geschrieben

    Ich würde dir gerne weiterhelfen, aber ich habe noch immer keinen genauen Durchblick, was du eigentlich machst. Und aus deinem Code werde ich auch nicht schlau.

    - - -
    Tanya
     
  5. 17. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Es ist folgendermassen. Es handelt hier um einen Microcontroller. Er ist an einem Sensor angeschlossen, zur Simulation werden öffner genutzt (die beschriebenen Meldegruppen). Du musst dir zwei Baugruppen vorstellen, einen Controller und eine Prozessüberwachung, an der die öffner angeschlossen werden. Wenn ein öffner auslöst, sendet er ein Signal an den Microcontroller, über einen PORT. Dieser PORT wird, da die Prozessüberwachung sändig die Datenleitungen abfragt in einer anderen Funktion verglichen, damit man eindeutige Zustände hat. Daher auch aktDatenwort.
    So, nun zum Code:
    Code:
    switch (aktDatenwort) //Einlesen vom PORT
    {
     //Wenn kein Fehler vorliegt hat der PORT die Zustände: 0x41, 0x42,0x44 und 0x48
     //Diese Zustände sind, wenn alle Öffner geschlossen sind.
     case 0x41: if (!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
    //Hier soll das Programm solange die Ausgabe machen, bis sich der Wert am PORT nicht ändert.
    //Solange aktAlarmStatus nicht 0x01 und nicht 0x02 und nicht 0x04 und nicht 0x08
    //gib aus:
     {
     lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     }
     break;
    //Das ganze wird vier mal gemacht, da es für jeden Schalter eine eigene Datenleitung gibt und
    //unabhängig von den anderen Abgefragt werden kann.
    //Wenn nun einer der Schalter auslöst, welche die die Zustände 0x21 (S1),0x22(S2),0x24(S3) und 0x28(S4)
    //haben, soll sich die Meldung ändern. 
    
    //Alarmmeldungen bei Überlast
    //Wenn z.B. der erste Schalter auslöst, soll aktAlarmStatus auf 0x01 gesetzt werden, somit springt
    //er aus der Abfrage heraus und geht in die Case, wo der Fehler angezeigt wird. 
     case 0x21: aktAlarmStatus=aktAlarmStatus|0x01;
     
    //Und das soll er nun solange machen, solange aktAlarmStatus nicht 0x02 und nicht 0x04 und nicht 0x08 
    //Das soll so lange gezeigt werden, bis der Fehler nicht behoben wird und ein Reset-Taster gedrückt wird. 
    //Meine Frage bezieht sich hier rauf: Ist es möglich diese if-Abragen zu verkürzen? 
     if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 1 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
    
    Also, besser könnte ich es nicht erklären.
    Das Problem ist, wenn man eine do-while-Schleife einbaut, verhart er in einem Zustand, somit ist es nur schwer möglich es so umzuschreiben, dass er gleichzeitig in einem Zustand ist und gleichzeitig die anderen Schalter abfragt.

    Ich weiß, es ist recht Schwer ein Program zu erklären -.-* Und Schuldige, wenn ich mich unklar ausdrücke oder ein Rechtschreibfehler mache.
     
  6. 17. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Demzufolge:

    Du prüfst ob (von rechts zu lesen, angefangen bei 0) Bit 1 nicht gesetzt, Bit 2 nicht gesetzt und Bit 3 nicht gesetzt.
    D.h. es ist eigentlich nur erlaubt diese Ausgabe zu machen, wenn der Wert von
    aktAlarmStatus = (binär) 0001 ist.
    Code:
    if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
    -> if (aktAlarmStatus | 0x01 == 0x01 )
    

    Des Weiteren habe ich deinen Code ein wenig umgebaut:
    Code:
    switch (aktDatenwort) //Einlesen des PORTs
    {
     //Meldung, wenn kein Fehler vorliegt
     // bei 41,42,44 und 48 wird jeweils das SELBE getan... also schreib es folgendermaßen:
     case 0x41:
     case 0x42:
     case 0x44:
     case 0x48:
     if (aktAlarmStatus | 0x00 == 0x00)
     {
     lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     }
     break;
     
     //Alarmmeldungen bei Überlast
     case 0x21: 
     aktAlarmStatus = aktAlarmStatus | 0x01;
     if (aktAlarmStatus | 0x01 == 0x01 )
     //if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 1 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
     
     case 0x22: 
     aktAlarmStatus = aktAlarmStatus | 0x02;
     if (aktAlarmStatus | 0x02 == 0x02 )
     //if(!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 2 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
    
     case 0x24: 
     aktAlarmStatus = aktAlarmStatus | 0x04;
     if (aktAlarmStatus | 0x04 == 0x04 )
     //if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 3 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
    
     case 0x28: 
     aktAlarmStatus = aktAlarmStatus | 0x08;
     if (aktAlarmStatus | 0x08 == 0x08 )
     //if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x01))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 4 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
     
     // es sollte ein DEFAULT existieren! Und dieser soll betreten 
     // werden, wenn irgendein unbekannter Wert auftritt - nicht nur bei NULL (0)
     default: 
     lcd_cls();
     lcd_PrintText(1,1,"Schnittstellenfehler");
     // und es wäre sinnvoll, den Fehler auch durch die Nummer zu verdeutlichen:
     lcd_PrintText(2,1, konvertiere_integer_zu_string(aktDatenwort) );
     break;
     
     }
    }
    

    Ich hoffe es hilft bis dato.
     
  7. 17. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Du hast es fast! Also, das Programm läuft...
    Die Prozessüberwachung läuft ständig, die Messgruppen ab. Somit ist der Wert von 0x21 bis 0x28 nicht konstant, er wechselt alle 400ms. Somit geht er z.B. wenn 0x21 auslöst in 0x22 bis 0x28 rein, obwohl nur eine Meldegruppe ausgelöst ist. Deswegen soll es auch in einer Case stehen bleiben.

    Aber ich finde es schon mal gut, dass du mir 2 Sachen gezeigt hast, die ich bislang noch nicht kannte, die möglich sind und dass du mein Problem soweit analysiert hast.

    Ich schätze mal, dass ich doch die Lösung mit einer do-while bevorzuge, ist einfacher und der Controller reagiert schneller.

    Er führt ja eine Case so lange aus, bis die Quit-Taste gedrückt wird.
    Das heißt, dass er nur einen Zustand haben kann. Was ist jedoch, wenn zwei Meldegruppen auslösen?
    Wenn ich es mit einer while oder do-while mache, bleibt er ja in einer Case stehen. Wie könnte man es lösen, dass er auch mehrere Meldegruppen anzeigt.
    Sprich z.B. Meldegruppe 1 & MG2 lösen aus. Nun soll der mir sowohl die Case von 0x21 und 0x22 darstellen. Würde es mit einer If gelöst werden können?
    z.B:
    Code:
    if (aktDatenwort 0x21 && 0x22) 
    {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppen 1u. 2 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
    }
    
    Hier mein aktueller Code, mit do-while:

    Code:
    switch (aktDatenwort)
     {
     case 0x00: lcd_cls(); //LCD-Löschen
     lcd_PrintText(1,1,"Schnittstellenfehler");
     break;
     
     //Displayausgabe, wenn kein Fehler vorliegt
     case 0x41: lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     break;
     
     
     //Alarmmeldungen bei Überlast
     case 0x21: do //Wenn Meldegruppe 1 auslöst
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 1 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     while (!io_key_OK()); //Solange nicht die Quit-Taste gedrückt wird
     break;
     
     case 0x22: do //Wenn Meldegruppe 2 auslöst
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 2 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     while (!io_key_OK()); //Solange nicht die Quit-Taste gedrückt wird
     break;
    
     case 0x24: do //Wenn Meldegruppe 3 auslöst
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 3 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     while (!io_key_OK()); //Solange nicht die Quit-Taste gedrückt wird
     break;
    
     case 0x28: do //Wenn Meldegruppe 4 auslöst
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 4 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     while (!io_key_OK()); //Solange nicht die Quit-Taste gedrückt wird
     break;
     }
    }
    
    
     
  8. 17. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Diesen Satz sollltest du bitte nochmal umschreiben - ich verstehe ihn nicht

    Warum schreibst du auch die ganze Zeit dieselben Informationen auf das Display? Soweit ich weiß, zeigt jedes Display die zuletzt übergebenen Daten an. Wenn du dann nochmal kommst, und den gleichen Text hinschreibst... warum bitte?
    Mach's doch so:
    Code:
    //Wenn Meldegruppe 1 auslöst
    
    // Text (nur 1x) rausschreiben
    lcd_PrintText(1,1," VORSICHT!!! ");
    lcd_PrintText(2,1," Meldegruppe 1 ");
    lcd_PrintText(3,1," Überbelastet ");
    lcd_PrintText(4,1,"Portalkran anhalten!");
    
    // Warten, solange nicht die Quit-Taste gedrückt wird
    while (!io_key_OK())
     usleep(1); 
     // oder wie auch immer ein "Schlaf"-Befehl bei dir heißt
     // oder du nimmst einen __asm{ nop }. Dann "dreht" sich 
     // der uC nicht mit seinen paar Mhz im Kreis ;)
    

    Und meine Frage bleibt: Hä?
     
  9. 17. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Hab mir das ganze durchgelessen und wie ich das verstehe wilst du,

    dass bei keinem Fehlern (Rückgabewert 0x4X [0x41, 0x42, 0x44, 0x48]) die Meldung "..Belastung Normal.." angezeigt wird

    und bei einem oder mehreren Fehler (Rückgabewert 0x2X [0x21, 0x22, 0x24, 0x28] die einzelnen
    Fehler solange nacheindander Angezeigt werden bis der Benutzter die Quit-Taste drückt.



    Hab hier ein Code zussamengeschrieben der dir vielleicht hilft das Problem zulössen, jedoch ohne jegliche SWITCH bzw. CASE
    verzweigung sondern nur durch IF-Abfragen....


    Aber davor übernahme der Logik von anderen Systemen:
    {0x21, 0x22, 0x24, 0x28} = {Fehler 1, Fehler 2, Fehler 3, Fehler 4}
    {0x01, 0x02, 0x04, 0x08} = {Fehler 1, Fehler 2, Fehler 3, Fehler 4}
    {0001, 0010, 0100, 1000} ={Fehler 1, Fehler 2, Fehler 3, Fehler 4}

    Jetzt wird aber bei mehreren Fehlern zb dieser Code übergeben:
    0101 (0x05)-> dh der Fehler 1 und der Fehler 3 sind aufgetreten
    1011 (0x0B)-> dh der Fehler 1, der Fehler 2 und Fehler 4 sind aufgetreten
    usw....


    Zur Praxis und dem Code:
    Code:
     [COLOR="Blue"]if [/COLOR]((aktDatenwort & 0xF0) == 0x40) [COLOR="DarkGreen"]// Keine Fehle[/COLOR]r
     {
     [COLOR="DarkGreen"]//Displayausgabe, wenn kein Fehler vorliegt[/COLOR]
     lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     }
     [COLOR="Blue"]else[/COLOR]
     [COLOR="Blue"]if [/COLOR]((aktDatenwort & 0xF0) == 0x20) [COLOR="DarkGreen"]// Alarmmeldungen: Prüfen und Anzeigen der Medlungen[/COLOR]
     { 
     [COLOR="Blue"]if [/COLOR]((aktDatenwort & 0x01) == 0x01)
     [COLOR="Blue"]do [/COLOR][COLOR="DarkGreen"]//Wenn Meldegruppe 1 auslöst[/COLOR]
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 1 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     [COLOR="Blue"]while [/COLOR](!io_key_OK()); /[COLOR="DarkGreen"]/Solange nicht die Quit-Taste [/COLOR]
    
     [COLOR="Blue"]if [/COLOR]((aktDatenwort & 0x02) == 0x02)
     [COLOR="Blue"]do [/COLOR][COLOR="DarkGreen"]//Wenn Meldegruppe 2 auslöst[/COLOR]
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 2 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     [COLOR="Blue"]while [/COLOR](!io_key_OK()); [COLOR="DarkGreen"]//Solange nicht die Quit-Taste[/COLOR]
    
     [COLOR="Blue"]if [/COLOR]((aktDatenwort & 0x04) == 0x04)
     [COLOR="Blue"]do [/COLOR][COLOR="DarkGreen"]//Wenn Meldegruppe 3 auslöst[/COLOR]
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 3 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     [COLOR="Blue"]while [/COLOR](!io_key_OK()); [COLOR="DarkGreen"]//Solange nicht die Quit-Taste[/COLOR]
    
     [COLOR="Blue"]if [/COLOR]((aktDatenwort & 0x08) == 0x08)
     [COLOR="Blue"]do [/COLOR][COLOR="DarkGreen"]//Wenn Meldegruppe 4 auslöst[/COLOR]
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 4 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     [COLOR="Blue"]while [/COLOR](!io_key_OK()); [COLOR="DarkGreen"]//Solange nicht die Quit-Taste [/COLOR]
     }
    
    [COLOR="Red"]//mit Fehlercode
     else
     {
     //Schnittstellenfehler Anzeigen
     char chr[21];
     sprintf(chr, "0x%.2x ", aktDatenwort);
    
     lcd_cls(); 
     lcd_PrintText(1,1,"Schnittstellenfehler");
     lcd_PrintText(2,1,"Unbekannter Code: ");
     lcd_PrintText(3,1, chr);
     }[/COLOR]
    
    [COLOR="Blue"]//oder ohne Fehlercode
     else
     {
     //Schnittstellenfehler Anzeigen
     lcd_cls(); 
     lcd_PrintText(1,1,"Schnittstellenfehler");
     }
    [/COLOR]

    Mfg Rushh0ur
     
  10. 18. Dezember 2008
    AW: Prozessüberwachung mit Controller


    Du bist ein Genie! Der Programmcode funkioniert und du hast mein Problem verstanden und sogar einen funktionsfähigen Code daraus gemacht, der einfach und simple zu verstehen ist!
    Ich danke dir!
    Aber, wie sieht es nun mit mehreren Fehlern aus? Ich habe es getestet. Ich habe eine If kopiert und statt 0x01, 0x05 eingefügt (1 und 3 offen), es passiert nichts, da 1 oder 3 eher öffnen, nicht zeitgleich! Das ist das große Problem! Die Abfrage für jeden Port, also 0x21 ... 0x28 wird alle 200uS nacheinander abgefragt.

    Ich sage ihm ja, sobald er in die Schleife geht, dass er die anderen Zustände ignorieren soll, bis nicht die "Reset"-Taste gedrückt wird...
    Gibt es keine Lösung ohne eine schleifen bedingung?
    Anscheinend ist es doch nicht so einfach, mehrere Schalter abzufragen...
     
  11. 18. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Ich verstehe nicht ganz, du möchtest das der Display bei Fehlern, die Fehler nach einander
    (in einem Zeitinterval?) auf dem Display anzeigt und dabei prüft ob der Status der Fehler
    Meldungen sich verändert und dem entsprechend auch die Fehlermeldungen ausgibt und bei
    einem Tastendruck auf "Reset" bzw. bei keinen Fehlern wieder auf die Standartanzeige zurück kehrt.

    Du sagst das die Abfrage alle 200us passiert dann würde ich das ganze auch alle "200us" in einer
    Schleife abfragen und auch je nach Status die Anzeige verändern lassen.

    Mfg Rushh0ur
     
  12. 18. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Nope, die Prozessüberwachung fragt alle 200µS die Zustände der Datenleitung ab.

    Also, die Aufgabe lautet:
    Bei einer Prozessüberwachung sollen Sensoren abgefragt werden.
    Über einen Microcontroller werden sie überwacht. Sobald einer der Sensoren etwas ausgibt, soll auf dem Display eine Fehlermeldung und die Adresse angezeigt werden. Ansonsten eine Ruhe meldung.
    Diese Meldung soll so lange bleiben, bis über eine "Quit"-Taste resetet wird.

    Ich mache es mit einer Do-While, doch mein Lehrer meint, dass der Controller in der Schleife hängen bleibt, was ja nicht allzu falsch ist.
    Und deswegen ist es nicht die richtige Programmierart.
     
  13. 18. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Ahso du willst die jeweiligen do-while scheifen
    durch einen Resourcenschonendencode ersetzen
    sodass nicht ständig neue Anzeigedaten an den Controller gesendet werden....

    Leider geht das nicht ohne Controler Interrupts die auf Tastendruck reagieren
    (was genau das ist, gehe ich nicht weiter ein...), dh. an einer Scheife kommst du
    nicht rum, denoch kann man den Code Resourcenschonender gestaltten.

    Mann sendet die Anzeigedaten einfach einmal und fragt dann nur noch in einer Schleife
    den Tastendruck ab und setz dabei einen Abfrageinterval, sodass dann halt nur zb. alle 100ms
    prüft ob die "Quit"-Taste gedrückt ist/wurde.

    Code:
    [COLOR="Blue"]if [/COLOR]((aktDatenwort & 0x01) == 0x01) [COLOR="Green"]//Wenn Meldegruppe 1 auslöst[/COLOR]
    {
     [COLOR="Green"]// Neue Anzeigedaten Senden[/COLOR]
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 1 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     
     [COLOR="Blue"]while [/COLOR](!io_key_OK()) [COLOR="Red"]Sleep(200);[/COLOR] [COLOR="Green"]//Solange nicht die Quit-Taste; Abfrage in 200ms Takt [/COLOR]
    }
    
    Ich weiß jetzt nicht genau unter welchen Vorraussetzungen du Programmierst und deswegen
    könnte der rotgeschriebene Befehl nicht verfügbar sein und du evtl. einen änlichen für deine
    Umgebung suchen müsstest.

    Desweitern könnte es sein dass der Micro kontroller auch einen indirekten Interruptbefhel hat
    der durch das Aufrufen das Programm solange anhält bis eine Bestimmte Teste gedrückt wurde.

    Mfg Rushh0ur
     
  14. 18. Dezember 2008
    AW: Prozessüberwachung mit Controller

    Also gehst du auch davon aus, dass die Lösung mit einer do-while Schleife die einfachere Variante währe. Er meint, man müsste es folgender Weise machen:

    Das hier sind nur Auszüge, von einem Ruhe-Zustand und einem Alarm-Zustand, zur veranschaulichung.

    Code:
    switch (aktDatenwort) //Einlesen des PORTs
    { 
     //Meldung, wenn kein Fehler vorliegt
     case 0x41: if (!(aktAlarmStatus&0x01)&&!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1,"PÜS-Überlastanzeige ");
     lcd_PrintText(2,1," Meldegruppen 1-4 ");
     lcd_PrintText(3,1," Belastung Normal ");
     lcd_PrintText(4,1," ");
     }
     break;
    
    
    //Alarmmeldungen bei Überlast
     case 0x21: aktAlarmStatus=aktAlarmStatus|0x01;
     if(!(aktAlarmStatus&0x02)&&!(aktAlarmStatus&0x04)&&!(aktAlarmStatus&0x08 ))
     {
     lcd_PrintText(1,1," VORSICHT!!! ");
     lcd_PrintText(2,1," Meldegruppe 1 ");
     lcd_PrintText(3,1," Überbelastet ");
     lcd_PrintText(4,1,"Portalkran anhalten!");
     }
     break;
    }
    
    ich finde, dass es sehr umständlich ist und man auf viel zu viele Sachen achten muss, damit das Programm ordentlich funktioniert. Und bei einigen braucht der Controller eine Zeit lang, bis er einen Schaltzustand realisiert.
     
  15. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.