TIA Schleife

litlegerman

Level-2
Beiträge
314
Reaktionspunkte
7
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Mogen ich habe follgende Darstellung:
Ich habe einen Umrichter von Lenze, dieser gibt mir einen Störcode raus (Int Format), diesen Code kann ich mit dem HAndbuch entschlüsseln.
Es ergeben sich 125 verschiedene Codes / Störungen, jetzt habe ich mir gedacht diese Störungen in einen Array[0..124] of String zu verschieben (schon erledigt) und die Codes in einen Array[0..124]of int, so das der String array immer zum Code Array passt, aslo:
String Array Stelle Code Array
Stoerung 01 [0] 100
...
Stoerung 45 [0] 1540
usw.
Wie kann ich das jetzt am elegantesten realisieren, ich dachte an eine Schleife, die dann immer das Code Array vergleicht, bei einem "Match" dann stoppen und die aktuelle Zeile aus dem String zu ziehen.
Aber leider bin ich nicht so fitt in SCL wir...
Danke fü die Hilfe

TIA V15
CPU S7 314c 2 PN/DP
 
Moin,
du brauchst lediglich deine Texte als String-Array. Die Nummer des Array-Eintrages muss mit der Nummer des Störcodes identisch sein. Dann brauchst du keine Schleife sondern gibst als Status-String aus:
Code:
#statusString := DBstatusStrings.Statustext[StatuscodeVonFU];
und so sieht bei mir der Status-DB mit den Statustexten (hier SEW) aus:
StatusFU.jpg
 
Zuletzt bearbeitet:
Ich habe leider gerade kein passendes Handbuch von Lenze zur Hand. Sind die Codes denn halbwegs fortlaufend? Weil bei deiner Reihe oben von 2818 bis 2822 kann man sein Text-Array ja auch als TextArray[2818..2822] anlegen.
 
Wenn du garantieren kannst, dass die Einträge aufsteigend sortiert sind, kannst du eine Binärsuche einsetzen.
Ich verwende die bei fast allen Listen, da die Suchzeit konstant ln(n)/ln(2) ist.
 
Code:
FUNCTION "GetLenzeText" : Void
   VAR_INPUT 
		errorCode : Int;   //Fehlernummer zum Suchen
   END_VAR

   VAR_OUTPUT 
		errText : STRING;   //out: line containing read texts
   END_VAR

   VAR_IN_OUT 
   END_VAR

   VAR_TEMP 
		l : INT;
		m : INT;
		r : INT;
   END_VAR

   VAR CONSTANT 
   END_VAR


BEGIN

(*
the following code implements a binary search
source: https://de.wikipedia.org/wiki/Bin%C3%A4re_Suche


/**
 * Binäre Suche auf dem Array M nach dem Eintrag suchwert
 *
 * @param M :          zu durchsuchendes Feld
 * @param eintraege :  Anzahl der Feldelemente
 * @param suchwert :   gesuchter Eintrag
 * @return >= 0: Index des gesuchten Eintrags
 *         <  0: nichts gefunden
 */
int binary_search(const int M[], const int eintraege, const int suchwert)
{
    const int NICHT_GEFUNDEN = -1 ;
    int mitte;
    int links = 0;                      /* man beginne beim kleinsten Index */
    int rechts = eintraege - 1;         /* Arrays-Index beginnt bei 0 */

    /* Solange die zu durchsuchende Menge nicht leer ist */
    while (links <= rechts)
    {
        mitte = links + ((rechts - links) / 2); /* Bereich halbieren */

        if (M[mitte] == suchwert)       /* Element suchwert gefunden? */
            return mitte;
        else
            if (M[mitte] > suchwert)
                rechts = mitte - 1;     /* im linken Abschnitt weitersuchen */
            else /* (M[mitte] < suchwert) */
                links = mitte + 1;      /* im rechten Abschnitt weitersuchen */
            /* end if */
        /* end if */
    }

    return NICHT_GEFUNDEN;
    // alternativ: return -mitte ; // gute Positionsschaetzung: "nach (-Returnwert) wuerde es hingehoeren"
}

the code uses the following substitutions
m:			mitte
l:			links
r:			rechts
M:			ErrTextsList.ErrNum[]	search key
suchwert:	        ErrTextsList.ErrText[]

*)

m := 0;								
l := 0;								
r := 124;

while (l <= r) do
	m := l + ((r-l) / 2);
	if (ErrTextsList.ErrNum[m] = errorCode) then
		  errText := ErrTextsList.ErrText[m];
		  return;
	else
		if (ErrTextsList.ErrNum[m] > errorCode) then
			r := m-1;
		else
			l := m+1;
		end_if;
	end_if;
	errText := 'NotFound';
end_while;

END_FUNCTION

Anbei mal eine SCL-Quelle, wie sie auf einer S7-1500 läuft (habs mal von meinem System abgespeckt). Am Eingang errCode kommt die gesuchte Nummer rein. Am Ausgang errText wird der String zurückgeliefert. Wird die Zeile errText := 'NotFound'; erreicht, dann ist der Text nicht gefunden worden.
Der DB "ErrTextsList" enthält
ErrNum : Array[0..124] of INT;
ErrText : Array[0..124] of STRING;

Es kann sein, dass man für S7-300 evtl. noch die String-Länge fix angeben muss.

Generell muss ich aber die Frage stellen, wofür das gebraucht wird? Ist es nicht einfacher, eine HMI-Textliste zu verwenden?

lg
 
Mußt du das unbedingt mit der SPS machen?
Hat man ein HMI von Siemens geht es auch anders:
Ich nehme die Fehler-Codes (Siemens, Lenze, SEW, Festo) jeweils in eine Textliste von WinCC-Flex, bzw, WinCC-Basic oder Advanced im TIA und trage zu dann hinter den Fehlercode den Text dort ein. (Achtung, Hex/Dez und maximale Größe des Index in der Textliste beachten). Damit brauche ich nur den Fehlercode in eine Variable schreiben, die dann mit der Textliste verbunden ist und somit den richtigen Fehlertext anzeigt.
Bei einem Lenze-Servo 9300 mußte aber der Code noch etwas aufbereitet werden (ging im Lenze selbst), weil der nicht rein numerisch oder zu groß war (Abschneiden von Zeichen).
 
Zurück
Oben