Je nejaka moznost, aby sme pri novom spusteni programu po chybe, ktora chybou v programe, prip.inou dostane PLC do Err,
zistili v prvom cykle kod tejto chyby?
Odpovědi 3
Chybový kód předešlé tvrdé chyby uživatelským programem je uložen v registru %S34. Měkké chyby, které nezastaví běh centrální jednotky, resp. celého systému, se dají identifikovat programem na základě hodnoty z tohoto registru a v programu se mohou ošetřit.
Popsáno je to v příručce programátoru PLC Tecomat, dostupná např. v Mosaicu (Nápověda, druhá příručka v seznamu, kapitola 5.3 Systémové registry)
Dakujem za odpoved. Ano, toto je ok, pokial sa program nezastavi. Alebo aj ak to ladíme Mosaicom, tak aj napr. v %SW48 je text, ktorý sa dá dohľadať v SYSGEN/xxx.lst. Pri ladeni s Mosaicom je to Ok.
Problém je neotestovaná tvrdá chyba, ktorá zastaví program, už v prevádzke na PLC niekde u užívateľa.
- User nahodne tukne na neotestovanu sekvenciu.
- Vznikne tvrda chyba, Plc -> Err, zastaví sa program, ktorý ju už nemá ako zapísať/zapamätať.
- nejde o vypadok napajania ale Plc sa po case (Restart PLC po tvrde chybe) znova spusti
- Pokial chyba narusila konzistenciu dat, PLC ide opat do Err a tak dookola
- ak by si PLC este v prvom cykle pri novom Hot-restarte (alebo inom) pamatal poslednu chybu, program by ju vzdy na zaciatku nejako spracoval
- napr. Urobil detailný log, poslal správu do centra, zablokoval chybovú sekvenciu – ak to logika dovolí…
- pripadne ak by existovala nejaka uloha od prerusenia, kde by sa cosi dalo programovo urobit ...
- Retain si ju tusim nezapamataju, lebo cyklus nedobehne do konca - chyba je niekde v strede cyklu
Jediný způsob, jak nyní získat informaci o poslední chybě před restartem je načtením dat z logu událostí PLC (WWW/LOGS/EVENT.TXT). Archiv projektu s jednoduchým příkladem najedete v přiloženém souboru.
Vlastní blok vypadá následovně:
FUNCTION_BLOCK fbReadEventLog
VAR CONSTANT
LINES_NUM : USINT := 10;
LINES_LAST : USINT := LINES_NUM - 1;
END_VAR
VAR_OUTPUT
wasErr : BOOL;
busy : BOOL;
lastError : STRING;
lastErrorDT : DATE_AND_TIME;
END_VAR
VAR_IN_OUT
END_VAR
VAR
rl : ReadLine;
li : USINT;
lines : ARRAY[0..LINES_LAST] OF STRING[255];
reading : BOOL;
END_VAR
VAR_TEMP
fileName : STRING := 'WWW/LOGS/EVENT.LOG';
tmp : STRING[255];
tmp_li : USINT;
i : USINT;
runcnt : USINT;
END_VAR
IF ProgramIsChanged() THEN
wasErr := false;
busy := true;
reading := true;
rl(maxLen := 255, line := 0, txtLine := lines[0], fileName := fileName);
rl.line := 1;
li := 0;
END_IF;
IF busy THEN
IF reading THEN
//nacist poslednich 10 radku logu udalosti
WHILE reading AND NOT System_S.CYCLE_TIME_WARNING DO
rl(txtLine := lines[li], fileName := fileName);
IF rl.done THEN
tmp := LEFT(lines[li], 1);
IF tmp = '$A0' THEN //konec logu
reading := false;
ELSE
li :=(li + 1) MOD LINES_NUM;
rl.line := rl.line + 1;
END_IF;
END_IF;
IF rl.err THEN //konec logu
reading := false;
END_IF;
END_WHILE;
ELSE
//vyhodnotit posledni nactene radky
tmp_li := li;
REPEAT
IF tmp_li > 0 THEN
tmp_li := tmp_li - 1;
ELSE
tmp_li := LINES_LAST;
END_IF;
IF FIND(lines[tmp_li], 'Run (') > 0 THEN
runcnt := runcnt + 1;
END_IF;
i := FIND(lines[tmp_li], 'Error');
IF i <> 0 THEN
tmp := lines[tmp_li];
lastError := MID(IN := tmp, L := 80, P := i);
tmp := REPLACE(IN1 := tmp, IN2 := '-', L := 1, P := 11);
tmp := 'DT#' + tmp;
lastErrorDT := STRING_TO_DATE_AND_TIME(tmp);
wasErr := true;
END_IF;
//ukoncit kdyz:
// byla chyba nebo
// prosli se vsechny radky nebo
// nasel se druhy start
UNTIL tmp_li = li OR wasErr OR runcnt = 2 END_REPEAT;
busy := false;
END_IF;
END_IF;
END_FUNCTION_BLOCKVaše odpověď
Pro vložení odpovědi je nezbytné být přihlášený. Pokračujte na přihlášení.
