saup Programování Mosaic 19. 3. 2026 1:04 19. 3. 2026 12:53

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

Luboš Urban 19. 3. 2026 1:30

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)

 

saup 19. 3. 2026 7:17

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

 

M.B. 19. 3. 2026 12:53

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_BLOCK

Vaše odpověď

Pro vložení odpovědi je nezbytné být přihlášený. Pokračujte na přihlášení.