Quello che segue è un
Emulatore di
PLC Siemens Simatic S5 realizzato in
JavaScript quindi compatibile con tutti i
moderni browser.
Sgart.it - Emulatore PLC Siemens S5 - v. 0.3 (BETA)
Per interagire con l'emulatore, avvialo tramite il pulsante run e clicca sugli ingressi verdi (vedi esempi)
E' un progetto che avevo in testa da molto tempo ma solo ora ho trovato il "tempo" di realizzarlo.
Tramite
JavaScript ho cercato di emulare l'hardware di un Controllore logico programmabile
PLC (Programmable Logic Controller) della
Siemens serie
Simatic Step 5 (
S5) che usavo tempo fa nel mio precedente lavoro.
Per la precisione l'hardware emulato è una
CPU 103 e la memoria e di circa 10000 word.
Si tratta di un
PLC ormai superato dalla nuova serie
S7 ma esistono ancora molte installazioni che lo usano e comunque penso possa tornare utile a livello didattico per provare piccoli programmi. Dico piccoli ma in realtà si dovrebbero poter scrivere anche grossi programmi solo che non penso siano utili in un ambiente di emulazione.
Si tratta di una versione beta a cui mancano alcune funzioni e soprattutto non ho avuto ancora il tempo di testare tutto adeguatamente.
Se trovi delle anomalie puoi segnalarmele alla mail info[at]sgart.it
L'emulatore supporta sia il linguaggio con la notazione inglese
STL (Statement List) che quella tedesca
AWL (Anweisungs-Liste). Nel menu a tendina trovi qualche esempio.
L'emulatore parte cercando di interpretare le istruzioni e/o direttive (
parser), se trova delle variabili prima le sostituisce e poi "parsa" la riga. Il risultato è l'ottenimento dell
'Opcode (codice macchina) che solitamente corrisponde a 1 word (2 byte) e in alcuni casi 2 word. La fase successiva e quella di
link per risolvere i salti definiti tramite
label (stringa di caratteri) e ricavare l'esatto indirizzo di memoria.
Sono supportati tutti i tipi di blocchi
OB (Organization Block),
PB (Program Block),
FB (Function Block) ,
SB (Sequence Block) e
DB (Data Block).
Le istruzioni di base sono implementate quasi tutte (logiche, lettura, trasferimento, salti assoluti, condizionali...) più sotto trovi l'elenco delle esclusioni.
Le caratteristiche dell'emulatore sono:
- Ingressi 128 byte
- Uscite 128 byte
- Flag 256 byte
- Temporizzatore 128 byte
- Contatori 128 byte
- Blocchi OB 256 byte
- Blocchi PB 256 byte
- Blocchi FB 256 byte
- Blocchi SB 256 byte
- Blocchi DB 256 byte
- Memoria 10240 words
E' possibile inserire delle direttive/impostazioni prima delle istruzioni per controllare il comportamento dell'emulatore. Le direttive devono avere come primo carattere sulla linea la chiocciola
@:
- @PIO= permette di definire la sequenza degli ingressi (I o E), uscite (Q o A) e flag (F o M) disegnati in altro. Gli ingressi verdi sono cliccabili. Es.: @PIO=IIQQF
- @AUTORUN= se presente ed ha il valore on indica che il codice deve andare in esecuzione appena caricato, in caso contrario è necessario premere il pulsante run
- @LANGUAGE=DE se presente il codice viene interpretato in AWL quindi con le istruzioni in lingua tedesca
Tramite il carattere cancelletto
# è possibile inserire dei commenti.
Sono gestite le variabile a cui è possibile assegnare dei valori per rendere più leggibile il codice (vedi esempi). Le variabili devono essere definite prima del loro utilizzo al di fuori di qualsiasi blocco e devono iniziare con il carattere meno
- seguito da delle lettere (es.: -PSTOP = 0.0 ).
L'elaborazione del programma avviene secondo lo schema classico, ovvero:
- vengono letti gli ingressi
- viene elaborato il programma
- viene trasferito il risultato sulle uscite
la sequenza si ripete all'infinito finchè non si preme il pulsante
stop.
Il programma parte sempre da
OB 1 quando questo non è presente ne viene generato uno dal parser con un salto assoluto al primo blocco (non DB) definito.
Cosa manca e note:
- La gestione dei blocchi OB speciali (OB 21, 22, 34...) solo OB 1 è supportato
- Il Data Block 1 (DB1) non è supportato
- I Function Block non supportano i parametri e sono trattati come PB
- Le istruzioni relative agli operandi formali dei blocchi FB non sono ancora implementate
- Le istruzioni di accesso diretto alla memoria non sono supportate
- Gli interrupt non sono supportati
- Non sono ancora implementate le istruzioni O (OR) e A (AND) per il momento vanno usati i corrispettivi con le parentesi O( e A( e chiusi alla fine con ) (il numero massimo di parentesi annidabili è 6)
- Non è implementato il Watchdog quindi occhio ai cicli infiniti (lo stack delle chiamate è limitato a 16 livelli)
- il tempo di ciclo visualizzato in millisecondi è puramente indicativo e dipende dal tuo hardware/software (pc / browser)
- e qualcos'altro che mi sono sicuramente dimenticato di elencare
Per far funzionare l'emulatore è necessario avere una delle ultime versione dei browser in grado di supportare l'elemento
canvas.
Tieni anche presente che un browser recente permettere l'esecuzione del codice
JavaScript in modo molto più efficiente e veloce... oltre ad essere più sicuro.
Vanno sicuramente bene le ultime versione di
Firefox,
Chrome,
Opera,
Safari e
Internet Explorer dalla versione 11.
Vedi anche
Simatic S5 PLC
# Sgart.it - PLC Siemens Step 5 Emulator
# demo marcia arresto (premi 0.0 e poi 0.1)
@PIO=IIIIQQQQ
# I 0.0 = pulsante di arresto NC
# I 0.1 = pulsante di marcia NA
# Q 4.0 = uscita motore
PB 0
A(
O I 0.1 # pulsante di marcia
O Q 4.0 # contatto di ritenuta
)
A I 0.0 # pulsante di arresto normalmente chiuso
= Q 4.0
BE
# Sgart.it - PLC Siemens Step 5 Emulator
# demo timer (premi l'ingresso 0.0 per partire)
PB 1
# SP = Pulse Timer - Attivazione di un tempo come impulso
A I 0.0
L KT 15.2
SP T 0
A T 0 # legge lo stato del timer
= Q 4.0 # setta l'uscita in base allo stato
L T 0 # legge il valore attuale del timer
T QW 13 # lo trasferisce sulla word 8 delle uscite
# SE = Extended Pulse Timer - Attivazione di un tempo come impulso prolungato
A I 0.1
L KT 90.0
SE T 1
A T 1
= Q 4.1
# SD = On-Delay Timer - Attivazione di un tempo con ritardo all'inserzione
A I 0.2
L KT 95.0
SD T 2
A T 2
= Q 4.2
# SS = Stored On-Delay Timer - Attiv. di un tempo con rit. all'inserz. e autoritenuta
A I 0.3
L KT 10.2
SS T 3
A I 1.3
R T 3
A T 3
= Q 4.3
LD T 3 # legge il valore attuale del timer in BCD
T QW 15
# SF = Off-Delay - Attivazione di un tempo con ritardo alla disinserzione
A I 0.4
L KT 105.0
SF T 4
A T 4
= Q 4.4
BE
# Sgart.it - PLC Siemens Step 5 Emulator
# demo counter (premi 0.1 per incrementare e 0.0 per decrementare)
PB 12 # test counter
A I 0.0 # decrementa contatore
CD C 1
A I 0.1 # incrementa contatore
CU C 1
A I 0.7 #setta il contatore
L KC 23
S C 1
A I 0.6 # resetta il contatore
R C 1
A C 1 # trasferisce lo stato binario del contatore
= Q 4.0 # sull'uscita
LD C 1 # visualizza il valore di conteggio in BCD
T QW 13
BE
# Sgart.it - PLC Siemens Step 5 Emulator
# demo salti con label
@autorun=on
DB 5
FF00 8800 1100110011001100
8080 1001
.
OB 1
JU PB 0
BE
PB 0
A(
O I 0.1 # marcia arresto
O Q 4.0
)
A I 0.0
= Q 4.0
JU PB 1
L kH 81
T QB 13
BE
PB 1
#test label
l KH F00F
A I 1.0
JC= F001
l KH 0FF0
F001: T QW 6
C DB 5
L kH 1
L DW 1
+f
T DW 1
T QW 15
BE
# Sgart.it - PLC Siemens Step 5 Emulator
# Demo Data Block (DB)
@PIO=IIQQ # definisco lo stato delle schede di ingresso (I) o uscita (Q)
@autorun=on
DB 5 #definisco l'inizio di un blocco dati
FF00 1234 1100110010101010 # posso inserire numeri esadecimali o binari
8080 1001 # andando liberamente su più linee
.
PB 0
C DB 5 # apro il DB 5
A I 0.0 # in base all'ingresso 0.0 scelgo la data word 1 o 2
JC= F001
L DL 1 # leggo il byte di sinistra della data word 1 e lo metto in ACCU1
L DR 1 # leggo il byte di destra della data word 1 e lo metto in ACCU1
T QW 2 # trasferisco il valore di ACCU1 nella word 2 di sucita
BEU # esco dal blocco senza condizioni
F001:
L DW 2 # leggo la data word 2 e la metto in ACCU1
T QW 2
BE
# Sgart.it - PLC Siemens Step 5 Emulator
# demo marcia arresto con VARIABILI
@PIO=IIIIQQQQ # definisco lo stato delle schede di ingresso (I) o uscita (Q)
# le variabili hanno come primo carattere un '-' (meno) seguito da una lettera,
# i successivi caratteri del nome possono essere sia lettere che numeri
# le variabili vanno definite prima dell'utilizzo all'esterno di un blocco
# il valore può essere una qualsiasi stringa e viene sostituita prima del parsing
-PSTOP = 0.0 # pulsante di arresto NC
-PSTART = I 0.1 # pulsante di marcia NA
-MOTORE = 4.0 # uscita comando motore
PB 0
A(
O -PSTART
O Q -MOTORE
)
A I -PSTOP
= Q -MOTORE
BE
# Sgart.it - PLC Siemens Step 5 Emulator
# demo generatore onda quadra
@PIO=IQQQFF # attenzione i flag vengono aggiornati insieme alle uscite alla fine del ciclo, non in tempo reale
@AUTORUN=on
PB 0
AN F 4.0 # aw il flag 4.0 non è settato
L KT 010.1 # carico in ACCU1 il tempo - 10 x 0.1s = 1s
SD T 5 # setto il temporizzatore 5
A T 5 # se ha terminato il tempo
= F 4.0 # setto il flag 4.0
A F 4.0 # se il flag 4.0 è settato (A=AND)
AN F 5.0 # e il flag 5.0 NON è settato (N=neegazione), li metto in AND
S Q 1.0 # se il risultato è vero setto l'uscita 1.0 a true
A F 4.0
A F 5.0
R Q 1.0 # se il risultato logico combinatorio (RLO) delle istruzioni precedenti è true resetto l'uscita 1.0
AN F 4.0
A Q 1.0
S F 5.0
AN F 4.0
AN Q 1.0
R F 5.0
AN Q 1.0 # leggo l'uscita 1.0 negata
= Q 2.1 # imposto l'uscita 2.1
BE
# Sgart.it - PLC Siemens Step 5 Emulator
# demo relè passo-passo Instruction set DE
@PIO=IIIIQQQQ, AUTORUN=on, LANGUAGE=DE
FB 0
#generazione di un impulso su M64.1
UN E 0.1
U M 64.0
= M 64.1
U E 0.1
= M 64.0
# segue il codice del comando start-stop
U M 64.1
UN M 0.0
O(
UN M 64.1
U M 0.0
)
= M 0.0 #uscita di comando (relè passo-passo)
U M 0.0
= A 4.0
U M 64.0
= A 5.0
U M 64.1
= A 5.1
BE