Sei sulla pagina 1di 115

HAL Tutorial Completo

Ver. 0.7

12 Maggio 2019

http://linuxcnc.org/docs/devel/html/hal/intro.html

http://linuxcnc.org/docs/devel/html/hal/basic-hal.html

http://linuxcnc.org/docs/devel/html/hal/tutorial.html

http://linuxcnc.org/docs/devel/html/hal/rtcomps.html

http://linuxcnc.org/docs/devel/html/gui/pyvcp.html

http://linuxcnc.org/docs/html/ladder/ladder-intro.html

http://linuxcnc.org/docs/devel/html/ladder/classic-ladder.html

http://linuxcnc.org/docs/devel/html/ladder/ladder-examples.html
Introduzione HAL
Sommario
HAL sta per Hardware Abstraction Layer. Al livello più alto è semplicemente un modo per
consentire a un certo numero di blocchi di costruzione di essere caricati e interconnessi per
assemblare un sistema complesso. La parte hardware è perché HAL è stato originariamente
progettato per semplificare la configurazione di LinuxCNC per un'ampia varietà di dispositivi
hardware. Molti degli elementi costitutivi sono driver per dispositivi hardware. Tuttavia,
HAL può fare molto di più che configurare semplicemente i driver hardware.

1. HAL si basa sulle tecniche di progettazione di


sistemi tradizionali
HAL si basa sugli stessi principi utilizzati per progettare circuiti e sistemi hardware, quindi è
utile esaminare prima questi principi.
Qualsiasi sistema (inclusa una macchina CNC), è costituito da componenti interconnessi. Per
la macchina CNC, tali componenti potrebbero essere il controller principale, i
servoamplificatori o gli azionamenti passo-passo, i motori, gli encoder, i finecorsa, i pulsanti
pendenti, forse un VFD per l'azionamento del mandrino, un PLC per l'esecuzione di un
cambio utensile, ecc. Bisogna selezionare, montare e collegare questi pezzi insieme per creare
un sistema completo.

1.1. Selezione delle parti


Il costruttore della macchina non deve preoccuparsi di come funziona ogni singola parte. Li
tratta come scatole nere. Durante la fase di progettazione, decide quali parti utilizzerà:
stepper o servi, quale marca di servoamplificatori, quale tipo di interruttori di limite e quanti,
ecc. Le decisioni dell'integratore su quali componenti specifici utilizzare si basano su ciò che
componente fa e le specifiche fornite dal produttore del dispositivo. La dimensione di un
motore e il carico che deve guidare influenzeranno la scelta dell'amplificatore necessario per
eseguirlo. La scelta dell'amplificatore può influire sui tipi di feedback richiesti
dall'amplificatore e dai segnali di velocità o di posizione che devono essere inviati
all'amplificatore da un controllo.
Nel mondo HAL, l'integratore deve decidere quali componenti HAL sono necessari. Di solito
ogni scheda di interfaccia richiede un driver. Ulteriori componenti potrebbero essere
necessari per la generazione del software di impulsi di passo, funzionalità PLC e una vasta
gamma di altri compiti.

1.2. Progettazione dell'interconnessione


Il progettista di un sistema hardware non solo seleziona le parti, ma decide anche in che
modo tali parti saranno interconnesse. Ogni scatola nera ha terminali, forse solo due per un
semplice interruttore, o dozzine per un servoazionamento o un PLC. Hanno bisogno di essere
collegati insieme. I motori si collegano ai servoamplificatori, i finecorsa si collegano al
controller e così via. Mentre il costruttore di macchine lavora sulla progettazione, crea un
grande schema elettrico che mostra come tutte le parti dovrebbero essere interconnesse.
Quando si utilizza HAL, i componenti sono interconnessi da segnali. Il progettista deve
decidere quali segnali sono necessari e come dovrebbero connettersi.
1.3. Implementazione
Una volta completato lo schema elettrico, è il momento di "costruire" la macchina. I pezzi
devono essere acquisiti e montati, e quindi sono interconnessi secondo lo schema elettrico.
In un sistema fisico, ogni interconnessione è un pezzo di filo che deve essere tagliato e
collegato ai terminali appropriati.
HAL fornisce una serie di strumenti per aiutare a costruire un sistema HAL. Alcuni
strumenti consentono di connettere (o disconnettere) un singolo filo. Altri strumenti
consentono di salvare un elenco completo di tutte le parti, i cavi e altre informazioni sul
sistema, in modo che possa essere ricostruito con un singolo comando.

1.4. analisi
Pochissime macchine funzionano correttamente la prima volta. Durante il test, il costruttore
può utilizzare un tester per vedere se un finecorsa funziona o per misurare la tensione
continua che passa in un servomotore. Può collegare un oscilloscopio per controllare la messa
a punto di un'unità o per cercare il rumore elettrico. Potrebbe trovare un problema che
richiede di cambiare lo schema elettrico; forse una parte deve essere collegata in modo
diverso o sostituita con qualcosa di completamente diverso.
HAL fornisce gli equivalenti software di un voltmetro, oscilloscopio, generatore di segnale e
altri strumenti necessari per testare e sintonizzare un sistema. Gli stessi comandi utilizzati
per costruire il sistema possono essere utilizzati per apportare modifiche in base alle esigenze.

1.5. Sommario
Questo documento è rivolto a persone che già sanno come fare questo tipo di integrazione del
sistema hardware, ma che non sanno come connettere l'hardware a LinuxCNC.
Il design hardware tradizionale come descritto sopra finisce sul bordo del controllo
principale. Fuori dal controllo ci sono un sacco di scatole relativamente semplici, collegate
insieme per fare tutto il necessario. Dentro, il controllo è un grande mistero - un'enorme
scatola nera che speriamo funzioni…
HAL estende questo tradizionale metodo di progettazione hardware all'interno della grande
scatola nera. Rende i driver di dispositivo e persino alcune parti interne del controller in
scatole nere più piccole che possono essere interconnesse e persino sostituite proprio come
l'hardware esterno. Consente allo schema di cablaggio del sistema di mostrare parte del
controller interno, anziché solo una grande scatola nera. E, cosa più importante, consente
all'Integratore di testare e modificare il controller usando gli stessi metodi che userebbe sul
resto dell'hardware.
Termini come motori, amplificatori ed encoder sono familiari alla maggior parte degli
integratori di macchine. Quando parliamo di usare un cavo schermato a otto conduttori extra
flessibile per collegare un encoder alla scheda di ingresso del servo nel computer, il lettore
capisce immediatamente di cosa si tratta e viene indirizzato alla domanda, che tipo di
connettori avrò bisogno per collegare ciascuna estremità. Lo stesso tipo di pensiero è
essenziale per l'HAL, ma la sequenza di specifici pensieri potrebbe richiedere un po' di tempo
per andare a regime. L'uso delle parole HAL può sembrare un po' strano all'inizio, ma il
concetto di lavorare da una connessione all'altra è lo stesso.
Questa idea di estendere lo schema elettrico all'interno del controller è ciò che HAL è tutto.
Se hai dimestichezza con l'idea di interconnettere le scatole nere hardware, probabilmente
non avrai problemi a usare l'HAL per interconnettere le scatole nere del software.
2. Concetti HAL
Questa sezione è un glossario che definisce i termini chiave HAL ma è leggermente diversa da
un glossario tradizionale perché questi termini non sono disposti in ordine alfabetico. Sono
organizzati dalla loro relazione o flusso nel mondo di HAL.
Componente
Quando abbiamo parlato della progettazione hardware, abbiamo fatto riferimento ai
singoli pezzi come parti , blocchi predefiniti , scatole nere , ecc. L'equivalente HAL è
un componente o componente HAL. (Questo documento usa il componente HAL
quando è probabile che ci sia confusione con altri tipi di componenti, ma normalmente
usa solo componenti ). Un componente HAL è un pezzo di software con input, output e
comportamento ben definiti, che possono essere installati e interconnessi secondo
necessità.
Parametro
Molti componenti hardware hanno regolazioni che non sono collegate ad altri
componenti ma devono comunque essere accessibili. Ad esempio, i servoamplificatori
hanno spesso potenziometri per consentire regolazioni di taratura e punti di prova in
cui è possibile collegare un misuratore o un mirino per visualizzare i risultati di
sintonizzazione. I componenti HAL possono anche avere tali elementi, che sono
indicati come parametri. Esistono due tipi di parametri: i parametri di input sono
equivalenti ai potenziometri: sono valori che possono essere regolati dall'utente e
rimangono fissi una volta impostati. I parametri di uscita non possono essere regolati
dall'utente - sono equivalenti ai punti di test che consentono il monitoraggio dei
segnali interni.
Pin
I componenti hardware hanno terminali che vengono utilizzati per interconnetterli.
L'equivalente HAL è un pin o un pin HAL. (Il pin HAL viene utilizzato quando
necessario per evitare confusione.) Tutti i pin HAL hanno un nome e i nomi dei pin
vengono utilizzati quando li si interconnette. I pin HAL sono entità software che
esistono solo all'interno del computer.
Physical Pin
Molti dispositivi I / O hanno pin o terminali fisici reali che si collegano all'hardware
esterno, ad esempio i pin di un connettore di una porta parallela. Per evitare
confusione, questi sono indicati come pin fisici. Queste sono le cose che sporgono nel
mondo reale.
Signal
In una macchina fisica, i terminali di componenti hardware reali sono interconnessi da
fili. L'equivalente HAL di un filo è un signal (segnale) o un segnale HAL. I segnali
HAL collegano i pin HAL come richiesto dal costruttore della macchina. I segnali HAL
possono essere scollegati e ricollegati a piacere (anche mentre la macchina è in
funzione).
Type
Quando si utilizza l'hardware reale, non si collegherà un'uscita relè a 24 volt
all'ingresso analogico +/- 10 V di un servoamplificatore. I pin HAL hanno le stesse
restrizioni, che si basano sul loro tipo. Sia i pin che i segnali hanno tipi e i segnali
possono essere collegati solo a pin dello stesso tipo. Attualmente ci sono 4 tipi, come
segue:
 bit - un singolo valore VERO / FALSO o ON / OFF
 float - un valore in virgola mobile a 64 bit, con circa 53 bit di risoluzione e oltre
1000 bit di intervallo dinamico.
 u32 - un intero senza segno a 32 bit, i valori legali sono compresi tra 0 e
4.294.967.295
 s32 - un intero con segno a 32 bit, valori legali da -2,147,483,647 a
+2,147,483,647

Function
I componenti hardware reali tendono ad agire immediatamente sui loro input. Ad
esempio, se cambia la tensione di ingresso a un servoamplificatore, anche l'uscita
cambia automaticamente. Tuttavia i componenti software non possono agire
automaticamente. Ogni componente ha un codice specifico che deve essere eseguito
per svolgere il compito di quel componente. In alcuni casi, quel codice viene
semplicemente eseguito come parte del componente. Tuttavia, nella maggior parte dei
casi, specialmente nei componenti in tempo reale, il codice deve essere eseguito in una
sequenza specifica ed a intervalli specifici. Ad esempio, gli input dovrebbero essere
letti prima che i calcoli vengano eseguiti sui dati di input e le uscite non dovrebbero
essere scritte fino a quando non vengono eseguiti i calcoli. In questi casi, il codice è
reso disponibile al sistema sotto forma di una o più function (funzioni). Ogni funzione
è un blocco di codice che esegue un'azione specifica. L'integratore di sistema può
utilizzare i thread per pianificare una serie di funzioni da eseguire in un ordine
particolare ed a intervalli di tempo specifici.
Thread
Un thread è un elenco di funzioni eseguite a intervalli specifici come parte di
un'attività in tempo reale. Quando un thread viene creato per la prima volta, ha un
intervallo di tempo specifico (periodo), ma nessuna funzione. Le funzioni possono
essere aggiunte al thread e verranno eseguite nell'ordine ogni volta che il thread viene
eseguito.
Ad esempio, supponiamo di avere un componente parport denominato hal_parport. Quel
componente definisce uno o più pin HAL per ogni pin fisico. I pin sono descritti nella sezione
doc di quel componente: i loro nomi, come ogni pin, si riferiscono al pin fisico, sono invertiti,
puoi cambiare polarità, ecc. Ma questo da solo non prende i dati dai pin HAL ai pin fisici . Ci
vuole del codice per farlo, ed è qui che le funzioni entrano in scena. Il componente parport
ha bisogno di almeno due funzioni: una per leggere i pin di input fisici e aggiornare i pin
HAL, l'altra per prendere i dati dai pin HAL e scriverli sui pin di output fisici. Entrambe
queste funzioni fanno parte del driver parport.

3. Componenti HAL
Ogni componente HAL è un pezzo di software con input, output e comportamenti ben
definiti, che possono essere installati e interconnessi secondo necessità. Questa sezione
elenca alcuni dei componenti disponibili e una breve descrizione di ciò che ciascuno fa. I
dettagli completi per ciascun componente sono disponibili più avanti in questo documento.

3.1. Programmi esterni con link HAL


motion
Un modulo in tempo reale che accetta comandi NML di movimento e interagisce con
HAL
[Neutral Message Language fornisce un meccanismo per gestire più tipi di messaggi nello
stesso buffer, oltre a semplificare l'interfaccia per la codifica e la decodifica dei buffer in
formato neutro e il meccanismo di configurazione.]
iocontrol
Un modulo dello spazio utente che accetta comandi I / O NML e interagisce con HAL
classicladder
Un PLC che utilizza HAL per tutti gli I / O
halui
Un programma spaziale utente che interagisce con HAL e invia comandi NML, è
destinato a funzionare come un'interfaccia utente completa usando manopole e
interruttori esterni

3.2. Componenti interni


stepgen
Generatore di impulsi di passo del software con anello di posizione. Vedi la sezione
[sec: stepgen]
encoder
Contatore di encoder basato su software. Vedi la sezione [encoder]
pid
Anelli di controllo proporzionale / integrale / derivativo. Vedi la sezione [pid]
siggen
Un generatore di seno / coseno / triangolo / onda quadra per il test. Vedi la sezione
[siggen]
supply
Una semplice fonte per i test.

3.3. Driver hardware


hal_ax5214h
Un driver per la scheda I / O digitale AX5241H di Axiom Measurement & Control
hal_gm
Scheda GM6-PCI General Mechatronics
hal_m5i20
Scheda Mesa Electronics 5i20
hal_motenc
Scheda Vital MOTENC-100
hal_parport
Porta parallela per PC.
hal_ppmc
Famiglia di controllori Pico Systems (PPMC, USC e UPC)
hal_stg
Scheda Servo To Go (versione 1 e 2)
hal_vti
Controllore PCI ENCDAC-4 Vigilant Technologies

3.4. Strumenti e utilità


halcmd
Strumento a riga di comando per configurazione e ottimizzazione. Vedi la sezione
[halcmd]
halgui
Strumento GUI per configurazione e tuning (non ancora implementato).
halmeter
Un pratico multimetro per segnali HAL. Vedi la sezione [halmeter] .
halscope
Oscilloscopio di memorizzazione digitale con funzionalità complete per segnali HAL.
Vedi la sezione Halscope .
Ciascuno di questi elementi costitutivi è descritto in dettaglio nei paragrafi successivi.

4. Problemi di temporizzazione in HAL


A differenza dei modelli fisici di cablaggio tra scatole nere su cui abbiamo detto che l'HAL è
basato, il semplice collegamento di due pin con un hal-signal è molto inferiore all'azione del
caso fisico.
La logica del relè reale è costituita da relè collegati tra loro e quando un contatto si apre o si
chiude, la corrente scorre (o si arresta) immediatamente. Altre bobine possono cambiare
stato, ecc. E succede tutto. Ma nella logica ladder in stile PLC, non funziona in questo modo.
Solitamente in un singolo passaggio attraverso la scala, ciascun ramo viene valutato
nell'ordine in cui appare e solo una volta per passaggio. Un esempio perfetto è un ladder, con
un contatto NC in serie con una bobina. Il contatto e la bobina appartengono allo stesso relè.
Se questo fosse un relè convenzionale, non appena la bobina viene eccitata, i contatti iniziano
ad aprirsi e disenergizzarlo. Ciò significa che i contatti si chiudono di nuovo, ecc. ecc. Il relè
diventa praticamente un cicalino.
Con un PLC, se la bobina è OFF e il contatto è chiuso quando il PLC inizia a valutare il ramo,
quindi quando finisce quel passaggio, la bobina è ON. Il fatto che accendendo la bobina si
apra l'alimentazione del contatto viene ignorata fino alla prossima passata. Al passaggio
successivo, il PLC vede che il contatto è aperto e diseccita la bobina. Quindi il relè passa
ancora rapidamente tra acceso e spento, ma a una velocità determinata dalla frequenza con
cui il PLC valuta il ramo.
In HAL, la funzione è il codice che valuta i rami. Infatti, la versione realtime di HAL-aware di
ClassicLadder esporta una funzione per fare esattamente questo. Nel frattempo, un thread è
la cosa che esegue la funzione a intervalli di tempo specifici. Proprio come è possibile
scegliere di avere un PLC che valuta tutti i suoi rami ogni 10 ms, o ogni secondo, è possibile
definire thread HAL con periodi diversi.
Ciò che distingue un thread da un altro non è ciò che fa il thread - che è determinato da quali
funzioni sono connesse ad esso. La vera distinzione è semplicemente la frequenza di
esecuzione di un thread.
In LinuxCNC potresti avere un thread da 50 us e un thread da 1 ms. Questi sarebbero creati
in base a BASE_PERIOD e SERVO_PERIOD, i tempi effettivi dipendono dai valori nel tuo
file ini.
Il prossimo passo è decidere cosa deve fare ciascun thread. Alcune di queste decisioni sono le
stesse in (quasi) qualsiasi sistema LinuxCNC: ad esempio, il comando di movimento-
comando viene sempre aggiunto al servo-thread.
Altre connessioni sarebbero fatte dall'integratore. Questi potrebbero includere l'aggancio
delle funzioni di lettura dell'encoder del driver STG e di scrittura DAC al servo thread, o
l'hooking della funzione stepgen al thread di base, insieme alle funzioni di parport per
scrivere gli step sulla porta.
Riferimento base di HAL
Sommario
1. Comandi HAL
1.1. loadrt
1.2. addf
1.3. loadusr
1.4. net
1.5. setp
1.6. sets
1.7. unlinkp
1.8. Comandi obsoleti
2. Dati HAL
2.1. Bit
2.2. Float
2.3. s32
2.4. u32
3. File HAL
4. Componenti HAL
5. Componenti logici
5.1. and2
5.2. not
5.3. or2
5.4. xor2
5.5. Esempi di logica
6. Componenti di conversione
6.1. weighted_sum
Questo documento fornisce un riferimento sulle basi di HAL.

1. Comandi HAL
Informazioni più dettagliate possono essere trovate nella pagina man di halcmd: run man
halcmd in una finestra di terminale.
Per visualizzare la configurazione HAL e controllare lo stato dei pin e dei parametri,
utilizzare la finestra Configurazione HAL nel menu Macchina in AXIS. Per vedere lo stato di
un pin aprire la scheda Watch e fare clic su ciascun pin che si desidera guardare e verrà
aggiunto alla finestra di controllo.
Figura 1. Finestra di configurazione HAL

1.1. loadrt
Il comando loadrt carica un componente HAL in realtime. Le funzioni dei componenti in
realtime devono essere aggiunte a un thread per essere aggiornati alla velocità del thread.
Non è possibile caricare un componente dello spazio utente nello spazio tempo reale.
La sintassi e un esempio:
loadrt <componente> <opzioni>

loadrt mux4 count=1

1.2. addf
Aggiunge funzione functname al thread nomefile. L'impostazione predefinita è aggiungere la
funzione nell'ordine in cui si trova nel file. Se la posizione è specificata, aggiunge la funzione
a quel punto nel thread. Posizione negativa indica la posizione rispetto alla fine della thread.
Ad esempio 1 è l'inizio del thread, -1 è la fine del thread, -3 è terzo a partire dalla fine.
E' importante caricar alcune funzioni in un certo ordine, come le funzioni di lettura e scrittura
di parport. Il nome della funzione è solitamente il nome del componente più un numero.
Nell'esempio seguente viene caricato il componente or2 e la funzione show mostra il nome
della funzione or2
$ halrun
halcmd: loadrt or2
halcmd: show function
Exported Functions:
Owner CodeAddr Arg FP Users Name
00004 f8bc5000 f8f950c8 NO 0 or2.0
È necessario aggiungere una funzione da un componente HAL in tempo reale a un thread per
ottenere la funzione da aggiornare alla velocità del thread.
Di solito ci sono due thread come mostrato in questo esempio. Alcuni componenti utilizzano
la matematica in virgola mobile e devono essere aggiunti a un thread che supporta la
matematica in virgola mobile. FP indica se la matematica in virgola mobile è supportata in
quel thread.
$ halrun
halcmd: loadrt motmod base_period_nsec = 55555 servo_period_nsec = 1000000
num_joints = 3

halcmd: show thread


Realtime Threads:
Period FP Name ( Time, Max-Time )
995976 YES servo-thread ( 0, 0 )
55332 NO base-thread ( 0, 0 )

 base-thread (il thread ad alta velocità): questo thread gestisce gli elementi che
richiedono una risposta rapida, come la creazione di impulsi di fase e la lettura e
scrittura della porta parallela. Non supporta la matematica in virgola mobile.
 servo-thread (thread a bassa velocità): questo thread gestisce gli elementi che possono
tollerare una risposta più lenta, come il controller di movimento, ClassicLadder e il
gestore dei comandi di movimento. Supporta la matematica in virgola mobile.
La sintassi e un esempio:
addf <funzione> <thread>

addf mux4.0 servo-thread

1.3. loadusr
Il comando loadusr carica un componente HAL dello spazio utente. Gli spazi programmi
degli utenti sono processi separati, che opzionalmente comunicano con altri componenti HAL
tramite pin e parametri. Non è possibile caricare componenti in tempo reale nello spazio
utente.
Le opzioni possono essere una o più delle seguenti:
-W aspettare che il componente sia pronto. Si presume che il componente abbia lo
stesso nome del primo argomento del comando.

-Wn aspettare il componente, che avrà il <nome> dato. Questo si applica solo se il
<nome> componente ha un'opzione per il nome.

-w aspettare che il programma esca

-io ignorare il valore di ritorno del programma (con -w)

-n nominare un componente quando è un'opzione valida per quel componente.

La sintassi e gli esempi:


loadusr <componente> <opzioni>
loadusr halui
loadusr -Wn spindle gs2_vfd -n spindle
1.4. net
Il comando net crea una connessione tra un segnale e uno o più pin. Se il segnale non esiste,
la rete crea il nuovo segnale. Questo sostituisce la necessità di usare il comando newsig. Le
frecce di direzione opzionali <= , => e <=> rendono più semplice seguire la logica durante la
lettura di una riga di comando della rete e non vengono utilizzate dal comando net. Le frecce
di direzione devono essere separate da uno spazio dai nomi dei pin.
Sintassi ed esempio:
net signal-name pin-name <optional arrow> <optional second pin-name>

net home-x joint.0.home-sw-in <= parport.0.pin-11-in


Nell'esempio sopra riportato home-x è il nome del segnale, joint.0.home-sw-in è un pin di
direzione IN , <= è la freccia di direzione opzionale e parport.0.pin-11-in è un pin di
direzione OUT . Ciò può sembrare confuso, ma le etichette in entrata e in uscita per un pin
della porta parallela indicano il modo fisico in cui il pin non funziona come viene gestito in
HAL.
Un pin può essere collegato a un segnale se obbedisce alle seguenti regole:
 Un pin IN può sempre essere collegato a un segnale
 Un pin IO può essere collegato a meno che non ci sia un pin OUT sul segnale
 Un pin OUT può essere collegato solo se non ci sono altri pin OUT o IO sul segnale
Lo stesso signal-name può essere usato in più comandi net per connettere pin aggiuntivi,
purché le regole sopra riportate siano rispettate.

Figura 2. Direzione del segnale


Questo esempio mostra il segnale xStep con la sorgente stepgen.0.out e con due lettori,
parport.0.pin-02-out e parport.0.pin-08-out. Fondamentalmente il valore di stepgen.0.out
viene inviato al segnale xStep e tale valore viene quindi inviato a parport.0.pin-02-out e
parport.0.pin-08-out.
# collegamento del segnale sorgente con quello di destinazione
net xStep stepgen.0.out => parport.0.pin-02-out parport.0.pin-08-out
Poiché il segnale xStep contiene il valore di stepgen.0.out (la sorgente) è possibile utilizzare di
nuovo lo stesso segnale per inviare il valore a un altro lettore. Per fare ciò basta usare il
segnale con i lettori su un'altra linea.
net xStep => parport.0.pin-02-out

Pin I/O
Un pin I/O come encoder.N.index-enable può essere letto o impostato come consentito dal
componente.

1.5. setp
Il comando setp imposta il valore di un pin o di un parametro. I valori validi dipenderanno
dal tipo di pin o parametro. È un errore se i tipi di dati non corrispondono.
Alcuni componenti hanno parametri che devono essere impostati prima dell'uso. I parametri
possono essere impostati prima dell'uso o durante l'esecuzione secondo necessità. Non è
possibile utilizzare setp su un pin collegato a un segnale.
La sintassi ed un esempio:
setp <pin/nome-parametro> <valore>

setp parport.0.pin-08-out TRUE

1.6. sets
Il comando sets comandi imposta il valore di un segnale.
La sintassi ed un esempio:
sets <nome-segnale> <valore>

net mysignal and2.0.in0 pyvcp.my-led

sets mysignal 1
È un errore se:
 Il nome del segnale non esiste
 Se il segnale ha già uno scrittore
 Se il valore non è il tipo corretto per il segnale

1.7. unlinkp
Il comando unlinkp scollega un pin dal segnale connesso. Se nessun segnale è stato collegato
al pin prima di eseguire il comando, non accade nulla. Il comando di scollegamento è utile
per la risoluzione dei problemi.
La sintassi ed un esempio:
unlinkp <nome-pin>

unlinkp parport.0.pin-02-out
1.8. Comandi obsoleti
I seguenti comandi sono obsoleti e possono essere rimossi dalle versioni future. Qualsiasi
nuova configurazione dovrebbe utilizzare il comando net . Questi comandi sono inclusi in
modo che le configurazioni precedenti funzionino ancora.
linksp
Il comando linksp crea una connessione tra un segnale e un pin.
La sintassi ed un esempio:
linksp <nome-segnale> <nome-pin>
linksp X-step parport.0.pin-02-out
Il comando linksp è stato sostituito dal comando net .
linkps
Il comando linkps crea una connessione tra un pin e un segnale. È lo stesso di linksp ma gli
argomenti sono invertiti.
La sintassi ed un esempio:
linkps <nome-pin> <nome-segnale>

linkps parport.0.pin-02-out X-Step


Il comando linkps è stato sostituito dal comando net .
newsig
Il comando newsig crea un nuovo segnale HAL con il nome <signame> e il tipo di dati di
<tipo>. Il tipo deve essere bit , s32 , u32 o float . Segnala errore se < signame > già esiste.
La sintassi ed un esempio:
newsig <signame> <tipo>

newsig Xstep bit


Ulteriori informazioni possono essere trovate nel manuale HAL o nelle pagine man di halrun.

2. Dati HAL
2.1. bit
Un valore bit è un segnale acceso o spento.
 valori bit = true o 1 e false o 0 (True, TRUE, true sono tutti validi)

2.2. float
Un float è un numero in virgola mobile. In altre parole, il punto decimale può muoversi
secondo le necessità.
 valori float = un valore in virgola mobile a 64 bit, con circa 53 bit di risoluzione e oltre
1000 bit di intervallo dinamico.
Per maggiori informazioni sui numeri in virgola mobile vedi:
http://en.wikipedia.org/wiki/Floating_point
https://it.wikipedia.org/wiki/Numero_in_virgola_mobile
2.3. s32
Un numero s32 è un numero intero che può avere un valore negativo o positivo.
 valori s32 = numeri interi da -2147483648 a 2147483647

2.4. U32
Un numero u32 è un numero intero che è solo positivo.
 valori u32 = numeri interi da 0 a 4294967295

3. File HAL
Se hai utilizzato Stepper Config Wizard per generare la tua configurazione, avrai fino a tre file
HAL nella tua directory di configurazione.
 my-mill.hal (se la tua configurazione è denominata my-mill ) Questo file viene
caricato per primo e non deve essere modificato se hai utilizzato Stepper Config
Wizard.
 custom.hal Questo file viene caricato in seguito e prima che venga caricata la GUI.
Qui è dove metti i tuoi comandi HAL personalizzati che vuoi caricare prima che la GUI
sia caricata.
 custom_postgui.hal Questo file viene caricato dopo il caricamento della GUI. Qui è
dove metti i tuoi comandi HAL personalizzati che vuoi caricare dopo che la GUI è stata
caricata. Tutti i comandi HAL che usano i widget pyVCP devono essere posizionati
qui.

4. Componenti HAL
Due parametri vengono aggiunti automaticamente a ciascun componente HAL quando viene
creato. Questi parametri consentono di definire il tempo di esecuzione di un componente.
.tempo
.tmax
Il tempo è il numero di cicli della CPU necessari per eseguire la funzione.
tmax è il numero massimo di cicli della CPU necessari per eseguire la funzione. tmax è un
parametro di lettura / scrittura in modo che l'utente possa impostarlo su 0 per sbarazzarsi
della prima inizializzazione del tempo di esecuzione della funzione.

5. Componenti logici
HAL contiene diversi componenti logici in tempo reale. I componenti logici seguono una
tabella di verità che indica quale sia l'output per ogni dato input. Tipicamente questi sono
manipolatori di bit e seguono le tabelle di verità della porta logica elettrica.

5.1. and2
Il componente and2 è un gate and con due input. La tabella di verità sotto mostra l'output in
base a ciascuna combinazione di input.
Sintassi
and2 [count=N] | [nomi=nome1[, nome2 ...]]
funzioni
and2.n
Pins
and2.N.in0 (bit, in)
and2.N.in1 (bit, in)
and2.N.out (bit, out)
Tabella della verità
in0 in 1 out
falso falso falso
vero falso falso
falso vero falso
vero vero vero

5.2. not
Il not componente è un inverter bit.
Sintassi
not [count=n] | [nomi=nome1 [, nome2 ...]]
funzioni
not.all
not.n
Pins
not.n.in (bit, in)
not.n.out (bit, out)
Tabella della verità
in out
vero falso
falso vero

5.3. or2
Il componente or2 è un gate or a due ingressi.
Sintassi
or2 [count=n] | [nomi=nome1 [, nome2 ...]]
funzioni
or2.n
Pins
or2.n.in0 (bit, in)
or2.n.in1 (bit, in)
or2.n.out (bit, out)
Tabella della verità
in0 in 1 out
vero falso vero
vero vero vero
falso vero vero
falso falso falso

5.4. xor2
Il componente xor2 è un gate xor a due ingressi (or esclusivo).
Sintassi
xor2 [count = n] | [nomi = nome1 [, nome2 ...]]
funzioni
xor2.n
Pins
xor2.n.in0 (bit, in)
xor2.n.in1 (bit, in)
xor2.n.out (bit, fuori)
Tabella della verità
in0 in 1 out
vero falso vero
vero vero falso
falso vero vero
falso falso falso

5.5. Esempi di logica


Un esempio and2 che collega due ingressi a un'uscita.
loadrt and2 count=1
addf e2.0 servo-thread
net my-sigin1 and2.0.in0 <= parport.0.pin-11-in
net my-sigin2 and2.0.in1 <= parport.0.pin-12-in
net both-on parport.0.pin-14-out <= and2.0.out

Nell'esempio precedente una copia di and2 viene caricata nello spazio realtime e aggiunta al
thread del servo. Il pin 11 della porta parallela è collegato al bit in0 del gate and2. Il pin 12 è
collegato al bit in1 del gate and2. Infine colleghiamo il bit and2.out al pin 14 della porta
parallela. Quindi, seguendo la tabella di verità per and2 se il pin 11 e il pin 12 sono attivi,
allora il pin di uscita 14 sarà acceso.
6. Componenti di conversione
6.1. weighted_sum
Il weighted_sum converte un gruppo di bit in un numero intero. La conversione è la somma
dei pesi dei bit attivi più qualsiasi offset. Il peso del m-th bit è 2 ^ m. Questo è simile a un
decimale in codice binario ma con più opzioni. Il bit di attesa interrompe l'elaborazione delle
modifiche di input in modo che la somma non cambi.
La seguente sintassi viene utilizzata per caricare il componente weighted_sum.
loadrt weighted_sum wsum_sizes = size [, size, ...]
Crea gruppi di somma ponderati ciascuno con il numero dato di bit di input (dimensione).
Per aggiornare il weighted_sum è necessario allegare process_wsums a un thread.
addf process_wsums servo-thread
Questo aggiorna il componente weighted_sum.
Nell'esempio seguente, preso dalla finestra Configurazione HAL in Axis, i bit 0 e 2 sono veri e
non vi è alcun offset. Il peso di 0 è 1 e il peso di 2 è 4, quindi la somma è 5.
weighted_sum
Component Pins:
Owner Type Dir Value Name
10 bit In TRUE wsum.0.bit.0.in
10 s32 I/O 1 wsum.0.bit.0.weight
10 bit In FALSE wsum.0.bit.1.in
10 s32 I/O 2 wsum.0.bit.1.weight
10 bit In TRUE wsum.0.bit.2.in
10 s32 I/O 4 wsum.0.bit.2.weight
10 bit In FALSE wsum.0.bit.3.in
10 s32 I/O 8 wsum.0.bit.3.weight
10 bit In FALSE wsum.0.hold
10 s32 I/O 0 wsum.0.offset
10 s32 Out 5 wsum.0.sum
Tutorial di HAL
1. Introduzione
La configurazione si sposta adesso dalla teoria al dispositivo - che è il dispositivo HAL. Per
coloro che conoscono un po' di programmazione per computer, questa sezione è come un
Hello World di HAL. Halrun può essere utilizzato per creare un sistema funzionante. È uno
strumento da riga di comando o file di testo per la configurazione e l'ottimizzazione. I
seguenti esempi illustrano la sua configurazione e il suo funzionamento.

1.1. Notazione
I comandi del terminale vengono visualizzati senza il prompt di sistema, a meno che non si
esegua HAL. La finestra del terminale si trova in Applicazioni / Accessori dalla barra dei
menu principale di Linux.

Esempio di comando terminale


me @ computer: ~ linuxcnc
$ halrun
(verrà mostrato come la seguente riga)
halrun

(verrà mostrato il messaggio halcmd: prompt quando si esegue HAL)


halcmd: loadrt debounce
halcmd: show pin

1.2. Comandi di completamento


La tua versione di halcmd potrebbe includere il comando di completamento. Invece di
completare i nomi dei file come fa una shell, completa i comandi con identificatori HAL.
Dovrai digitare abbastanza lettere così da avere una corrispondenza unica. Prova a premere
TAB dopo aver avviato un comando HAL:

Completamento scheda
halcmd: loa<TAB>
halcmd: load
halcmd: loadrt
halcmd: loadrt deb<TAB>
halcmd: loadrt debounce

1.3. L'ambiente RTAPI


RTAPI è l'acronimo di Real Time Application Programming Interface. Molti componenti
HAL funzionano in tempo reale e tutti i componenti HAL memorizzano i dati nella memoria
condivisa in modo che i componenti in tempo reale possano accedervi. Normalmente Linux
non supporta la programmazione in tempo reale o il tipo di memoria condivisa di cui HAL ha
bisogno. Fortunatamente ci sono sistemi operativi in tempo reale (RTOS) che forniscono le
estensioni necessarie a Linux. Sfortunatamente, ogni RTOS fa le cose in modo leggermente
diverso.
Per affrontare queste differenze, il team di LinuxCNC ha creato RTAPI, che fornisce un modo
coerente per i programmi di comunicare con RTOS. Se sei un programmatore che vuole
lavorare sull'interno di LinuxCNC, potresti voler studiare linuxcnc / src / rtapi / rtapi.h per
capire l'API. Ma se sei una persona normale tutto quello che devi sapere su RTAPI è che (e
anche RTOS) deve essere caricato nella memoria del tuo computer prima di fare qualsiasi
cosa con HAL.

2. Un semplice esempio
2.1. Caricamento di un componente
Per questo tutorial, assumeremo che tu abbia installato correttamente LinuxCNC. In tal caso,
tutto ciò che devi fare è caricare i moduli RTOS e RTAPI richiesti in memoria. Basta eseguire
il seguente comando da una finestra di terminale:

Caricamento HAL

halrun
halcmd:

Con il sistema operativo in tempo reale e RTAPI caricato, possiamo passare al primo
esempio. Si noti che il prompt viene ora visualizzato come halcmd:. Questo perché i
comandi successivi saranno interpretati come comandi HAL, non comandi di shell.
Per il primo esempio, useremo un componente HAL chiamato siggen , che è un semplice
generatore di segnali. Una descrizione completa del componente siggen è disponibile nella
sezione Siggen del manuale. È un componente in tempo reale, implementato come modulo
del kernel di Linux. Per caricare siggen usa il comando HAL loadrt .

Caricamento siggen
halcmd: loadrt siggen

2.2. Esaminiamo l'HAL


Ora che il modulo è caricato, è ora di introdurre halcmd , lo strumento da riga di comando
utilizzato per configurare l'HAL. Questo tutorial introdurrà alcune funzioni di halcmd, per
una descrizione più completa prova man halcmd, o vedi il riferimento nella sezione Hal
Commands del manuale. La prima caratteristica di halcmd è il comando show. Questo
comando visualizza informazioni sullo stato attuale dell'HAL. Per mostrare tutti i componenti
installati:

Mostra componenti
halcmd: show comp

Loaded HAL Components:


ID Type Name PID State
3 RT siggen ready
2 User halcmd2177 2177 ready

Dato che halcmd stesso è un componente HAL, verrà sempre visualizzato nell'elenco. Il
numero dopo halcmd nell'elenco dei componenti è l'ID del processo. È possibile eseguire più
di una copia di halcmd contemporaneamente (ad esempio in finestre diverse), quindi il PID
viene aggiunto alla fine del nome per renderlo univoco. L'elenco mostra anche il componente
siggen che abbiamo installato nel passaggio precedente. Il RT sotto Type indica che siggen è
un componente in tempo reale. L' user in Type indica che si tratta di un componente dello
spazio utente.
Successivamente, vediamo quali pin siggen si rendono disponibili:

Mostra pin

halcmd: show pin

Owner Type Dir Value Name


4 float IN 1 siggen.0.amplitude
4 bit OUT FALSE siggen.0.clock
4 float OUT 0 siggen.0.cosine
4 float IN 1 siggen.0.frequency
4 float IN 0 siggen.0.offset
4 bit IN FALSE siggen.0.reset
4 float OUT 0 siggen.0.sawtooth
4 float OUT 0 siggen.0.sine
4 float OUT 0 siggen.0.square
4 float OUT 0 siggen.0.triangle
4 s32 OUT 0 siggen.0.update.time

Questo comando visualizza tutti i pin nell'HAL corrente. Un sistema complesso potrebbe
avere dozzine o centinaia di pin. Ma al momento ci sono solo undici pin. Di questi pin otto
sono in virgola mobile, due sono bit (booleani) e uno un intero con segno a 32 bit. Sette
forniscono i dati in uscita dal componente siggen e quattro vengono utilizzati per trasferire le
impostazioni verso il componente. Poiché non abbiamo ancora eseguito il codice contenuto
all'interno del componente, alcuni pin hanno un valore pari a zero.
Il prossimo passo è guardare i parametri:

Mostra parametri
halcmd: show param

Parameters:
Owner Type Dir Value Name
4 s32 RW 0 siggen.0.update.tmax
4 bit RO FALSE siggen.0.update.tmax-increased

Il comando show param mostra tutti i parametri nell'HAL. In questo momento ogni
parametro ha il valore predefinito che è stato dato quando il componente è stato caricato.
Notare la colonna con l'etichetta Dir. I parametri etichettati -W sono quelli scrivibili che non
vengono mai modificati dal componente stesso, ma sono destinati a essere modificati
dall'utente per controllare il componente. Vedremo come farlo più tardi. I parametri
etichettati R- sono parametri di sola lettura. Possono essere modificati solo dal componente.
Infine, i parametri con etichetta RW sono parametri di lettura-scrittura. Ciò significa che
vengono modificati dal componente, ma possono anche essere modificati dall'utente. Nota: i
parametri siggen.0.update.tmax e siggen.0.update.tmax-increased sono a scopo di debug e
non saranno trattati in questa sezione.
La maggior parte dei componenti in tempo reale esportano una o più funzioni per eseguire
effettivamente il codice in tempo reale che contengono. Vediamo quale funzioni siggen
esporta:
Mostra funzioni
halcmd: show funct

Exported Functions:
Owner CodeAddr Arg FP Users Name
00003 f801b000 fae820b8 YES 0 siggen.0.update

Il componente siggen ha esportato una singola funzione. Richiede la virgola mobile. Non è
attualmente collegato a nessun thread, quindi gli users sono zero.

2.3. Esecuzione del codice in tempo reale


Per eseguire effettivamente il codice contenuto nella funzione siggen.0.update , abbiamo
bisogno di un thread in tempo reale. Il componente chiamato thread che viene utilizzato per
creare un nuovo thread. Consente di creare un thread chiamato test-thread con un periodo
di 1 ms (1.000 s o 1.000.000 ns):
halcmd: loadrt threads name1=test-thread period1=1000000

Vediamo se ha funzionato:

Mostra thread
halcmd: show thread

Realtime Threads:
Period FP Name ( Time, Max-Time )
999855 YES test-thread ( 0, 0 )

Lo ha fatto. Il periodo potrebbe non essere esattamente 1.000.000 ns a causa delle


limitazioni hardware, ma abbiamo un thread che gira all'incirca alla velocità corretta e che
può gestire le funzioni in virgola mobile. Il prossimo passo è connettere la funzione al thread:

Aggiungi funzione
halcmd: addf siggen.0.update test-thread

Fino ad ora abbiamo usato halcmd solo per guardare l'HAL. Tuttavia, questa volta abbiamo
usato il comando addf (add function) per modificare effettivamente qualcosa nell'HAL .
Abbiamo detto a halcmd di aggiungere la funzione siggen.0.update al thread -thread-test, e
se guardiamo di nuovo l'elenco dei thread, vediamo che è riuscito:
halcmd: show thread

Realtime Threads:
Period FP Name ( Time, Max-Time )
999855 YES test-thread ( 0, 0 )
1 siggen.0.update

È necessario un ulteriore passaggio prima che il componente siggen inizi a generare segnali.
Quando l'HAL viene avviato per la prima volta, i thread non sono effettivamente in
esecuzione. Questo per consentire all'utente di configurare completamente il sistema prima
dell'avvio del codice in tempo reale. Una volta che sei soddisfatto della configurazione, puoi
iniziare il codice in tempo reale come questo:

halcmd: start

Ora il generatore di segnale è in esecuzione. Diamo un'occhiata ai suoi pin di uscita:


halcmd: show pin

Component Pins:
Owner Type Dir Value Name
4 float IN 1 siggen.0.amplitude
4 bit OUT FALSE siggen.0.clock
4 float OUT -0.7862885 siggen.0.cosine
4 float IN 1 siggen.0.frequency
4 float IN 0 siggen.0.offset
4 bit IN FALSE siggen.0.reset
4 float OUT -0.212 siggen.0.sawtooth
4 float OUT 0.6178596 siggen.0.sine
4 float OUT -1 siggen.0.square
4 float OUT -0.576 siggen.0.triangle
4 s32 OUT 2292 siggen.0.update.time
10 s32 OUT 2292 test-thread.time
E guardiamo di nuovo:
halcmd: show pin

Component Pins:
Owner Type Dir Value Name
4 float IN 1 siggen.0.amplitude
4 bit OUT TRUE siggen.0.clock
4 float OUT 0.8542775 siggen.0.cosine
4 float IN 1 siggen.0.frequency
4 float IN 0 siggen.0.offset
4 bit IN FALSE siggen.0.reset
4 float OUT 0.826 siggen.0.sawtooth
4 float OUT -0.5198173 siggen.0.sine
4 float OUT 1 siggen.0.square
4 float OUT 0.652 siggen.0.triangle
4 s32 OUT 2343 siggen.0.update.time
10 s32 OUT 2343 test-thread.time
Abbiamo fatto due comandi pin show in rapida successione, e puoi vedere che le uscite non
sono più zero. Le uscite seno, coseno, a dente di sega (sawtooth) e triangolo (triangle)
cambiano costantemente. Anche l'uscita quadrata (square) funziona, tuttavia passa
semplicemente da +1.0 a -1.0 ogni ciclo.

2.4. Modifica dei parametri


Il vero potere di HAL è che puoi cambiare le cose. Ad esempio, possiamo usare il comando
setp per impostare il valore di un parametro. Cambiamo l'ampiezza del generatore di segnali
da 1.0 a 5.0:

Imposta il pin
halcmd: setp siggen.0.amplitude 5
Controllare nuovamente i parametri e i pin

halcmd: show param

Parameters:
Owner Type Dir Value Name
Owner Type Dir Value Name
4 s32 RW 8541 siggen.0.update.tmax
4 bit RO FALSE siggen.0.update.tmax-increased
10 s32 RW 8541 test-thread.tmax

halcmd: show pin

Component Pins:
Owner Type Dir Value Name
4 float IN 5 siggen.0.amplitude
4 bit OUT FALSE siggen.0.clock
4 float OUT 4.842916 siggen.0.cosine
4 float IN 1 siggen.0.frequency
4 float IN 0 siggen.0.offset
4 bit IN FALSE siggen.0.reset
4 float OUT -4.6 siggen.0.sawtooth
4 float OUT 1.243449 siggen.0.sine
4 float OUT -5 siggen.0.square
4 float OUT 4.2 siggen.0.triangle
4 s32 OUT 3021 siggen.0.update.time
10 s32 OUT 3021 test-thread.time
Si noti che il valore del parametro siggen.0.amplitude è stato modificato in 5 e che i pin ora
hanno valori maggiori.

2.5. Salvataggio della configurazione HAL


La maggior parte di ciò che abbiamo fatto con halcmd finora ha semplicemente visto le cose
con il comando show . Tuttavia due dei comandi hanno effettivamente cambiato le cose.
Mentre progettiamo sistemi più complessi con HAL, useremo molti comandi per configurare
le cose nel modo in cui le vogliamo. HAL ha la memoria di un elefante e manterrà quella
configurazione finché non la spegneremo. E la prossima volta? Non vogliamo inserire
manualmente una serie di comandi ogni volta che vogliamo utilizzare il sistema. Possiamo
salvare la configurazione dell'intero HAL con un singolo comando:
Salvare
halcmd: save
# components
loadrt siggen
loadrt threads name1=test-thread period1=1000000
#loadrt __test-thread (not loaded by loadrt, no args saved)
# pin aliases
# param aliases
# signals
# nets
# parameter values
setp siggen.0.update.tmax 8541
setp test-thread.tmax 8541
# realtime thread/function links
addf siggen.0.update test-thread
L'output del comando save è una sequenza di comandi HAL.
Se inizi con un HAL vuoto ed esegui questi comandi, otterrai la configurazione esistente al
momento del comando di save (salvataggio). Per salvare questi comandi per un uso futuro,
semplicemente reindirizziamo l'output a un file:

Salva in un file
halcmd: save all saved.hal

2.6. Uscire da Halrun


Quando hai finito con la sessione HAL, scrivi exit al prompt halcmd : . Questo ti restituirà il
prompt di sistema e chiuderà la sessione HAL. Non chiudere semplicemente la finestra del
terminale senza chiudere prima la sessione HAL.

Esci da HAL
halcmd: exit

2.7. Ripristino della configurazione HAL


Per ripristinare la configurazione HAL memorizzata in saved.hal , dobbiamo eseguire tutti
questi comandi HAL. Per fare ciò, usiamo -f <nome file> che legge i comandi da un file, e -I
(maiuscolo i) che mostra il prompt halcmd dopo l'esecuzione dei comandi:

Esegui un file salvato


halrun -I -f saved.hal

Si noti che non esiste un comando di start in saved.hal. È necessario scriverlo nuovamente
(oppure modificare saved.hal per aggiungerlo lì).

2.8. Rimozione di HAL dalla memoria


Se si verifica uno arresto imprevisto di una sessione HAL, potrebbe essere necessario
scaricare HAL prima che possa iniziare un'altra sessione. Per fare questo digitare il seguente
comando in una finestra di terminale.

Rimozione di HAL
halrun -U

3. Halmeter
È possibile creare sistemi HAL molto complessi senza mai utilizzare un'interfaccia grafica.
Tuttavia, c'è qualcosa di soddisfacente nel vedere il risultato del tuo lavoro. Il primo e più
semplice strumento GUI per l'HAL è Halmeter. È un programma molto semplice che è
l'equivalente HAL del pratico multimetro Fluke (o simulatore analogico Simpson per i vecchi
temporizzatori).
Utilizzeremo nuovamente il componente siggen per verificare l'halmeter. Se hai appena
terminato l'esempio precedente, puoi caricare siggen utilizzando il file salvato. Altrimenti
possiamo caricarlo proprio come facevamo prima:
halrun
halcmd: loadrt siggen
halcmd: loadrt threads name1=test-thread period1=1000000
halcmd: addf siggen.0.update test-thread
halcmd: start
halcmd: setp siggen.0.amplitude 5

A questo punto abbiamo il componente siggen caricato e funzionante. È tempo di avviare


Halmeter.

Avvio Halmeter
halcmd: loadusr halmeter

La prima finestra che vedrai è la finestra Select Item to Probe (Seleziona oggetto da
Esaminare) .

Figura 1. Finestra di selezione Halmeter

Questa finestra di dialogo ha tre schede. La prima scheda mostra tutti i pin HAL nel sistema.
Il secondo mostra tutti i segnali e il terzo visualizza tutti i parametri. Vorremmo prima
esaminare il pin siggen.0.cosine , quindi fare clic su di esso e quindi fare clic sul pulsante
Close (Chiudi) . La finestra di selezione della sonda si chiuderà e il misuratore assomiglierà
alla seguente figura.

Figura 2. Halmeter
Per cambiare il display del misuratore, premere il pulsante Select che riporta la finestra Select
item to probe (Seleziona oggetto da Esaminare).
Dovresti vedere il valore cambiare mentre siggen genera la sua onda di coseno. L'halmeter
aggiorna il suo display circa 5 volte al secondo.
Per spegnere l'halmeter, fai clic sul pulsante di uscita.
Se si desidera guardare più di un pin, segnale o parametro alla volta, è possibile avviare più
halmeters. La finestra dell’ halmeter è stata intenzionalmente realizzata in modo molto
piccolo in modo da poterli visualizzare sullo schermo in una volta sola.

4. Esempio di Stepgen
Fino ad ora abbiamo caricato solo un componente HAL. Ma l'idea alla base dell'HAL è quella
di consentire di caricare e connettere un numero di componenti semplici per creare un
sistema complesso. Il prossimo esempio userà due componenti.
Prima di iniziare a costruire questo nuovo esempio, vogliamo iniziare con una lavagna pulita.
Se hai appena terminato uno degli esempi precedenti, dobbiamo rimuovere tutti i
componenti e ricaricare le librerie RTAPI e HAL.
halcmd: exit

4.1. Installazione dei componenti


Ora andremo a caricare il componente del generatore di impulsi di passo. Per una
descrizione dettagliata di questo componente, fare riferimento alla sezione stepgen del
Manuale dell'integratore. In questo esempio useremo il tipo di controllo della velocità di
stepgen. Per ora, possiamo saltare i dettagli, e basta eseguire i seguenti comandi.
halrun
halcmd: loadrt stepgen step_type=0,0 ctrl_type=v,v
halcmd: loadrt siggen
halcmd: loadrt threads name1=fast fp1=0 period1=100000 name2=slow period2=1000000

Il primo comando carica due generatori di passi, entrambi configurati per generare step di
tipo 0. Il secondo comando carica il nostro vecchio amico siggen, e il terzo crea due thread,
uno fast (veloce) con un periodo di 100 microsecondi e uno slow (lento) con un periodo di
tempo 1 millisecondo. Il thread veloce non supporta le funzioni in virgola mobile.
Come prima, possiamo usare halcmd show per dare un'occhiata all'HAL. Questa volta
abbiamo molti più pin e parametri rispetto a prima:
halcmd: show pin

Component Pins:
Owner Type Dir Value Name
11 s32 OUT 0 fast.time
7 float IN 1 siggen.0.amplitude
7 bit OUT FALSE siggen.0.clock
7 float OUT 0 siggen.0.cosine
7 float IN 1 siggen.0.frequency
7 float IN 0 siggen.0.offset
7 bit IN FALSE siggen.0.reset
7 float OUT 0 siggen.0.sawtooth
7 float OUT 0 siggen.0.sine
7 float OUT 0 siggen.0.square
7 float OUT 0 siggen.0.triangle
7 s32 OUT 0 siggen.0.update.time
12 s32 OUT 0 slow.time
4 s32 OUT 0 stepgen.0.counts
4 bit OUT FALSE stepgen.0.dir
4 bit IN FALSE stepgen.0.enable
4 float OUT 0 stepgen.0.position-fb
4 bit OUT FALSE stepgen.0.step
4 float IN 0 stepgen.0.velocity-cmd
4 s32 OUT 0 stepgen.1.counts
4 bit OUT FALSE stepgen.1.dir
4 bit IN FALSE stepgen.1.enable
4 float OUT 0 stepgen.1.position-fb
4 bit OUT FALSE stepgen.1.step
4 float IN 0 stepgen.1.velocity-cmd
4 s32 OUT 0 stepgen.capture-position.time
4 s32 OUT 0 stepgen.make-pulses.time
4 s32 OUT 0 stepgen.update-freq.time

halcmd: show param

Parameters:
Owner Type Dir Value Name
11 s32 RW 0 fast.tmax
7 s32 RW 0 siggen.0.update.tmax
7 bit RO FALSE siggen.0.update.tmax-increased
12 s32 RW 0 slow.tmax
4 u32 RW 0x00000001 stepgen.0.dirhold
4 u32 RW 0x00000001 stepgen.0.dirsetup
4 float RO 0 stepgen.0.frequency
4 float RW 0 stepgen.0.maxaccel
4 float RW 0 stepgen.0.maxvel
4 float RW 1 stepgen.0.position-scale
4 s32 RO 0 stepgen.0.rawcounts
4 u32 RW 0x00000001 stepgen.0.steplen
4 u32 RW 0x00000001 stepgen.0.stepspace
4 u32 RW 0x00000001 stepgen.1.dirhold
4 u32 RW 0x00000001 stepgen.1.dirsetup
4 float RO 0 stepgen.1.frequency
4 float RW 0 stepgen.1.maxaccel
4 float RW 0 stepgen.1.maxvel
4 float RW 1 stepgen.1.position-scale
4 s32 RO 0 stepgen.1.rawcounts
4 u32 RW 0x00000001 stepgen.1.steplen
4 u32 RW 0x00000001 stepgen.1.stepspace
4 s32 RW 0 stepgen.capture-position.tmax
4 bit RO FALSE stepgen.capture-position.tmax-increased
4 s32 RW 0 stepgen.make-pulses.tmax
4 bit RO FALSE stepgen.make-pulses.tmax-increased
4 s32 RW 0 stepgen.update-freq.tmax
4 bit RO FALSE stepgen.update-freq.tmax-increased

4.2. Collegamento di pin con segnali


Quello che abbiamo sono due generatori di impulsi e un generatore di segnale. Ora è il
momento di creare alcuni segnali HAL per collegare i due componenti. Faremo finta che i
due generatori di impulsi a step stiano guidando l'asse X e Y della tavola di una macchina.
Vogliamo spostare la tavola in modo circolare. Per fare ciò, invieremo un segnale coseno
all'asse X e un segnale sinusoidale all'asse Y. Il modulo siggen crea il seno e il coseno, ma
abbiamo bisogno di fili per collegare i moduli insieme. Nell'HAL, i fili sono chiamati segnali.
Dobbiamo crearne due. Possiamo chiamarli come vogliamo, per questo esempio saranno X-
vel e Y-vel. Il segnale X-vel è progettato per andare dall'uscita del coseno del generatore di
segnali all'ingresso di velocità del primo generatore di impulsi di passo. Il primo passo è
connettere il segnale all'uscita del generatore di segnale. Per collegare un segnale a un pin
usiamo il comando net.

comando net
halcmd: net X-vel <= siggen.0.cosine

Per vedere l'effetto del comando net , mostriamo di nuovo i segnali.


halcmd: show sig

Signals:
Type Value Name (linked to)
float 0 X-vel <== siggen.0.cosine
Quando un segnale è collegato a uno o più pin, il comando show elenca i pin immediatamente
successivi al nome del segnale. La freccia mostra la direzione del flusso di dati - in questo
caso, i flussi di dati vanno dal pin siggen.0.cosine al segnale X-vel. Ora colleghiamo l' X-vel
all'ingresso di velocità di un generatore di impulsi di passo.
halcmd: net X-vel => stepgen.0.velocity-cmd

Possiamo anche collegare il segnale dell'asse Y Y-vel . È progettato per funzionare dall'uscita
sinusoidale del generatore di segnali all'ingresso del generatore di impulsi del secondo stadio.
Il seguente comando realizza in una riga i due comandi netti ottenuti per X-vel .
halcmd: net Y-vel siggen.0.sine => stepgen.1.velocity-cmd

Ora diamo un'ultima occhiata ai segnali e ai pin collegati ad essi.


halcmd: show sig

Signals:
Type Value Name (linked to)
float 0 X-vel <== siggen.0.cosine
==> stepgen.0.velocity-cmd
float 0 Y-vel <== siggen.0.sine
==> stepgen.1.velocity-cmd
Il comando show sig chiarisce esattamente come i dati attraversano l'HAL. Ad esempio, il
segnale X-vel proviene da pin siggen.0.cosine e passa al pin stepgen.0.velocity-cmd.

4.3. Configurare l'esecuzione in tempo reale - thread e funzioni


Pensare ai dati che fluiscono attraverso i fili rende i pin e i segnali abbastanza facili da capire.
Thread e funzioni sono un po' più difficili. Le funzioni contengono le istruzioni del computer
che in realtà portano a termine le cose. Thread è il metodo utilizzato per eseguire quelle
istruzioni quando sono necessarie. Per prima cosa esaminiamo le funzioni a nostra
disposizione.
halcmd: show funct

Exported Functions:
Owner CodeAddr Arg FP Users Name
00004 f9992000 fc731278 YES 0 siggen.0.update
00003 f998b20f fc7310b8 YES 0 stepgen.capture-position
00003 f998b000 fc7310b8 NO 0 stepgen.make-pulses
00003 f998b307 fc7310b8 YES 0 stepgen.update-freq
In generale, dovrai fare riferimento alla documentazione di ciascun componente per vedere
quali sono le sue funzioni. In questo caso, la funzione siggen.0.update viene utilizzata per
aggiornare le uscite del generatore di segnali. Ogni volta che viene eseguito, calcola i valori
delle uscite seno, coseno, triangolo e quadrato. Per ottenere segnali uniformi, deve essere
eseguito a intervalli specifici.
Le altre tre funzioni sono correlate ai generatori di impulsi di passo.
Il primo, stepgen.capture_position, viene utilizzato per il feedback di posizione. Cattura il
valore di un contatore interno che conta gli impulsi di passo mentre vengono generati.
Supponendo che non ci siano step mancanti, questo contatore indica la posizione del motore.
La funzione principale per il generatore di impulsi di passo è stepgen.make_pulses. Ogni
volta che viene eseguito make_pulses , decide se è il momento di fare un passo, e in tal caso
imposta le uscite di conseguenza. Per gli impulsi graduali regolari, dovrebbe funzionare il più
frequentemente possibile. Poiché ha bisogno di correre così velocemente, make_pulses è
altamente ottimizzato ed esegue solo alcuni calcoli. A differenza degli altri, non ha bisogno di
matematica in virgola mobile.
L'ultima funzione, stepgen.update-freq, è responsabile del ridimensionamento e di altri
calcoli che devono essere eseguiti solo quando il comando di frequenza cambia.
Ciò che questo significa per il nostro esempio è che vogliamo eseguire siggen.0.update a una
velocità moderata per calcolare i valori seno e coseno. Immediatamente dopo aver eseguito
siggen.0.update, vogliamo eseguire stepgen.update_freq per caricare i nuovi valori nel
generatore di impulsi di passo. Infine, dobbiamo eseguire stepgen.make_pulses il più
velocemente possibile per impulsi regolari. Poiché non usiamo il feedback sulla posizione,
non è necessario eseguire stepgen.capture_position.
Eseguiamo le funzioni aggiungendole ai thread. Ogni thread viene eseguito a una velocità
specifica. Vediamo quali thread abbiamo a disposizione.
halcmd: show thread
Realtime Threads:

Realtime Threads:
Period FP Name ( Time, Max-Time )
1000000 YES slow ( 0, 0 )
100000 NO fast ( 0, 0 )

I due thread sono stati creati quando abbiamo caricato i threads. Il primo, slow , viene
eseguito ogni millisecondo ed è in grado di eseguire funzioni in virgola mobile. Lo useremo
per siggen.0.update e stepgen.update_freq. Il secondo thread è fast , che viene eseguito ogni
100 microsecondi e non supporta il punto mobile. Lo useremo per stepgen.make_pulses. Per
collegare le funzioni al thread corretto, usiamo il comando addf. Specifichiamo prima la
funzione, seguita dal thread.
halcmd: addf siggen.0.update slow
halcmd: addf stepgen.update-freq slow
halcmd: addf stepgen.make-pulses fast

Dopo aver dato questi comandi, possiamo eseguire nuovamente il comando show thread per
vedere cosa è successo.
halcmd: show thread
Realtime Threads:
Period FP Name ( Time, Max-Time )
1000000 YES slow ( 0, 0 )
1 siggen.0.update
2 stepgen.update-freq
100000 NO fast ( 0, 0 )
1 stepgen.make-pulses

Ora ogni thread è seguito dai nomi delle funzioni, nell'ordine in cui verranno eseguite le
funzioni.

4.4. Impostazione dei parametri


Siamo quasi pronti per iniziare il nostro sistema HAL. Tuttavia, dobbiamo ancora regolare
alcuni parametri. Per impostazione predefinita, il componente siggen genera segnali che
oscillano da +1 a -1. Per il nostro esempio va bene, vogliamo che la velocità della tavola vari
da +1 a -1 pollici al secondo. Tuttavia, il ridimensionamento del generatore di impulsi di
passo non è del tutto corretto. Per impostazione predefinita, genera una frequenza di uscita
di 1 passo al secondo con un ingresso di 1.000. È improbabile che un passo al secondo ci dia
un pollice al secondo del movimento del tavolo. Supponiamo invece di avere una vite passo-
passo da 5 giri per pollice, collegata a un motore passo-passo con 200 passi per giro e con
microstepping 10x. Quindi ci vogliono 2000 passi per un giro della vite e 5 giri per muoversi
di un pollice. Ciò significa che il ridimensionamento globale è di 10000 passi per pollice.
Abbiamo bisogno di moltiplicare l'ingresso di velocità al generatore di impulsi di passo per
10000 per ottenere l'uscita corretta. Questo è esattamente ciò per cui è il parametro
stepgen.n.velocity-scale. In questo caso, sia l'asse X che Y hanno lo stesso
ridimensionamento, quindi impostiamo i parametri di ridimensionamento per entrambi a
10000.
halcmd: setp stepgen.0.position-scale 10000
halcmd: setp stepgen.1.position-scale 10000
halcmd: setp stepgen.0.enable 1
halcmd: setp stepgen.1.enable 1

Questo ridimensionamento della velocità significa che quando il pin stepgen.0.velocity-cmd è


1.000, il generatore di passi genererà 10000 impulsi al secondo (10 KHz). Con il motore e la
vite di comando descritti sopra, l'asse si muoverà esattamente a 1.000 pollici al secondo.
Questo illustra un concetto chiave di HAL - cose come il ridimensionamento sono fatte al
livello più basso possibile, in questo caso nel generatore di impulsi di passo. Il segnale
interno X-vel è la velocità della tavola in pollici al secondo, e altri componenti come siggen
non conoscono (o si preoccupano) del ridimensionamento del tutto. Se avessimo cambiato la
vite o il motore, avremmo modificato solo il parametro di scala del generatore di impulsi di
passo.

4.5. Avvio!
Ora abbiamo tutto configurato e pronto per l'avvio. Proprio come nel primo esempio,
usiamo il comando start .
halcmd: start

Anche se non sembra accadere nulla, all'interno del computer il generatore di impulsi di
passo sta sfogliando gli impulsi di passo, variando da 10 KHz in avanti a 10 KHz in
retromarcia e viceversa. Più avanti in questo tutorial vedremo come far uscire quei segnali
interni per far funzionare i motori nel mondo reale, ma prima vogliamo esaminarli e vedere
cosa sta succedendo.
5. Halscope
L'esempio precedente genera alcuni segnali molto interessanti. Ma gran parte di ciò che
accade è troppo veloce per essere visto con l'halmeter. Per dare un'occhiata più da vicino a
cosa sta succedendo all'interno dell'HAL, vogliamo un oscilloscopio. Fortunatamente HAL ne
ha uno, chiamato halscope.
Halscope ha due parti: una parte in tempo reale che viene caricata come modulo del kernel e
una parte utente che fornisce la GUI e il display. Tuttavia, non devi preoccuparti di questo,
perché la porzione dello spazio utente richiederà automaticamente che venga caricata la parte
in tempo reale. Si noti inoltre che la prima volta che si esegue halscope in una directory viene
visualizzato un messaggio di warning che avverte che il file autosave.halscope non può essere
aperto.

Avvio di Halscope
halcmd: loadusr halscope
halcmd: halscope: config file 'autosave.halscope' could not be opened

Si aprirà la finestra della GUI dell'oscilloscopio, immediatamente seguita da una finestra di


dialogo in tempo reale non collegata che assomiglia alla figura seguente.

Figura 3. Finestra di dialogo in tempo reale non collegata


Questa finestra di dialogo è quella dove si imposta la frequenza di campionamento per
l'oscilloscopio. Per ora vogliamo campionare una volta al millisecondo, quindi fare clic sul
thread 989 us lento e lasciare il moltiplicatore a 1. Lasciamo anche la lunghezza del record a
4000 campioni, in modo che possiamo usare fino a quattro canali contemporaneamente.
Quando selezioni un thread e fai clic su OK, la finestra di dialogo scompare e la finestra
dell'oscilloscopio assomiglia alla figura seguente.

Figura 4. Finestra dell'ambito iniziale

5.1. Agganciare le sonde dell'oscilloscopio


A questo punto, Halscope è pronto per l'uso. Abbiamo già selezionato una frequenza di
campionamento e una lunghezza di registrazione, quindi il prossimo passo è decidere cosa
guardare. Ciò equivale ad agganciare le sonde dell'ambito virtuale all'HAL. Halscope ha 16
canali, ma il numero che puoi utilizzare in qualsiasi momento dipende dalla lunghezza del
record - più canali significano record più brevi, poiché la memoria disponibile per il record è
fissata a circa 16.000 campioni.
I pulsanti dei canali attraversano la parte inferiore della schermata di Halscope. Fare clic sul
pulsante 1 e verrà visualizzata la finestra di dialogo Seleziona sorgente del canale, come
mostrato nella seguente figura. Questa finestra di dialogo è molto simile a quella utilizzata da
Halmeter. Vorremmo guardare i segnali che abbiamo definito in precedenza, quindi facciamo
clic sulla scheda Segnali e la finestra di dialogo mostra tutti i segnali nell'HAL (solo due per
questo esempio).
Figura 5. Seleziona la sorgente del canale

Per scegliere un segnale, basta fare clic su di esso. In questo caso, vogliamo che il canale 1
mostri il segnale X-vel . Fare clic sulla scheda Segnali quindi fare clic su X-vel e la finestra di
dialogo si chiude e il canale è ora selezionato.

Figura 6. Seleziona segnale

Il pulsante del canale 1 viene premuto e il numero del canale 1 e il nome X-vel appaiono sotto
la fila di pulsanti. Quella visualizzazione indica sempre il canale selezionato - è possibile
avere molti canali sullo schermo, ma quello selezionato viene evidenziato e i vari controlli
come la posizione verticale e la scala funzionano sempre su quella selezionata.
Figura 7. Halscope

Per aggiungere un segnale al canale 2, fare clic sul pulsante 2 . Quando viene visualizzata la
finestra di dialogo, fai clic sulla scheda Segnali , quindi fai clic su Y-vel . Vogliamo anche
guardare le uscite a onda quadrata e triangolare. Non ci sono segnali collegati a quei pin,
quindi usiamo invece la scheda Pins. Per il canale 3, selezionare siggen.0.triangle e per il
canale 4, selezionare siggen.0.square .

5.2. Catturare le nostre prime forme d'onda


Ora che abbiamo diverse sonde collegate all'HAL, è tempo di catturare alcune forme d'onda.
Per avviare l'oscilloscopio, fare clic sul pulsante Normale nella sezione Modo Operativo dello
schermo (in alto a destra). Dato che abbiamo una lunghezza di registrazione di 4000
campioni e stiamo acquisendo 1000 campioni al secondo, Halscope starà per circa 2 secondi
a riempire metà del suo buffer. Durante quel tempo una barra di avanzamento appena sopra
la schermata principale mostrerà il riempimento del buffer. Una volta che il buffer è pieno a
metà, lo scope attende un trigger. Dal momento che non ne abbiamo ancora configurato uno,
aspetterà per sempre. Per attivarlo manualmente, fai clic sul pulsante Forza nella sezione
Trigger in alto a destra. Dovresti vedere il resto del riempimento del buffer, quindi lo
schermo mostrerà le forme d'onda catturate. Il risultato sarà simile alla seguente figura.
Figura 8. Forme d'onda catturate

La casella Selected Channel (Canale selezionato) in basso ti dice che la traccia viola è quella
attualmente selezionata, il canale 4, che sta visualizzando il valore del pin siggen.0.square .
Prova a fare clic sui pulsanti dei canali da 1 a 3 per evidenziare le altre tre tracce.

5.3. Regolazioni verticali


Le tracce sono piuttosto difficili da distinguere poiché tutte e quattro sono uno sopra l'altra.
Per risolvere questo problema, utilizziamo i controlli Verticali nella casella a destra dello
schermo. Questi controlli agiscono sul canale attualmente selezionato. Quando si regola il
guadagno, si noti che copre una vasta gamma - a differenza di un ambito reale, questo può
visualizzare segnali che vanno da minuscole (unità Pico) a molto grandi (unità Tera). Il
controllo di posizione sposta la traccia visualizzata su e giù solo all'altezza dello schermo. Per
le regolazioni più ampie è necessario utilizzare il pulsante offset.
Figura 9. Regolazione verticale

5.4. Attivazione (Triggering)


L'uso del pulsante Forza è un modo piuttosto insoddisfacente per attivare l'ambito. Per
impostare il trigger reale, fai clic sul pulsante Sorgente in basso a destra. Apparirà la finestra
di dialogo Trigger Source, che è semplicemente una lista di tutte le sonde che sono
attualmente connesse. Seleziona un probe da utilizzare per l'attivazione facendo clic su di
esso. Per questo esempio useremo il canale 3, l'onda triangolare come mostrato nella figura
seguente.

Figura 10. Finestra di dialogo Trigger Source


Dopo aver impostato la sorgente del trigger, puoi regolare il livello di trigger e la posizione di
trigger usando i cursori nella casella Trigger lungo il lato destro. Il livello può essere regolato
dall'alto verso il basso dello schermo e viene visualizzato sotto i cursori. La posizione è la
posizione del punto di trigger all'interno del record complessivo. Con il cursore verso il basso,
il punto di trigger si trova alla fine del record e Halscope visualizza ciò che è accaduto prima
del punto di trigger. Quando il cursore è completamente sollevato, il punto di trigger si trova
all'inizio del record, visualizzando ciò che è accaduto dopo che è stato attivato. Il punto di
trigger è visibile come una linea verticale nella finestra di avanzamento sopra lo schermo. La
polarità del trigger può essere modificata facendo clic sul pulsante appena sotto il display del
livello di trigger.
Ora che abbiamo regolato i controlli verticali e l'attivazione, la visualizzazione
dell'oscilloscopio assomiglia alla figura seguente.

Figura 11. Forme d'onda con trigger

5.5. Regolazioni orizzontali


Per osservare da vicino una parte di una forma d'onda, puoi utilizzare il cursore di zoom nella
parte superiore dello schermo per espandere le forme d'onda orizzontalmente e il cursore di
posizione per determinare quale parte della forma d'onda ingrandita è visibile. Tuttavia, a
volte semplicemente espandendo le forme d'onda non è sufficiente ed è necessario aumentare
la frequenza di campionamento. Ad esempio, vorremmo esaminare gli impulsi di passo
effettivi generati nel nostro esempio. Poiché gli impulsi di passo possono essere solo lunghi
50, il campionamento a 1KHz non è abbastanza veloce. Per modificare la frequenza di
campionamento, fare clic sul pulsante che visualizza il numero di campioni e frequenza di
campionamento per visualizzare la finestra di dialogo Seleziona velocità campionamento,
figura 12. Per questo esempio, faremo clic sul thread 50 us, fast (veloce), che ci fornisce una
frequenza di campionamento di circa 20 KHz. Ora invece di visualizzare circa 4 secondi di
dati, un record è di 4000 campioni a 20 KHz, o circa 0.20 secondi.

Figura 12. Finestra di dialogo Sample Rate

5.6. Più canali


Ora guardiamo gli impulsi del passo. Halscope ha 16 canali, ma per questo esempio ne
usiamo solo 4 alla volta. Prima di selezionare altri canali, dobbiamo disattivarne un paio.
Fare clic sul pulsante canale 2, quindi fare clic sul pulsante Chan Off (Canale off) nella parte
inferiore della casella Verticale . Quindi fai clic sul canale 3, gira su off, e fai lo stesso per il
canale 4. Anche se i canali sono disattivati, ricordano ancora a cosa sono connessi, e infatti
continueremo a utilizzare il canale 3 come sorgente di trigger. Per aggiungere nuovi canali,
selezionare il canale 5 e scegliere pin stepgen.0.dir, quindi canale 6 e selezionare
stepgen.0.step. Quindi fare clic su modalità di esecuzione Normale per avviare l'oscilloscopio
e regolare lo zoom orizzontale su 5 ms per divisione. Dovresti vedere gli impulsi di passo
rallentare mentre il comando di velocità (canale 1) si avvicina a zero, quindi il pin di direzione
cambia stato e gli impulsi di passo accelerano di nuovo. Potresti voler aumentare il guadagno
sul canale 1 a circa 20 millisec per divisione per vedere meglio il cambiamento nel comando
di velocità. Il risultato dovrebbe assomigliare alla seguente figura.
Figura 13. Step Pulses

5.7. Più campioni


Se si desidera registrare più campioni contemporaneamente, riavviare il realtime e caricare
halscope con un argomento numerico che indica il numero di campioni che si desidera
acquisire.
halcmd: loadusr halscope 80000

Se il componente scope_rt non è già stato caricato, halscope lo caricherà e richiederà 80000
campioni totali, in modo che durante il campionamento di 4 canali alla volta ci saranno
20000 campioni per canale. (Se scope_rt è già stato caricato, l'argomento numerico di
halscope non avrà alcun effetto).
Descrizioni dei componenti HAL
Sommario
1. Stepgen
2. PWMgen
3. Encoder
4. PID
5. Simulated Encoder
6. Debounce
7. Siggen
8. lut5

1. Stepgen
Questo componente fornisce una generazione basata su software di impulsi di passo in
risposta a comandi di posizione o di velocità. In modalità posizione, ha un loop di posizione
pre-calibrato, quindi la calibrazione PID non è necessaria. In modalità velocità, guida un
motore alla velocità comandata, rispettando i limiti di velocità e accelerazione. È un
componente solo in tempo reale e, a seconda della velocità della CPU, ecc., è in grado di
raggiungere velocità massime tra i 10kHz fino a 50kHz. Il diagramma a blocchi del
generatore di impulsi di passo mostra tre diagrammi a blocchi, ciascuno dei quali è un
generatore di impulsi a singola fase. Il primo diagramma è per il tipo di step 0, (passo e
direzione). Il secondo è per il tipo di step 1 (su / giù o pseudo-PWM) e il terzo è per i tipi di
step da 2 a 14 (vari schemi di stepping). I primi due diagrammi mostrano il controllo della
modalità di posizione, mentre il terzo mostra la modalità di velocità. La modalità di controllo
e il tipo di passo sono impostati in modo indipendente e qualsiasi combinazione può essere
selezionata.
Diagramma a blocchi generatore impulsi

Installazione
halcmd: loadrt stepgen step_type=<type-array> [ctrl_type=<ctrl_array>]
<type-array> è una serie di numeri decimali separati da virgola. Ogni numero fa sì che
venga caricato un generatore di impulsi a singola fase, il valore del numero determina il tipo
di passo. <ctrl_array> è una serie separata da virgola di caratteri p o v , per specificare la
posizione o la modalità di velocità. ctrl_type è facoltativo, se omesso, tutti i generatori di
passi saranno in modalità posizione.
Per esempio:
halcmd: loadrt stepgen step_type=0,0,2 ctrl_type=p,p,v
installerà tre generatori a step. I primi due usano il tipo di passo 0 (passo e direzione) e
funzionano in modalità posizione. L'ultimo utilizza il tipo di passo 2 (quadratura) e funziona
in modalità velocità. Il valore predefinito per <config-array> è 0,0,0 che installerà tre
generatori di tipo 0 (passo / dir). Il numero massimo di generatori di passi è 8 (come definito
da MAX_CHAN in stepgen.c). Ogni generatore è indipendente, ma tutti sono aggiornati dalla
stessa funzione allo stesso momento. Nelle seguenti descrizioni, <chan> è il numero di un
generatore specifico. Il primo generatore è il numero 0.
Rimozione
halcmd: unloadrt stepgen
pins
Ogni generatore di impulsi di passo avrà solo alcuni di questi pin, a seconda del tipo di passo
e del tipo di controllo selezionato.

 (float) stepgen. <chan>.position-cmd - Posizione del motore desiderata, in unità di


posizione (solo in modalità posizione).
 (float) stepgen. <chan>.velocity-cmd - Velocità motore desiderata, in unità di
posizione al secondo (solo modalità velocità).
 (s32) stepgen. <chan>.accounts - Posizione di feedback nei conteggi, aggiornata da
capture_position () .
 (float) stepgen. <chan>.position-fb - Posizione di feedback in unità di posizione,
aggiornata da capture_position () .
 (bit) stepgen. <chan>.enable - Abilita i passi di output - quando è falso, non vengono
generati passaggi.
 (bit) stepgen. <chan>.step - Step pulse output (solo step type 0).
 (bit) stepgen. <chan>.dir - Output di direzione (solo tipo di passaggio 0).
 (bit) stepgen. <chan>.up - UP output pseudo-PWM (solo tipo step 1).
 (bit) stepgen. <chan>.down - DOWN output pseudo-PWM (solo tipo step 1).
 (bit) stepgen. <chan>.phase-A - Uscita fase A (solo tipi di step 2-14).
 (bit) stepgen. <chan>.phase-B - Uscita fase B (solo tipi di step 2-14).
 (bit) stepgen. <chan>.phase-C - Uscita fase C (solo tipi di step 3-14).
 (bit) stepgen. <chan>.phase-D - Uscita fase D (solo tipi di step 5-14).
 (bit) stepgen. <chan>.phase-E - Uscita fase E (solo tipi di step 11-14).

parametri

 (float) stepgen.<chan>.position-scale - Steps per unità di posizione. Questo


parametro viene utilizzato sia per l'output che per il feedback.
 (float) stepgen. <chan>.maxvel - Velocità massima, in unità di posizione al secondo.
Se 0.0, non ha effetto.
 (float) stepgen. <chan>.maxaccel - Velocità massima di accelerazione / decelerazione,
in unità di unità al secondo al quadrato. Se 0.0, non ha effetto.
 (float) stepgen. <chan>.frequency - La frequenza di passo corrente, in passi al
secondo.
 (float) stepgen.<chan>.steplen - Lunghezza di un impulso di passo (tipo di passo 0 e
1) o tempo minimo in un determinato stato (tipi di step 2-14), in nano secondi.
 (float) stepgen.<chan>.stepspace - Distanza minima tra due impulsi di passo (solo i
tipi di passaggio 0 e 1), in nano secondi. Impostare su 0 per abilitare la funzione
stepgen doublefreq . Per utilizzare doublefreq, la funzione di reimpostazione parport
deve essere abilitata.
 (float) stepgen.<chan>.dirsetup - Tempo minimo da una variazione di direzione
all'inizio dell'impulso di passo successivo (solo il tipo di passaggio 0), in nanosecondi.
 (float) stepgen.<chan>.dirhold – Tempo minimo dalla fine di un impulso step a un
cambio di direzione (solo il tipo di step 0), in nanosecondi.
 (float) stepgen.<chan>.dirdelay – Durata minima di un passo nella direzione opposta
(solo i tipi di step 1-14), in nano secondi.
 (s32) stepgen.<chan>.rawcounts - Contatore delle risposte non elaborate, aggiornato
da make_pulses () .

In modalità posizione, i valori di maxvel e maxaccel vengono utilizzati dall'anello di posizione


interno per evitare di generare treni di impulsi di passo che il motore non può seguire.
Quando è impostato su valori appropriati per il motore, anche un grande cambiamento
istantaneo nella posizione comandata determinerà un movimento trapezoidale regolare nella
nuova posizione. L'algoritmo funziona misurando sia l'errore di posizione che l'errore di
velocità e calcolando un'accelerazione che tenta di ridurre entrambi a zero allo stesso tempo.
Per ulteriori dettagli, incluso il contenuto della casella dell'equazione di controllo, consultare
il codice.
In modalità velocità, il massimo è un semplice limite applicato alla velocità comandata e il
valore massimo è usato per aumentare la frequenza effettiva se la velocità comandata cambia
bruscamente. Come in modalità posizione, i valori corretti per questi parametri assicurano
che il motore possa seguire il treno di impulsi generato.
Step Type 0
Il tipo di step 0 è il tipo standard di passo e direzione. Quando configurato per il tipo di passo
0, ci sono quattro parametri aggiuntivi che determinano il tempo esatto dei segnali di passo e
direzione. Nella figura seguente viene mostrato il significato di questi parametri. I parametri
sono in nanosecondi, ma saranno arrotondati per eccesso a un multiplo intero del periodo di
thread per i thread che chiamano make_pulses (). Ad esempio, se make_pulses () viene
chiamato ogni 16 us, e steplen è 20000, allora gli impulsi di passo saranno 2 x 16 = 32 us. Il
valore predefinito per tutti e quattro i parametri è 1ns, ma l'arrotondamento automatico ha
effetto la prima volta che il codice viene eseguito. Poiché una fase richiede steplen ns e
stepspace ns bassi, la frequenza massima è 1.000.000.000 divisa per (steplen + stepspace) .
Se maxfreq è impostato su un valore superiore a tale limite, verrà abbassato
automaticamente. Se maxfreq è zero, rimarrà zero, ma la frequenza di uscita sarà ancora
limitata.
Quando si utilizza il driver della porta parallela, la frequenza del passo può essere
raddoppiata usando la funzione di reset parport insieme all'impostazione doublefreq di
stepgen.
Figura 1. Temporizzazione di passo e direzione - Step Type 1

Il tipo di step 1 ha due uscite, su e giù. Gli impulsi appaiono su uno o l'altro, a seconda della
direzione di marcia. Ogni impulso è lungo steplen ns e gli impulsi sono separati da almeno
stepspace ns. La frequenza massima è uguale a quella del tipo di passo 0. Se maxfreq è
impostato su un valore superiore al limite, verrà abbassato. Se maxfreq è zero, rimarrà zero
ma la frequenza di uscita sarà ancora limitata.
Step Tipo 2 - 14
I tipi di step da 2 a 14 sono basati sullo stato e hanno da due a cinque uscite. Ad ogni step, un
contatore di stati viene incrementato o decrementato. Il due e tre fasi, quattro fasi e cinque
fasi mostrano i modelli di uscita in funzione del contatore di stati. La frequenza massima è
1.000.000.000 divisa per steplen, e come nelle altre modalità, maxfreq verrà abbassato se è
superiore al limite.
Tipi di step a due e tre fasi
Tipi di step a quattro fasi

Tipi di step a cinque fasi


funzioni
Il componente esporta tre funzioni. Ogni funzione agisce su tutti i generatori di impulsi di
passo - l'esecuzione di generatori diversi in thread diversi non è supportata.

 (funct) stepgen.make-pulses - Funzione ad alta velocità per generare e contare gli


impulsi (senza virgola mobile).
 (funct) stepgen.update-freq - La funzione a bassa velocità si posiziona sulla
conversione, ridimensionamento e limitazione della velocità.
 (funct) stepgen.capture-position - Funzione a bassa velocità per feedback, aggiorna i
latch e la posizione delle scale.

La funzione ad alta velocità stepgen.make-pulses dovrebbe essere eseguita in un thread molto


veloce, da 10 a 50 us a seconda delle capacità del computer. Il periodo di quel thread
determina la frequenza massima del passo, dal momento che steplen, stepspace, dirsetup,
dirhold e dirdelay sono tutti arrotondati ad un multiplo intero del periodo di thread in
nanosecondi. Le altre due funzioni possono essere chiamate ad un tasso molto più basso.

2. PWMgen
Questo componente fornisce una generazione basata su software di forme d'onda PWM
(Pulse Width Modulation) e PDM (Pulse Density Modulation). È un componente in tempo
reale e, a seconda della velocità della CPU, ecc., è capace di frequenze PWM da poche
centinaia di Hertz a una risoluzione piuttosto buona, circa 10 KHz con risoluzione limitata.
Installazione
loadrt pwmgen output_type=<config-array>
<Config-array> è una serie di numeri decimali separati da virgola. Ogni numero causa il
caricamento di un singolo generatore PWM, il valore del numero determina il tipo di uscita.
Il seguente esempio installerà tre generatori PWM. Non esiste alcun valore predefinito, se
<config-array> non è specificato, nessun generatore PWM verrà installato. Il numero
massimo di generatori di frequenza è 8 (come definito da MAX_CHAN in pwmgen.c). Ogni
generatore è indipendente, ma tutti sono aggiornati dalla stessa funzione (s) allo stesso
tempo. Nelle seguenti descrizioni, <chan> è il numero di un generatore specifico. Il primo
generatore è il numero 0.
Esempio
loadrt pwmgen output_type=0,1,2
Rimozione
unloadrt pwmgen

Tipi di output
Il generatore PWM supporta tre diversi tipi di output .

 Uscita tipo 0 - Solo pin di uscita PWM. Sono accettati solo comandi positivi, i valori
negativi sono considerati zero (e saranno influenzati dal parametro min-dc se è diverso
da zero).
 Uscita tipo 1 - PWM / PDM e pin di direzione. Gli input positivi e negativi verranno
emessi come PWM positivi e negativi. Il pin di direzione è falso per i comandi positivi
e vero per i comandi negativi. Se il controllo richiede PWM positivo sia per CW che
per CCW, utilizzare il componente abs per convertire il segnale PWM in valore positivo
quando viene immesso un input negativo.
 Uscita tipo 2 : pin UP e DOWN. Per i comandi positivi, il segnale PWM appare
sull'uscita superiore e l'uscita giù rimane falsa. Per i comandi negativi, il segnale PWM
appare sull'uscita giù e l'uscita su rimane falsa. Il tipo di uscita 2 è adatto per la guida
della maggior parte dei ponti H.

Pins
Ogni generatore PWM avrà i seguenti pin:

 (float) pwmgen. <chan>.value - Valore del comando, in unità arbitrarie. Verrà


ridimensionato dal parametro di scala (vedi sotto).
 (bit) pwmgen.<chan>.enable - Abilita o disabilita le uscite del generatore PWM.

Ogni generatore PWM avrà anche alcuni di questi pin, a seconda del tipo di output
selezionato:

 (bit) pwmgen. <chan>.pwm - PWM (o PDM) output, (solo tipi di output 0 e 1).
 (bit) pwmgen. <chan>.dir - Output di direzione (solo tipo di output 1).
 (bit) pwmgen. <chan>.up - Uscita PWM / PDM per valore di input positivo (solo tipo
di output 2).
 (bit) pwmgen. <chan>.down - Uscita PWM / PDM per valore di ingresso negativo
(solo tipo di uscita 2).

parametri

 (float) pwmgen.<chan>.scale - Fattore di scala per convertire il valore da unità


arbitrarie a ciclo di lavoro. Ad esempio se la scala è impostata su 4000 e il valore di
input è passato a pwmgen. <Chan> .value è 4000, quindi sarà duty cycle del 100%
(sempre attivo). Se il valore è 2000, allora sarà un'onda quadra al 50% a 25Hz.
 (float) pwmgen.<chan>.pwm-freq - Frequenza PWM desiderata, in Hz. Se 0.0,
genera PDM anziché PWM. Se impostato superiore ai limiti interni, la prossima
chiamata di update_freq () la imposterà al limite interno. Se diverso da zero e dither è
falso, la prossima chiamata di update_freq () la imposterà al multiplo intero più vicino
del periodo di funzione make_pulses () .
 (bit) pwmgen.<chan>.dither-pwm - Se true, consente al dithering di raggiungere
frequenze PWM o cicli di lavoro medi che non sono ottenibili con PWM puro. Se falso,
sia la frequenza PWM che il ciclo di lavoro saranno arrotondati a valori che possono
essere raggiunti esattamente.
 (float) pwmgen. <chan>.min-dc - Ciclo di lavoro minimo, compreso tra 0.0 e 1.0 (il
duty cycle andrà a zero quando disabilitato, indipendentemente da questa
impostazione).
 (float) pwmgen.<chan>.max-dc - Ciclo di lavoro massimo, compreso tra 0.0 e 1.0.
 (float) pwmgen.<chan>.curr-dc - Ciclo di lavoro corrente - dopo tutte le limitazioni e
gli arrotondamenti (sola lettura).

funzioni
Il componente esporta due funzioni. Ogni funzione agisce su tutti i generatori PWM -
l'esecuzione di generatori diversi in thread diversi non è supportata.

 (funct) pwmgen.make-impules - Funzione ad alta velocità per generare forme d'onda


PWM (senza virgola mobile). La funzione ad alta velocità pwmgen.make-impules
deve essere eseguita nel thread di base (più veloce), da 10 a 50 us a seconda delle
capacità del computer. Il periodo di quel thread determina la massima frequenza
portante PWM, nonché la risoluzione dei segnali PWM o PDM. Se il thread di base è
50.000nS, ogni 50uS il modulo decide se è il momento di cambiare lo stato
dell'output. Con un duty cycle del 50% e una frequenza PWM di 25Hz, ciò significa
che l'uscita cambia stato ogni (1/25) secondo / 50uS * 50% = 400 iterazioni. Ciò
significa anche che hai 800 valori di duty cycle possibili (senza dithering)
 (funct) pwmgen.update - Funzione a bassa velocità per ridimensionare e limitare il
valore e gestire altri parametri. Questa è la funzione del modulo che fa la matematica
più complicata per capire quanti periodi base l'uscita dovrebbe essere alta, e per quanti
dovrebbe essere bassa.

3. Encoder
Questo componente fornisce il conteggio basato su software di segnali da encoder in
quadratura. È un componente solo in tempo reale e, a seconda della velocità della CPU, della
latenza e così via, è in grado di ottenere frequenze di conteggio massimo di 10 kHz fino a un
massimo di 50 kHz.
Il thread di base dovrebbe essere 1/2 della velocità di conteggio per tenere conto della
variazione del rumore e della temporizzazione. Ad esempio se si dispone di un encoder a 100
impulsi per giro sul mandrino e il numero massimo di giri / min è 3000, il thread di base
massima deve essere di 25 us. Un encoder a 100 impulsi per giro avrà 400 conteggi. La
velocità del mandrino di 3000 RPM = 50 RPS (giri al secondo). 400 * 50 = 20.000 conteggi
al secondo o 50 us tra i conteggi.
Il Diagramma a blocchi del contatore dell'encoder è uno schema a blocchi di un canale di un
contatore dell'encoder.

Figura 2. Diagramma a blocchi del contatore encoder

Installazione
halcmd: loadrt encoder [num_chan=<contatori>]
<contatori> è il numero di contatori dell'encoder che si desidera installare. Se numchan non
viene specificato, verranno installati tre contatori. Il numero massimo di contatori è 8 (come
definito da MAX_CHAN in encoder.c). Ogni contatore è indipendente, ma tutti sono
aggiornati dalla stessa funzione (s) allo stesso tempo. Nelle seguenti descrizioni, <chan> è il
numero di un contatore specifico. Il primo contatore è il numero 0.
Rimozione
halcmd: unloadrt encoder

Pins

 encoder. <chan> .counter-mode (bit, I / O) (default: FALSE) - Abilita la modalità


contatore. Quando è vero, il contatore conta ogni fronte di salita dell'ingresso di fase
A, ignorando il valore sulla fase B. Questo è utile per contare l'uscita di un sensore a
singolo canale (non quadratura). Quando è falso, conta in modalità quadratura.
 encoder. <chan>.counts (s32, Out) - Posizione nei conteggi dell'encoder.
 encoder. <chan>.counts-latched (s32, Out) - Non utilizzato in questo momento.
 encoder. <chan>.index-enable (bit, I / O) - Quando True, i conteggi e la posizione
vengono reimpostati su zero sul prossimo fronte di salita della Fase Z. Allo stesso
tempo, l' indice di abilitazione viene reimpostato su zero per indicare che il fronte di
salita è avvenuto. Il pin di abilitazione dell'indice è bidirezionale. Se l' abilitazione
all'indice è False, il canale della fase Z dell'encoder verrà ignorato e il contatore
conterà normalmente. Il driver dell'encoder non imposterà mai l' abilitazione
dell'indice True. Tuttavia, alcuni altri componenti potrebbero farlo.
 encoder. <chan>.latch-falling (bit, In) (default: TRUE) - Non usato in questo
momento.
 encoder. <chan>.latch-input (bit, In) (default: TRUE) - Non utilizzato in questo
momento.
 encoder. <chan>.latch-rising (bit, In) - Non usato in questo momento.
 encoder. <chan>.min-speed-estimate (float, in) - Determina la magnitudine minima
della velocità reale a cui la velocità sarà stimata come non nullo e interpolazione della
postazione verrà interpolata. Le unità di stima a velocità minima sono le stesse delle
unità di velocità . Fattore di scala, in conteggi per unità di lunghezza. L'impostazione
di questo parametro troppo basso farà sì che impieghi molto tempo prima che la
velocità passi a 0 dopo che gli impulsi dell'encoder hanno smesso di arrivare.
 encoder.<chan>.phase-A (bit, In) - Fase A del segnale dell'encoder in quadratura.
 encoder.<chan>.phase-B (bit, In) - Fase B del segnale dell'encoder in quadratura.
 encoder.<chan>.phase-Z (bit, In) - Fase Z (impulso indice) del segnale dell'encoder in
quadratura.
 encoder.<chan>.position (float, Out) - Posizione in unità in scala (vedi scala di
posizione ).
 encoder.<chan>.position-interpolated (float, Out) - Posizione in unità scalate,
interpolata tra i conteggi dell'encoder. I punti interpolati in posizione sono interpolati
tra i conteggi dell'encoder, in base alla velocità misurata più recentemente. Valido solo
quando la velocità è approssimativamente costante e superiore alla stima della
velocità minima . Non utilizzare per il controllo di posizione, poiché il suo valore non
è corretto alle basse velocità, durante le inversioni di direzione e durante i cambi di
velocità. Tuttavia consente di utilizzare un encoder a basso ppr (incluso un encoder a
un impulso per giro) per la filettatura del tornio e può avere anche altri usi.
 encoder.<chan>.position-latched (float, Out) - Non usato in questo momento.
 encoder.<chan>.position-scale (float, I / O) - Fattore di scala, in conteggi per unità di
lunghezza. Ad esempio, se la scala della posizione è 500, i 1000 conteggi dell'encoder
verranno riportati come una posizione di 2,0 unità.
 encoder.<chan>.rawcounts (s32, In) - Il conteggio grezzo, determinato dai contatori
di aggiornamento. Questo valore viene aggiornato più frequentemente dei conteggi e
della posizione. Inoltre, non viene influenzato dal reset o dall'indice.
 encoder.<chan>.reset (bit, In) - Quando True, forza i conteggi e posiziona a zero
immediatamente.
 encoder.<chan>.velocity (float, Out) - Velocità in unità in scala al secondo. L'encoder
utilizza un algoritmo che riduce notevolmente il rumore di quantizzazione rispetto alla
semplice differenziazione dell'output di posizione . Quando la grandezza della velocità
reale è inferiore alla stima a velocità minima, l'uscita di velocità è 0.
 encoder.<chan>.x4-mode (bit, I / O) (default: TRUE) - Abilita la modalità times-4.
Quando è vero, il contatore conta ogni fronte della forma d'onda della quadratura
(quattro conteggi per ciclo completo). Quando è falso, conta solo una volta per ciclo
completo. In modalità contraria, questo parametro viene ignorato. La modalità 1x è
utile per alcuni jogwheels.

parametri

 encoder.<chan>.capture-position.time (s32, RO)


 encoder.<chan>.capture-position.tmax (s32, RW)
 encoder.<chan>.update-counters.time (s32, RO)
 encoder.<chan>.update-counter.tmax (s32, RW)

funzioni
Il componente esporta due funzioni. Ogni funzione agisce su tutti i contatori dell'encoder -
l'esecuzione di contatori diversi in thread diversi non è supportata.

 (funct) encoder.update-counters - Funzione ad alta velocità per contare gli impulsi


(senza virgola mobile).
 (funct) encoder.capture-position - Funzione a bassa velocità per aggiornare i latch e la
posizione della scala.

4. PID
Questo componente fornisce loop di controllo Proporzionale / Integrale / Derivativo. È un
componente solo in tempo reale. Per semplicità, questa discussione presuppone che stiamo
parlando di anelli di posizione, tuttavia questo componente può essere utilizzato per
implementare altri circuiti di feedback quali velocità, altezza torcia, temperatura, ecc. Il
diagramma a blocchi del loop PID è uno schema a blocchi di un singolo anello PID .
Figura 3. Diagramma a blocchi del loop PID

Installazione
halcmd: loadrt pid [num_chan=<loops>] [debug=1]
<loops> è il numero di loop PID che si desidera installare. Se numchan non è specificato,
verrà installato un ciclo. Il numero massimo di loop è 16 (come definito da MAX_CHAN in
pid.c). Ogni loop è completamente indipendente. Nelle seguenti descrizioni, <loopnum> è il
numero di loop di un loop specifico. Il primo ciclo è il numero 0.
Se viene specificato debug = 1 , il componente esporterà alcuni pin aggiuntivi che potrebbero
essere utili durante il debug e l'ottimizzazione. Per impostazione predefinita, i pin aggiuntivi
non vengono esportati, per risparmiare spazio nella memoria condivisa ed evitare di
ingombrare l'elenco dei pin.
Rimozione
halcmd: unloadrt pid

Pins
I tre pin più importanti sono

 (float) pid.<loopnum>.command - La posizione desiderata, come comandato da un


altro componente di sistema.
 (float) pid.<loopnum>.feedback - La posizione attuale, misurata da un dispositivo di
feedback come un encoder.
 (float) pid.<loopnum>.output - Un comando di velocità che tenta di spostarsi dalla
posizione attuale alla posizione desiderata.

Per un loop di posizione, il comando e il feedback sono in unità di posizione. Per un asse
lineare, questo potrebbe essere pollici, mm, metri o qualsiasi cosa sia rilevante. Allo stesso
modo, per un asse angolare, potrebbe essere gradi, radianti, ecc. Le unità del pin di uscita
rappresentano la modifica necessaria per far corrispondere il feedback al comando. In
quanto tale, per un loop di posizione, l' output è una velocità, in pollici/sec, mm/sec,
gradi/sec, ecc. Le unità di tempo sono sempre secondi e le unità di velocità corrispondono
alle unità di posizione. Se il comando e il feedback sono espressi in metri, l'output è espresso
in metri al secondo.
Ogni loop ha due pin che vengono utilizzati per monitorare o controllare il funzionamento
generale del componente.

 (float) pid.<loopnum>.error - Uguale .command meno .feedback .


 (bit) pid.<loopnum>.enable - Un bit che abilita il ciclo. Se .enable è falso, tutti gli
integratori vengono resettati e l'output è forzato a zero. Se .enable è vero, il ciclo
funziona normalmente.

Pin utilizzati per segnalare la saturazione. La saturazione si verifica quando l'uscita del
blocco PID è al suo limite massimo o minimo.

 (bit) pid.<loopnum>.saturated - True quando l'output è saturo.


 (float) pid.<loopnum>.saturated_s - Il tempo in cui l'output è stato saturato.
 (s32) pid.<loopnum>.saturated_count - Il tempo in cui l'output è stato saturato.

I guadagni, i limiti e le altre caratteristiche sintonizzabili del loop sono disponibili come pin
in modo che possano essere regolati dinamicamente per ulteriori possibilità di accordatura
avanzate.

 (float) pid.<loopnum>.Pgain - Guadagno proporzionale


 (float) pid.<loopnum>.Igain - Guadagno integrale
 (float) pid.<loopnum>.Dgain - Guadagno derivativo
 (float) pid.<loopnum>.bias - Offset costante sull'output
 (float) pid.<loopnum .FF0 - Zeroth order feedforward - output proporzionale al
comando (posizione).
 (float) pid.<loopnum>.FF1 - Feedforward del primo ordine - uscita proporzionale alla
derivata del comando (velocità).
 (float) pid.<loopnum>.FF2 - Feedforward del secondo ordine - uscita proporzionale
alla derivata seconda del comando (accelerazione).
 (float) pid.<loopnum>.deadband - Quantità di errore che verrà ignorata
 (float) pid.<loopnum>.maxerror - Limite di errore
 (float) pid.<loopnum>.maxerrorI - Limite sull'integratore di errori
 (float) pid.<loopnum>.maxerrorD - Limite sulla derivata dell'errore
 (float) pid.<loopnum>.maxcmdD - Limite sulla derivata del comando
 (float) pid.<loopnum>.maxcmdDD - Limite sulla derivata seconda del comando
 (float) pid.<loopnum>.maxoutput - Limite sul valore di uscita

Se è stato specificato debug = 1 quando è stato installato il componente, verranno esportati


quattro pin aggiuntivi:
 (float) pid.<loopnum>.errorI - Integrale dell'errore.
 (float) pid.<loopnum>.errorD - Derivato dell'errore.
 (float) pid.<loopnum>.commandD - Derivata del comando.
 (float) pid.<loopnum>.commandDD - Derivata seconda del comando.

funzioni
Il componente esporta una funzione per ogni loop PID. Questa funzione esegue tutti i calcoli
necessari per il ciclo. Poiché ogni loop ha una propria funzione, i singoli loop possono essere
inclusi in thread diversi ed eseguiti a velocità diverse.

 (funct) pid.<loopnum>.do_pid_calcs - Esegue tutti i calcoli per un singolo loop PID.

Se vuoi capire l'esatto algoritmo usato per calcolare l'output del loop PID, fai riferimento alla
figura PID Loop Block Diagram , i commenti all'inizio di emc2 / src / hal / components /
pid.c , e ovviamente al codice. I calcoli del ciclo si trovano nella funzione C calc_pid () .

5. Encoder simulato
L'encoder simulato è esattamente questo. Produce impulsi in quadratura con un impulso
indice, ad una velocità controllata da un pin HAL. Utile principalmente per i test.
Installazione
halcmd: loadrt sim-encoder num_chan=<numero>
<numero> è il numero di encoder che si desidera simulare. Se non specificato, verrà
installato un codificatore. Il numero massimo è 8 (come definito da MAX_CHAN in
sim_encoder.c).
Rimozione
halcmd: unloadrt sim-encoder

Pins

 (float) sim-encoder.<chan-num>.speed - Il comando di velocità per l'encoder


simulato.
 (bit) sim-encoder.<chan-num>.phase-A - Uscita quadratura.
 (bit) sim-encoder.<chan-num>.phase-B - Uscita quadratura.
 (bit) sim-encoder.<chan-num>.phase-Z - Uscita impulso indice.

Quando .speed è positivo, .phase-A precede .phase-B .


parametri

 (u32) sim-encoder.<chan-num>.ppr - Pulses Per Revolution (impulsi a giro).


 (float) sim-encoder.<chan-num>.scale - Fattore di scala per la velocità . Il valore
predefinito è 1.0, il che significa che la velocità è in giri al secondo. Passare a 60 per
RPM, a 360 per gradi al secondo, a 6.283185 per radianti per sec, ecc.

Nota che gli impulsi per giro non sono gli stessi conteggi per giro. Un impulso è un ciclo di
quadratura completo. La maggior parte dei contatori dell'encoder conta quattro volte durante
un ciclo completo.
funzioni
Il componente esporta due funzioni. Ogni funzione ha effetto su tutti gli encoder simulati.
 (funct) sim-encoder.make-impules - Funzione ad alta velocità per generare impulsi in
quadratura (senza virgola mobile).
 (funct) sim-encoder.update-speed - Funzione a bassa velocità per leggere la velocità ,
eseguire il ridimensionamento e impostare i make-impules .

6. Debounce
Debounce è un componente in tempo reale in grado di filtrare le anomalie create dai contatti
degli interruttori meccanici. Può anche essere utile in altre applicazioni in cui gli impulsi
brevi devono essere rifiutati.
Installazione
halcmd: loadrt debounce cfg=<config-string>
<config-string> è una serie di numeri decimali separati da virgola. Ogni numero installa un
gruppo di filtri antirimbalzo identici, il numero determina quanti filtri ci sono nel gruppo.
Per esempio:
halcmd: loadrt debounce cfg=1,4,2
installerà tre gruppi di filtri. Il gruppo 0 contiene un filtro, il gruppo 1 ne contiene quattro e il
gruppo 2 contiene due filtri. Il valore predefinito per <config-string> è "1" che installerà un
singolo gruppo contenente un singolo filtro. Il numero massimo di gruppi 8 (come definito
da MAX_GROUPS in debounce.c). Il numero massimo di filtri in un gruppo è limitato solo
dallo spazio di memoria condiviso. Ogni gruppo è completamente indipendente. Tutti i filtri
in un singolo gruppo sono identici e sono tutti aggiornati con la stessa funzione allo stesso
tempo. Nelle seguenti descrizioni, <G> è il numero del gruppo e <F> è il numero del filtro
all'interno del gruppo. Il primo filtro è il gruppo 0, il filtro 0.
Rimozione
halcmd: unloadrt debounce
Pins
Ogni singolo filtro ha due pin.

 (bit) debounce.<G>.<F>.in - Inserimento del filtro <F> nel gruppo <G> .


 (bit) debounce.<G>.<F>.out - Output del filtro <F> nel gruppo <G> .

parametri
Ogni gruppo di filtri ha un parametro

 (s32) debounce.<G>.delay - Ritarda il filtro per tutti i filtri nel gruppo <G> .

Il ritardo del filtro è espresso in unità di periodi di thread. Il ritardo minimo è zero. L'output
di un filtro di ritardo zero segue esattamente il suo input - non filtra nulla. Con l'aumentare
del ritardo, vengono rifiutati i glitch più lunghi. Se il ritardo è 4, tutti i glitch inferiori o
uguali a quattro periodi di thread verranno rifiutati.
funzioni
Ogni gruppo di filtri ha una funzione, che aggiorna tutti i filtri in quel gruppo
simultaneamente. Diversi gruppi di filtri possono essere aggiornati da diversi thread in
periodi diversi.

 (funct) debounce.<G> - Aggiorna tutti i filtri nel gruppo <G> .


7. Siggen
Siggen è un componente in tempo reale che genera onde quadrate, triangolari e sinusoidali.
Viene utilizzato principalmente per i test.
Installazione
halcmd: loadrt siggen [num_chan=<chans>]
<chans> è il numero di generatori di segnali che si desidera installare. Se numchan non è
specificato, verrà installato un generatore di segnale. Il numero massimo di generatori è 16
(come definito da MAX_CHAN in siggen.c). Ogni generatore è completamente indipendente.
Nelle seguenti descrizioni, <chan> è il numero di un generatore di segnale specifico (i numeri
iniziano da 0).
Rimozione
halcmd: unloadrt siggen
Pins
Ogni generatore ha cinque pin di uscita.

 (float) siggen.<chan>.sine - Uscita sinusoidale.


 (float) siggen.<chan>.cosine - Output coseno.
 (float) siggen.<chan>.sawtooth - Uscita a dente di sega.
 (float) siggen.<chan>.triangle - Uscita a onda triangolare.
 (float) siggen.<chan>.square - Uscita ad onda quadra.

Tutte e cinque le uscite hanno la stessa frequenza, ampiezza e offset.


Oltre ai pin di uscita, ci sono tre pin di controllo:

 (float) siggen. <chan>.frequency - Imposta la frequenza in Hertz, il valore predefinito


è 1 Hz.
 (float) siggen. <chan>.amplitude - Imposta l'ampiezza di picco delle forme d'onda di
uscita, l'impostazione predefinita è 1.
 (float) siggen. <chan>.offset - Imposta l'offset DC delle forme d'onda di uscita, il
valore predefinito è 0.

Ad esempio, se siggen.0.amplitude è 1.0 e siggen.0.offset è 0.0, le uscite oscilleranno da -1.0


a +1.0. Se siggen.0.amplitude è 2.5 e siggen.0.offset è 10.0, le uscite oscilleranno da 7.5 a
12.5.
parametri
Nessuno.
[Prima della versione 2.1, la frequenza, l'ampiezza e l'offset erano parametri. Sono stati
cambiati in pins per consentire il controllo da parte di altri componenti.]

funzioni

 (funct) siggen.<chan>.update - Calcola i nuovi valori per tutte e cinque le uscite.

8. lut5
Il componente lut5 è un componente logico a 5 input basato su una tabella di ricerca.

 lut5 non richiede un thread in virgola mobile.


Installazione
loadrt lut5 [count = N | nomi = nome1 [, nome2 ...]]
addf lut5.N servo-thread | base-thread
setp lut5.N.function 0xN

Funzione di calcolo
Per calcolare il numero esadecimale della funzione partendo dall'alto, metti un 1 o 0 per
indicare se quella riga sarebbe vera o falsa. Quindi annota tutti i numeri nella colonna di
output partendo dall'alto e scrivendoli da destra a sinistra. Questo sarà il numero binario.
Usando una calcolatrice con funzione di programmatore come quella di Linux inserisci il
numero binario e poi convertilo in esadecimale e questo sarà il valore per la funzione.

Tabella 1. Tabella di ricerca


Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
0 0 0 0 0
0 0 0 0 1
0 0 0 1 0
0 0 0 1 1
0 0 1 0 0
0 0 1 0 1
0 0 1 1 0
0 0 1 1 1
0 1 0 0 0
0 1 0 0 1
0 1 0 1 0
0 1 0 1 1
0 1 1 0 0
0 1 1 0 1
0 1 1 1 0
0 1 1 1 1
1 0 0 0 0
1 0 0 0 1
1 0 0 1 0
1 0 0 1 1
1 0 1 0 0
1 0 1 0 1
1 0 1 1 0
1 0 1 1 1
1 1 0 0 0
Tabella 1. Tabella di ricerca
Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
1 1 0 0 1
1 1 0 1 0
1 1 0 1 1
1 1 1 0 0
1 1 1 0 1
1 1 1 1 0
1 1 1 1 1

Due esempi di input


Nella seguente tabella abbiamo selezionato lo stato dell'output per ogni linea che vogliamo
essere vera.

Tabella 2. Tabella di ricerca


Bit Bit Bit Bit Bit
4 3 2 1 0 Risultato
0 0 0 0 0 0
0 0 0 0 1 1
0 0 0 1 0 0

0 0 0 1 1 1

Guardando la colonna di output del nostro esempio vogliamo che l'output sia attivo quando
Bit 0 o Bit 0 e Bit1 sono accesi e nient'altro. Il numero binario è b1010 (ruota l'uscita di 90
gradi CW). Inserire questo numero nella calcolatrice, quindi cambiare la visualizzazione in
esadecimale e il numero necessario per la funzione è 0xa. Il prefisso esadecimale è 0x .
Pannello di controllo virtuale Python
PyVCP
Sommario
1. Introduzione
2. Costruzione del pannello
3. Sicurezza
4. AXIS
5. Stand Alone
6. Widget
6.1. Sintassi
6.2. Note generali
6.3. Etichetta
6.4. Multi_Label
6.5. LED
6.6. Pulsanti
6.7. Numero visualizzazioni
6.8. Numero di ingressi
6.9. Immagini
6.10. Contenitori

1. Introduzione
PyVCP - Pannello di controllo virtuale Python

Il PyVCP (Pannello di controllo virtuale Python) è progettato per offrire all'integratore la


possibilità di personalizzare l'interfaccia AXIS con pulsanti e indicatori per svolgere compiti
speciali.
I pannelli di controllo della macchina hardware possono utilizzare molti pin di I/O e possono
essere costosi. È qui che i pannelli di controllo virtuali danno ivantaggio e poi non costa nulla
per costruire un PyVCP.
I pannelli di controllo virtuali possono essere utilizzati per testare o monitorare le attività per
sostituire temporaneamente i dispositivi I/O reali durante il debug della logica ladder, o per
simulare un pannello fisico prima di costruirlo e collegarlo a una scheda I/O.

Il seguente grafico mostra molti dei widget PyVCP.


2. Costruzione del pannello
Il layout di un pannello PyVCP viene specificato con un file XML che contiene tag di widget
tra <pyvcp> e </pyvcp>

<pyvcp>
<label text="This is a LED indicator"/>
<led/>
</pyvcp>

Se si riporta questo testo in un file chiamato tiny.xml e si esegue il comando

halcmd loadusr pyvcp -c mypanel tiny.xml

PyVCP creerà il pannello per te, che include due widget, un'etichetta con il testo This is a LED
indicator e un LED, utilizzato per visualizzare lo stato di un segnale HAL BIT. Creerà anche
un componente HAL chiamato mypanel (tutti i widget in questo pannello sono connessi ai
pin che iniziano con mypanel). Poiché nessun tag <halpin> era presente nel tag <led>,
PyVCP assegnerà automaticamente il pin HAL per il widget LED mypanel.led.0.
Per un elenco di widget e relativi tag e opzioni, consultare il riferimento del widget di seguito.

Una volta creato il pannello, il collegamento dei segnali HAL ai pin PyVCP viene eseguito con
halcmd:

net <nome-segnale> <nome-pin> <direzione-opt> <nome-pin-opt> nome-segnale

3. Sicurezza
Le parti dei file PyVCP sono valutate come codice Python e possono compiere qualsiasi azione
disponibile per i programmi Python. Utilizza solo file .xml PyVCP provenienti da un'origine di
cui ti fidi.

4. AXIS
Poiché AXIS utilizza lo stesso toolkit GUI (Tkinter) come PyVCP, è possibile includere un
pannello PyVCP sul lato destro della normale interfaccia utente AXIS. Un tipico esempio è
spiegato di seguito.

Inserisci il tuo file PyVCP XML descrivendo il pannello nella stessa directory in cui si trova il
tuo file .ini. Diciamo che vogliamo visualizzare la velocità corrente del mandrino usando un
widget Barra. Inserire quanto segue in un file chiamato spindle.xml:

<pyvcp>
<label>
<text>"Velocità del mandrino:"</text>
</label>
<bar>
<halpin>"spindle-speed"</halpin>
<max_>5000</ max_>
</bar>
</pyvcp>

Qui abbiamo creato un pannello con un widget Label e una barra, specificato che il pin HAL
collegato alla barra deve essere denominato spindle speed e impostare il valore massimo della
barra su 5000 (vedi il riferimento del widget sotto per tutte le opzioni). Per rendere AXIS
comprensivo di questo file e chiamarlo all'avvio, è necessario specificare quanto segue nella
sezione [DISPLAY] del file .ini:

PYVCP = spindle.xml

Per rendere il nostro widget efficace per visualizzare la velocità del mandrino, ha bisogno di
essere collegato al segnale HAL appropriato. Un file .hal che verrà eseguito dopo l'avvio di
AXIS e PyVCP può essere specificato nella sezione [HAL] del file .ini:

POSTGUI_HALFILE = spindle_to_pyvcp.hal

Questa modifica eseguirà i comandi HAL specificati in spindle_to_pyvcp.hal. Nel nostro


esempio il contenuto potrebbe assomigliare a questo:

net spindle-rpm-filtered => pyvcp.spindle-speed


supponendo che un segnale chiamato spindle-rpm-filtered esista già. Si noti che durante
l'esecuzione con AXIS, tutti i pin HAL del widget PyVCP hanno nomi che iniziano con pyvcp..

Questo è come dovrebbe apparire il pannello PyVCP appena creato in AXIS. La


configurazione sim/lathe è già configurata in questo modo.

5. Stand Alone
Questa sezione descrive come i pannelli PyVCP possono essere visualizzati da soli con o senza
il controller macchina di LinuxCNC.

Per caricare un pannello PyVCP stand-alone con LinuxCNC usa questi comandi:

loadusr -Wn mypanel pyvcp -g WxH + X + Y -c mypanel <percorso/>panel_file.xml

Potresti usarlo se volessi un pannello mobile o un pannello con un GUI diversa da AXIS.

● -Wn panelname - fa in modo che HAL attenda il completamento del caricamento del
componente panelname (diventa pronto in HAL) prima di elaborare più comandi
HAL. Questo è importante perché i pannelli PyVCP esportano pin HAL e altri
componenti HAL avranno bisogno di essere già presenti per connettersi ad essi.
Notare la W maiuscola e la minuscola n. Se si utilizza l'opzione -Wn, è necessario
utilizzare l'opzione -c per denominare il pannello.
● pyvcp <-g> <-c> panel.xml - crea il pannello con la geometria opzionale e/o
panelname dal file del pannello xml. Il file panel.xml può avere qualsiasi nome che
termina con .xml. Il file .xml è il file che descrive come costruire il pannello. È
necessario aggiungere il nome del percorso se il pannello non si trova nella directory in
cui si trova lo script HAL.
● -g <WxH> <+ X + Y> - specifica la geometria da utilizzare durante la costruzione del
pannello. La sintassi è larghezza x altezza +XAnchor +YAnchor. È possibile impostare
la dimensione o la posizione o entrambi. Il punto di ancoraggio è l'angolo in alto a
sinistra del pannello. Un esempio è -g 250x500 + 800 + 10 Imposta il pannello a 250
pixel di larghezza, a 500 pixel di altezza e lo posiziona a X800 Y10.
● -c panelname - dice a PyVCP come chiamare il componente e anche il titolo della
finestra. Il nome del pannello può essere un nome qualsiasi senza spazi.

Per caricare un pannello PyVCP stand-alone senza LinuxCNC, utilizzare questo comando:

loadusr -Wn mypanel pyvcp -g 250x500 + 800 + 0 -c mypanel mypanel.xml

Il comando minimo per caricare un pannello pyvcp è:

loadusr pyvcp mypanel.xml

Si utilizzerà questo se si desidera un pannello senza il controller di macchina di LinuxCNC


come per i test o un DRO stand-alone.

Il comando loadusr viene utilizzato quando si carica anche un componente che impedirà a
HAL di chiudersi fino al completamento. Se hai caricato un pannello e caricato Classic Ladder
utilizzando loadusr -w classicladder, CL avrebbe mantenuto HAL aperto (e il pannello)
finché non hai chiuso CL. Il -Wn sopra significa attendere che il componente -Wn "nome" sia
pronto. (il nome può essere qualsiasi nome. Nota la lettera maiuscola e la lettera minuscola
n.) Il -c indica a PyVCP di creare un pannello con il nome panelname utilizzando le
informazioni in panel_file_name.xml. Il nome panel_file_name.xml può essere qualsiasi
nome ma deve terminare in .xml - è il file che descrive come compilare il pannello. È
necessario aggiungere il nome del percorso se il pannello non si trova nella directory in cui si
trova lo script HAL.

Un comando opzionale da utilizzare se si desidera che il pannello interrompa l'esecuzione da


parte di HAL dei comandi / spegnimento. Dopo aver caricato qualsiasi altro componente, si
desidera che sia l'ultimo comando HAL:

waituser panelname

Questo indica a HAL di attendere la chiusura del componente panelname prima di


continuare i comandi HAL. Di solito viene impostato come ultimo comando in modo che
l'HAL si chiuda quando il pannello viene chiuso.

6. Widget
I segnali HAL sono disponibili in due varianti, bit e numeri. I bit sono segnali off/on. I
numeri possono essere float, s32 o u32. Per ulteriori informazioni sui tipi di dati HAL,
consultare la HAL Data sezione. Il widget PyVCP può visualizzare il valore del segnale con un
indicatore widget o modificare il valore del segnale con un widget di controllo. Quindi ci sono
quattro classi di widget PyVCP che è possibile collegare a un segnale HAL. Una quinta classe
di widget detti helper ti consente di organizzare ed etichettare il tuo pannello.
1. Widget per indicare bit: led, rectled
2. Widget per controllare bit: segnali di bottone, checkbutton, radiobutton
3. Widgets indicanti numero: segnali numero, s32, u32, barre, quadranti
4. Widgets per controllare valori numerici: i segnali spinbox, scala, jogwheel
5. WidgetHelper: hbox , vbox, table, label, labelframe

6.1. Sintassi

Ogni widget è descritto brevemente, seguito dal markup utilizzato e da una schermata. Tutti i
tag all'interno del tag del widget principale sono facoltativi.

6.2. Note generali

Al momento sono supportate sia una sintassi basata su tag sia una sintassi basata su attributi.
Ad esempio, i seguenti frammenti XML sono trattati in modo identico:

<led halpin="my-led"/>
e
<led> <halpin>"my-led"</ halpin> </ led>

Quando viene utilizzata la sintassi basata sugli attributi, vengono utilizzate le seguenti regole
per trasformare il valore degli attributi in un valore Python:

1. se il primo carattere dell'attributo è uno dei seguenti, viene valutato come


un'espressione Python: {([""
2. Se la stringa è accettata da int (), il valore viene trattato come un numero intero
3. Se la stringa è accettato da float (), il valore viene considerato come virgola mobile
4. Altrimenti, la stringa viene accettata come una stringa.

Quando si usa la sintassi basata su tag, il testo all'interno del tag è sempre valutata come
un'espressione Python.

Gli esempi che seguono mostrano un mix di formati

Commenti

Per aggiungere un commento usa la normale sintassi xml per un commento

<! - Il mio commento ->

Modifica del file XML

Modifica il file XML con un editor di testo. Nella maggior parte dei casi puoi fare clic destro
sul file e selezionare Apri con editor di testo o simile.

Colori

I colori possono essere specificati usando i colori X11 rgb per nome gray75 o hex #0000ff.
Una lista completa si trova qui http: // sedition.com/perl/rgb.html.

Colori comuni (i colori con i numeri indicano le sfumature di quel colore)


● white
● black
● blue e blue1 - 4
● cyan e cyan1 - 4
● green e green1 - 4
● yellow e yellow1 - 4
● red e red1 - 4
● purple e purple1 - 4
● gray e gray0 - 100

I pin HAL

I pin HAL forniscono un mezzo per collegare il widget a qualcosa. Una volta creato un pin
HAL per il tuo widget, puoi collegarlo a un altro pin HAL con un comando net in un file .hal.
Per maggiori informazioni sul net comando vedi la sezione HAL Commands.

6.3. Label (Etichetta)

Un'etichetta è un modo per aggiungere testo al tuo pannello.

● <label> </label> - crea un'etichetta


● <text> "text" </text> - il testo da inserire nell'etichetta, un'etichetta vuota può essere
utilizzata come distanziatore per allineare altri oggetti.
● <font> ( "Helvetica", 20) </font> - specifica il carattere e la dimensione del testo
● <relief> FLAT </relief> - specifica il bordo intorno all'etichetta (FLAT, RAISED,
SUNKEN) di default è FLAT
● <bd> n </bd> - dove n è la larghezza del bordo quando si utilizzano i valori RAISED o
SUNKEN
● <padx> n </padx> - dove n è la quantità di spazio orizzontale extra.
● <pady> n </pady> - dove n è la quantità di spazio verticale extra.

L'etichetta ha un pin di disabilitazione opzionale che viene creato quando si aggiunge


<disable_pin> True </ disable_pin>.

<label>
<text>"This is a Label:"</text>
<font>("Helvetica", 20)</font>
</label>

Il codic e sopra riportato ha prodotto questo esempio.

6.4. Multi_Label

Un'estensione dell'etichetta di testo.

Etichetta di testo selezionabile, in grado di visualizzare fino a 6 legende sull'etichetta quando


viene attivato il pin di bit associato.
Si può collegare ciascun pin della legenda a un segnale e ottenere un'etichetta descrittiva
quando il segnale è VERO.

Se più di un pin della legenda è TRUE, verrà visualizzata la legenda con il numero più alto
VERO.

Se viene creato un pin di disabilitazione con <disable_pin> True </ disable_pin> e quel pin
è impostato su true, le etichette modificabili diventano grigio.

<multilabel>
<legends>["Label1","Label2","Label3","Label4",
"Label5","Label6"]</legends>
<font>("Helvetica", 20)</font>
<disable_pin>True</disable_pin>
</multilabel>

L'esempio precedente creerebbe i seguenti pin.

pyvcp.multilabel.0.disable
pyvcp.multilabel.0.legend0
pyvcp.multilabel.0.legend1
pyvcp.multilabel.0.legend2
pyvcp.multilabel.0.legend3
pyvcp.multilabel.0.legend4
pyvcp.multilabel.0.legend5

Se hai più di una multilabel, i pin creati incrementerebbero il numero come questo
pyvcp.multilabel.1.legend1.

6.5. LED

Un LED è utilizzato per indicare lo stato di un bit halpin. Il colore del LED sarà on_color
quando halpin è true, altrimenti off_color.

● <led> </led> - produce un LED rotondo


● < rectled > </rectled> - produce un LED rettangolare
● <halpin> nome </halpin> - nome del pin, il default è led.n, dove n è un intero che
viene incrementato per ciascun LED.
● <size> n </ size> - n è la dimensione del led in pixel, il valore predefinito è 20
● <on_color> color </on_color> - imposta il colore del LED quando il pin è true.
L'impostazione predefinita è verde. Vedi i colori per maggiori informazioni.
● <off_color> color < off_color> - imposta il colore del LED quando il pin è falso. Il
valore predefinito è rosso
● <height> n </height> - imposta l'altezza del LED in pixel
● <width> n </width> - imposta la larghezza del LED in pixel
● <disable_pin> false </disable_pin> - quando true aggiunge un pin disabilitato al led.
● <disabled_color> color </disabled_color> - imposta il colore del LED quando il pin è
disabilitato.

LED rotondo

<led>
<halpin>"my-led"</halpin>
<dimension>50</dimension>
<on_color>"green"</on_color>
<off_color>"red"</off_color>
</led>

Il codice sopra riportato ha prodotto questo esempio.

LED rettangolare

Questa è una variante del widget led.

<vbox>
<relief>RIDGE</relief>
<bd>6</bd>
<rectled>
<halpin>"my-led"</halpin>
<height>"50"</height>
<width>"100"</width>
<on_color>"green"</on_color>
<off_color>"red"</off_color>
</rectled>
</vbox>

Il codice sopra riportato ha prodotto questo esempio. Mostra anche un box verticale con
rilievo.

6.6. Buttons (Pulsanti)

Un pulsante viene utilizzato per controllare un pin BIT. Il pin verrà impostato su True
quando il pulsante viene premuto e tenuto premuto, e verrà impostato su False quando il
pulsante viene rilasciato. I pulsanti possono utilizzare le seguenti varianti opzionali.

● <padx> n </padx> - dove n è la quantità di spazio orizzontale extra.


● <pady> n </pady> - dove n è la quantità di spazio verticale extra.
● <activebackground> "color" </activebackground> : il cursore sul colore.
● <fg> "color" </fg> - il colore in primo piano.
● <bg> "color" </bg> - il colore di sfondo.
● <disable_pin> True </disable_pin> - disabilita il pin.

Pulsante di Testo

Un pulsante di testo controlla un bit halpin. Il halpin è falso finché non viene premuto il
pulsante, altrimenti è vero. Il pulsante è un pulsante momentaneo.
Il pulsante di testo ha un pin di disabilitazione opzionale che viene creato quando si aggiunge
<disable_pin> True </disable_pin>.

<button>
<halpin>"ok-button"</halpin>
<text>"OK"</ text>
</button>
<button>
<halpin>"abort-button"</halpin>
<text>"Abort"</text>
</button>

Il codice sopra riportato ha prodotto questo esempio.

Checkbutton (Pulsante di controllo)

Un pulsante di controllo controlla un bit halpin. Il halpin verrà impostato su True quando il
pulsante è selezionato e False quando il pulsante è deselezionato. Il check button è un
pulsante di attivazione/disattivazione del tipo. I Checkbuttons possono essere impostati
inizialmente come TRUE o FALSE nel campo di inizializzazione. Viene anche creato
automaticamente un pin chiamato changepin, che può commutare il Checkbutton tramite
HAL, se il valore collegato viene modificato, per aggiornare il display da remoto.

<checkbutton>
<halpin>"coolant-chkbtn"</halpin>
<text>"Coolant"</text>
<initval>1</initval>
</checkbutton>
<checkbutton>
<halpin>"chip-chkbtn"</halpin>
<text>"Chips "</text>
<initval>0</initval>
</checkbutton>

Il codice sopra riportato ha prodotto questo esempio. Il pulsante di controllo del refrigerante
è controllato. Nota gli spazi extra nel testo Chips per mantenere allineati i checkbutton.

Radiobutton (bottone radio)

Un radiobutton imposterà solo uno degli halpins a True. Gli altri pin sono impostati su False.
Può essere impostato il campo di inizializzazione per scegliere la selezione predefinita quando
viene visualizzato il pannello. Solo un pulsante di opzione può essere impostato su TRUE (1)
o solo il set di pin di numero più alto TRUE avrà quel valore.
<radiobutton>
<choices>["one", "two", "three"]</choices>
<halpin>"my-radio"</halpin>
<initval>0</initval>
</radiobutton>

Il codice sopra riportato ha prodotto questo esempio.

Notare che i pin HAL nell'esempio precedente si chiameranno my-radio.one, my-radio.two e


my-radio.three. Nell'immagine sopra, one è il valore selezionato.

6.7. Display numerici

I display numerici possono utilizzare le seguenti opzioni di formattazione

● <font> ("Nome font", n) </font> dove n è la dimensione del carattere


● <width> n </width> dove n è la larghezza complessiva dello spazio utilizzato
● < justify> pos </justify> dove pos è LEFT, CENTER o RIGHT (non funziona)
● <padx> n </padx> dove n è la quantità di spazio orizzontale extra
● <pady> n < pady> dove n è la quantità di spazio verticale extra

Number (Numero)

Il widget number visualizza il valore di un segnale floating.

<number>
<halpin>"my-number"</halpin>
<font>("Helvetica", 24)</font>
<format>"+ 4.4f"</format>
</number>

Il codice sopra riportato ha prodotto questo esempio.

● <font> - è una specifica per un tipo e dimensione di carattere. Un font che mostrerà
almeno la dimensione 200 è di tipo 10 courier, quindi per un widget Number molto
grande è possibile specificare:

<font>("courier 10 pitch", 100)</font>

● <format> - è un formato di specifica C-style che determina come viene visualizzato il


numero.
Numero s32

Il widget numero s32 mostra il valore di un numero s32. La sintassi è la stessa del number
tranne il nome che è <s32>. Assicurati che la larghezza sia sufficientemente ampia da coprire
il numero più grande che prevedi di utilizzare.

<s32>
<halpin>"my-number"</halpin>
<font>("Helvetica",24)</font>
<format>"6d"</format>
<width>6</width>
</s32>

Il codice sopra riportato ha prodotto questo esempio.

Numero u32

Il widget numero u32 mostra il valore di un numero u32. La sintassi è uguale al number
tranne il nome che è <u32>.

Bar (Barra)

Un widget bar mostra il valore di un segnale FLOAT sia graficamente utilizzando una barra di
visualizzazione che numericamente. Il colore della barra può essere impostato come un colore
nel suo intervallo (predefinito usando fillcolor) o impostato per cambiare il colore in base al
valore del halpin (deve essere impostato range1, range2 range3, se si desidera solo 2
intervalli, impostare 2 di loro allo stesso colore).

<bar>
<halpin>"my-bar"</halpin>
<min_>0</min_>
<max_>150</max_>
<bgcolor>"gray"</bgcolor>
<fillcolor>"red"</fillcolor>
<range1>0,100, "green"</range1>
<range2>101,135, "orange"</range2>
<range3>136, 150, "red"</range3>
</bar>

Il codice sopra riportato ha prodotto questo esempio.

Meter

Meter visualizza il valore di un segnale FLOAT utilizzando un indicatore tradizionale.


<meter>
<halpin>"mymeter"</halpin>
<text>"Battery"</text>
<subtext>"Volt"</subtext>
<size>250</size>
<min_>0</min_>
<max_>15.5</max_>
<majorscale>1</majorscale>
<minorscale>0.2</minorscale>
<region1>(14.5,15.5, "yellow")</region1>
<region2>(12,14.5, "green")</region2>
<region3>(0,12, "red")</region3>
</meter>

Il codice sopra riportato ha prodotto questo esempio.

6.8. Ingressi Numerici

Spinbox

Spinbox controlla un pin FLOAT. Aumenta o diminuisce il valore del pin premendo sulle
frecce o puntando verso la casella di selezione e ruotando la rotellina del mouse. Se il campo
param_pin è impostato su TRUE (1), verrà creato un pin che può essere utilizzato per
impostare la casella di selezione su un valore iniziale e per modificare a distanza il suo valore
senza input HID.

<spinbox>
<halpin>"my-spinbox"</halpin>
<min_>-12</min_>
<max_>33</max_>
<initval>0</initval>
<resolution>0.1</resolution>
<format>"2.3f"</format>
<font>("Arial", 30)</font>
<param_pin>1</param_pin>
</spinbox>

Il codice sopra riportato ha prodotto questo esempio.


Scale

Scale controlla un float o un pin s32. Aumenta o diminuisce il valore del pin sia trascinando il
cursore, sia indicando la scala e ruotando la rotellina del mouse. Il halpin avrà sia -f che -i
aggiunti ad esso per formare i pin float e s32. width è la larghezza del cursore in verticale e
l'altezza del cursore in orientamento orizzontale. Se il campo param_pin è impostato su
TRUE (1), verrà creato un pin che può essere utilizzato per impostare la casella di selezione su
un valore iniziale e per modificare a distanza il suo valore senza input HID.

<scale>
<font>("Helvetica", 16)</font>
<width>"25"</width>
<halpin>"my-hscale"</halpin>
<resolution>0.1</resolution>
<orient>HORIZONTAL</orient>
<initval>-15</initval>
<min_>-33</min_>
<max_>26</max_>
<param_pin>1</param_pin>
</scale>
<scale>
<font>("Helvetica", 16)</font>
<width>"50"</width>
<halpin>"my-vscale"</halpin>
<resolution>1</resolution>
<orient>VERTICAL</orient>
<min_>100</min_>
<max_>0</max_>
<param_pin>1</param_pin>
</scale>

Il codice sopra riportato ha prodotto questo esempio.

Dial

Il dial produce un float di HAL e reagisce sia alla rotellina del mouse che al trascinamento.
Doppio clic sinistro per aumentare la risoluzione e doppio clic destro per ridurre la
risoluzione di una cifra. L'output è limitato dai valori minimo e massimo. Il <cpr> è il
numero di segni di graduazione all'esterno dell'anello (attenzione ai numeri alti). Se il campo
param_pin è impostato su TRUE (1), verrà creato un pin che può essere utilizzato per
impostare la casella di selezione su un valore iniziale e per modificare a distanza il suo valore
senza input HID.

<dial>
<dimension>200</dimension>
<cpr>100</cpr>
<min_>-15</min_>
<max_>15</max_>
<text>"Dial"</text>
<initval>0</initval>
<resolution>0.001</resolution>
<halpin>"anaout"</halpin>
<dialcolor>"yellow"</dialcolor>
<edgecolor>"green"</edgecolor>
<dotcolor>"black"</dotcolor>
<param_pin>1</param_pin>
</dial>

Il codice sopra riportato ha prodotto questo esempio.

Jogwheel

Jogwheel simula un jogwheel reale emettendo un pin FLOAT che conta su o giù mentre la
ruota viene girata, sia trascinando un movimento circolare, o facendo ruotare la rotella del
mouse.

<jogwheel>
<halpin>"my-wheel"</halpin>
<cpr>45</cpr>
<size>250</size>
</jogwheel>

Il codice sopra riportato ha prodotto questo esempio.


6.9. Immagini

Le immagini visualizzate usano solo il formato immagine .gif. Tutte le immagini devono avere
la stessa dimensione. Le immagini devono trovarsi nella stessa directory del file ini (o nella
directory corrente se in esecuzione dalla riga di comando con halrun / halcmd).

Bit di immagine

L' image_bit alterna tra due immagini impostando il halpin su true o false.

<image name='fwd' file='fwd.gif'/>


<image name='rev' file='rev.gif'/>
<vbox>
<image_bit halpin='selectimage' images='fwd rev'/>
</vbox>

Questo esempio è stato prodotto dal codice precedente. Utilizzando i due file immagine
fwd.gif e rev.gif. FWD viene visualizzato quando selectimage è false e REV viene visualizzato
quando selectimage è true.

Immagine u32

L' image_u32 è lo stesso di image_bit tranne che hai essenzialmente un numero illimitato di
immagini e selezioni l'immagine impostando la halpin su un valore intero con 0 per la prima
immagine nella lista delle immagini e 1 per la seconda immagine, ecc.

<image name="stb" file='stb.gif'/>


<image name='fwd' file='fwd.gif'/>
<image name='rev' file='rev.gif'/>
<vbox>
<image_u32 halpin='selectimage' images='stb fwd rev'/>
</vbox>

Il codice precedente ha prodotto il seguente esempio aggiungendo l'immagine stb.gif.

Si noti che il valore predefinito è il minimo anche se è impostato su un valore superiore a


max, a meno che non vi sia un minimo negativo.

6.10. Contenitori

I contenitori sono widget che contengono altri widget. I contenitori sono usati per
raggruppare altri widget.

Borders

I contenitori sono specificati con due tag usati insieme. Il tag <relief> specifica il tipo di
bordo e <bd> specifica la larghezza del bordo.

● <relief> type </relief> - Dove type è FLAT, SUNKEN, RAISED, GROOVE, o RIDGE
● <bd> n </bd> - Dove n è la larghezza del bordo.

<hbox>
<button>
<relief>FLAT</relief>
<text>"FLAT"</text>
<bd>3</bd>
</button>
<button>
<relief >SUNKEN</relief>
<text>"SUNKEN"</text>
<bd>3</bd>
</button>
<button>
< relief >RAISED</relief>
<text>"RAISED"</text>
<bd>3</ bd>
</button>
<button>
<relief>GROOVE</relief>
<text>"GROOVE"</text>
<bd>3</bd>
</button>
<button>
<relief>RIDGE</ relief>
<text>"RIDGE"</text>
<bd>3</bd>
</button>
</hbox>
Il codice sopra riportato ha prodotto questo esempio.

Fill

Il riempimento del contenitore è specificato con il tag <boxfill fill = "" /> . Le voci valide sono
none, x, y ed entrambi. Il riempimento x è un riempimento orizzontale e il riempimento y è
un riempimento verticale

● <boxfill fill = "style" /> - Dove lo style è nessuno, x, y, o entrambi. L'impostazione


predefinita è x per Vbox e y per Hbox.

Anchor

Le ancore del contenitore sono specificate con il tag <boxanchor anchor = "" />. L'ancora
specifica dove posizionare ogni schiavo nel suo complesso. Le voci valide sono center, n, s, e,
w, per centro, nord, sud, est e ovest. Anche le combinazioni come sw, se, nw e ne sono valide.

● <boxanchor anchor = "position" /> - Dove position è al centro, n, s, e, w, ne, nw, se o


sw. L'impostazione predefinita è al centro.

Expand

L’espansione del contenitore è specificata con il tag booleano <boxexpand expand = "" />. Le
voci valide sono yes, no.

● <boxexpand expand = "boolean" /> - Dove boolean è yes o no. L'impostazione


predefinita è yes.

Hbox

Usa una Hbox quando vuoi raggruppare i widget orizzontalmente uno accanto all'altro.

<hbox>
<relief>RIDGE</relief>
<bd>6</ bd>
<label> <text>"a hbox:"</text> </label>
<LED> </LED>
<number> </number>
<bar> </bar>
</hbox>

Il codice sopra riportato ha prodotto questo esempio.


All'interno di un Hbox, puoi usare i tag <boxfill fill = "" />, <boxanchor anchor = "" /> e
<boxexpand expand = "" /> per scegliere come comportarsi quando gli oggetti nella casella
viene ridimensionata. Il valore predefinito è fill = "y", anchor = "center", expand = "yes" per
un Hbox.

Vbox

Usa una Vbox quando vuoi impilare verticalmente i widget uno sopra l'altro.

<vbox>
<relief>RIDGE</relief>
<bd>6</bd>
<label> <text>"a vbox:"</text> </label>
<LED> </LED>
<number> </number>
<bar> </bar>
</vbox>

Il codice sopra riportato ha prodotto questo esempio.

All'interno di una Vbox, puoi usare i tag <boxfill fill = "" />, <boxanchor anchor = "" /> e
<boxexpand expand = "" /> per scegliere come comportarsi quando gli oggetti nella casella
viene ridimensionata. Il valore predefinito è fill = "x", anchor = "center", expand = "yes" per
un Hbox.

Labelframe

Un labelframe è un frame con un groove e un'etichetta nell'angolo in alto a sinistra.

<labelframe text="Group Title">


<font>("Helvetica", 16)</font>
<hbox>
</led>
</led>
</hbox>
</labelframe>

Il codice sopra riportato ha prodotto questo esempio.


Tabella

Una tabella è un contenitore che consente il layout in una griglia di righe e colonne. Ogni riga
viene avviata da un tag <tablerow />. Un widget contenuto può estendersi su righe o colonne
attraverso l'uso del tag <tablespan rows = cols = /> . I lati delle celle a cui i widget contenuti
"attaccano" possono essere impostati mediante l'uso del tag <tablesticky sticky = /> . Una
tabella si espande sulle sue righe e colonne flessibili.

Esempio:

<table flexible_rows="[2]" flexible_columns="[1,4]">


<tablesticky sticky="new"/>
<tablerow />
<label>
<text>"A (cell 1,1)"</text>
<relief>RIDGE</relief>
<bd>3</bd>
</label>
<label text="B (cell 1,2)"/>
<tablespan columns="2"/>
<label text="C, D (cells 1,3 e 1,4)"/>
<tablerow />
<label text="E (cells 2,1)"/>
<tablesticky sticky="new"/>
<tablespan rows="2"/>
<label text="'spans\n2 rows'"/>
<tablesticky sticky="new"/>
<label text="G (cell 2,3)"/>
<label text="H (cell 2,4)"/>
<tablerow />
<label text="J (cell 3,1)"/>
<label text="K (cell 3,2)"/>
<U32 halpin="test"/>
</table>

Il codice sopra riportato ha prodotto questo esempio.

Tabs

Un'interfaccia a schede può risparmiare un bel po 'di spazio.

<tabs>
<names> ["spindle", "green eggs"]</names>
</tabs>
<tabs>
<name>["Spindle", "Green Eggs", "Ham"]</name>
<vbox>
<label>
<text>"Spindle speed:"</text>
</label>
<bar>
<halpin>"spindle-speed"</halpin>
<max_>5000</max_>
</bar>
</vbox>
<vbox>
<label>
<text>"(this is the green eggs tab)"</text>
</label>
</vbox>
<vbox>
<label>
<text>"(this tab has nothing on it)"</text>
</label>
</vbox>
</tabs>

Il codice sopra riportato ha prodotto questo esempio mostrando ogni scheda selezionata.
Introduzione al Classicladder
Sommario
1. Storia
2. Introduzione
3. Esempio
4. Circuito di accensione / spegnimento di base

1. Storia
Classic Ladder è un'implementazione gratuita di un interprete ladder, rilasciato sotto licenza
LGPL. È stato scritto da Marc Le Douarain.
Descrive l'inizio del progetto sul suo sito web:
Ho deciso di programmare un linguaggio ladder solo a scopo di test all'inizio del febbraio
2001. Era previsto che avrei dovuto partecipare a un nuovo prodotto dopo aver lasciato
l'azienda in cui lavoravo in quel momento. E stavo pensando che avere un linguaggio ladder
in quei prodotti potesse essere una buona opzione da considerare. E così ho iniziato a
codificare le prime linee per calcolare un ramo con elementi minimi e visualizzarlo
dinamicamente con Gtk, per vedere se la mia prima idea di realizzare tutto questo funziona.
E così velocemente ho scoperto che è avanzato abbastanza bene, ho continuato con elementi
più complessi: timer, pioli multipli, ecc ...
Voila, ecco questo lavoro ... e altro: ho continuato ad aggiungere funzionalità da allora.
da "Genesis" sul sito web di Classic Ladder
- Marc Le Douarain
Classic Ladder è stato adattato per funzionare con HAL di LinuxCNC e attualmente viene
distribuito insieme a LinuxCNC. Se ci sono problemi / problemi / bug, segnalali al progetto
LinuxCNC Machine Controller.

2. Introduzione
La logica ladder o il linguaggio di programmazione Ladder è un metodo per disegnare
schemi logici elettrici. Ora è un linguaggio grafico molto popolare per la programmazione di
controllori logici programmabili (PLC). È stato originariamente inventato per descrivere la
logica creata dai relè. Il nome si basa sull'osservazione che i programmi in questa lingua
ricordano le scale, con due binari verticali e una serie di pioli (rung) orizzontali tra di loro.
In Germania e altrove in Europa, lo stile è quello di disegnare i binari orizzontalmente lungo
la parte superiore e inferiore della pagina mentre i pioli vengono disegnati verticalmente da
sinistra a destra.
Un programma in logica ladder, chiamato anche schema ladder, è simile a uno schema per
un insieme di circuiti relè. La logica ladder è utile perché un'ampia varietà di ingegneri e
tecnici può comprenderla e usarla senza ulteriore addestramento a causa della somiglianza
con i circuiti reali.
La logica ladder è ampiamente utilizzata per programmare i PLC, dove è richiesto il controllo
sequenziale di un processo o di un'operazione di produzione. La logica ladder è utile per
sistemi di controllo semplici ma critici o per rielaborare i vecchi circuiti relè cablati. Poiché i
controllori logici programmabili sono diventati più sofisticati, è stato utilizzato anche in
sistemi di automazione molto complessi.
La logica ladder può essere pensata come un linguaggio basato su regole, piuttosto che un
linguaggio procedurale. Un rung nella scala rappresenta una regola. Se implementate con
relè e altri dispositivi elettromeccanici, le varie regole vengono eseguite contemporaneamente
e immediatamente. Quando implementate in un controllore logico programmabile, le regole
vengono generalmente eseguite sequenzialmente dal software, in un ciclo. Eseguendo il ciclo
abbastanza velocemente, in genere molte volte al secondo, si ottiene l'effetto di un'esecuzione
simultanea e immediata.
La logica ladder segue questi passaggi generali per il funzionamento.
 Leggi gli input
 Risolvi logica
 Aggiorna uscite

3. Esempio
I componenti più comuni di ladder sono i contatti (input), che di solito sono NC
(normalmente chiuso) o NO (normalmente aperto) e bobine (uscite).

 il contatto NO

 il contatto NC

 la bobina (uscita)
Naturalmente ci sono molti altri componenti per un linguaggio a scala completa, ma la
comprensione di questi ti aiuterà a cogliere il concetto generale.
La scala è composta da uno o più pioli (rung). Questi pioli sono tracce orizzontali (che
rappresentano i fili), con componenti su di essi (input, output e altro), che vengono valutati
da sinistra a destra.
Questo esempio è il ramo più semplice:

L'ingresso a sinistra, B0, un contatto normalmente aperto, è collegato alla bobina (uscita) a
destra, Q0. Ora immagina che venga applicata una tensione all'estremità più a sinistra,
perché l'ingresso B0 diventa vero (ad esempio, l'ingresso è attivato o l'utente ha premuto il
contatto NO). La tensione ha un percorso diretto per raggiungere la bobina (uscita) a destra,
Q0. Di conseguenza, la bobina Q0 (uscita) passerà da 0 / off / false a 1 / on / true. Se l'utente
rilascia B0, l'uscita Q0 torna rapidamente a 0 / off / false.

4. Circuito di accensione / spegnimento di base


Basandosi sull'esempio sopra, supponiamo di aggiungere un interruttore che si chiude ogni
volta che la bobina Q0 è attiva. Questo sarebbe il caso in un relè, in cui la bobina può attivare
i contatti dell'interruttore; o in un contattore, dove ci sono spesso diversi piccoli contatti
ausiliari oltre ai grandi contatti trifase che sono la caratteristica principale del contattore.
Poiché questo interruttore ausiliario è pilotato dalla bobina Q0 nel nostro esempio
precedente, gli daremo lo stesso numero della bobina che lo guida. Questa è la pratica
standard seguita in tutta la programmazione ladder, anche se all'inizio potrebbe sembrare
strano vedere un interruttore etichettato come una bobina. Chiamiamo quindi questo
contatto ausiliario Q0 e collegalo attraverso il contatto pulsante B0 del nostro esempio
precedente.
Diamo un'occhiata a questo:

Come prima, quando l'utente preme il pulsante B0, la bobina Q0 si accende. E quando la
bobina Q0 si accende, l'interruttore Q0 si accende. Ora succede la parte interessante.
Quando l'utente rilascia il pulsante B0, la bobina Q0 non si ferma come prima. Questo
perché l'interruttore Q0 di questo circuito tiene premuto il pulsante dell'utente. Quindi
vediamo che l'interruttore Q0 sta ancora tenendo accesa la bobina Q0 dopo che il pulsante di
avvio è stato rilasciato.
Questo tipo di contatto su una bobina o un relè, utilizzato in questo modo, viene spesso
chiamato contatto di ritenuta , poiché tiene sulla bobina a cui è associato. Viene anche
occasionalmente chiamato un contatto di tenuta , e quando è attivo si dice che il circuito è
sigillato .
Sfortunatamente, il nostro circuito finora ha un piccolo uso pratico, perché, anche se
abbiamo un pulsante di avvio o di avvio sotto forma di pulsante B0, non abbiamo modo di
chiudere questo circuito una volta avviato. Ma è facile da risolvere. Tutto ciò di cui abbiamo
bisogno è un modo per interrompere la potenza della bobina Q0. Quindi aggiungiamo un
pulsante normalmente chiuso (NC) appena prima della bobina Q0.
Ecco come sarebbe:

Ora abbiamo aggiunto o fermato il pulsante B1. Se l'utente lo spinge, il contatto dal piolo
alla bobina è interrotto. Quando la bobina Q0 perde potenza, scende a 0 / off / false.
Quando la bobina Q0 si spegne, commuta anche Q0, quindi il contatto di tenuta è interrotto
o il circuito non è chiuso. Quando l'utente rilascia il pulsante di arresto , il contatto viene
ripristinato dal ramo alla bobina Q0, ma il ramo si è spento, quindi la bobina non ritorna.
Questo circuito è stato usato per decenni praticamente su ogni macchina che ha un motore
trifase controllato da un contattore, quindi era inevitabile che sarebbe stato adottato da
programmatori ladder / PLC. È anche un circuito molto sicuro, nel senso che se start e stop
vengono entrambi premuti contemporaneamente, la funzione stop prevale sempre.
Questo è il componente base di gran parte della programmazione ladder, quindi se sei nuovo,
faresti bene ad assicurarti di capire come funziona questo circuito.
Programmazione di ClassicLadder
Sommario
1. Concetti ladder
2. Lingue
3. Componenti
3.1. File
3.2. Modulo Realtime in tempo reale
3.3. Variabili
4. Caricamento del modulo utente di Classic Ladder
5. GUI Classic Ladder - L’ interfaccia utente di ClassicLadder
5.1. Gestione delle sezioni (Section Manager)
5.2. Sezione Display (Section Display )
5.3. Le finestre delle Variabili (Variable Windows)
5.4. La finestra dei Simboli (Symbol Window)
5.5. La finestra dell'Editor (Editor Window)
5.6. La finestra di configurazione (Config Window)
6. Oggetti Ladder
6.1. CONTATTI
6.2. TIMER IEC
6.3. TIMER T
6.4. MONOSTABLES
6.5. CONTATORI (COUNTERS)
6.6. CONFRONTARE (COMPARE)
6.7. ASSEGNAZIONE VARIABILI
6.8. COILS
7. Variabili classicladder
8. Programmazione GRAFCET
9. Modbus
9.1. Impostazioni MODBUS
9.2. MODBUS Informazioni
9.3. Errori di comunicazione
9.4. Errori MODBUS
10.Impostazione di Classic Ladder
10.1. Aggiungere moduli
10.2. Aggiunta della logica ladder

1. Concetti ladder
Classic Ladder è un tipo di linguaggio di programmazione originariamente implementato su
PLC industriali (si chiama Programmazione ladder). Si basa sul concetto di contatti relè e
bobine e può essere utilizzato per costruire controlli logici e funzioni in un modo che è
familiare a molti integratori di sistemi. Il ladder (scala) consiste di pioli (rung) che possono
avere rami e assomiglia a un circuito elettrico. È importante sapere come vengono valutati i
programmi ladder durante l'esecuzione.
Sembra naturale che ogni riga venga valutata da sinistra a destra, quindi la riga successiva in
basso, ecc., Ma non funziona in questo modo nella logica ladder. La logica ladder analizza i
rami della scala 3 volte per modificare lo stato delle uscite.
 gli input sono letti e aggiornati
 la logica è interpretata
 vengono impostate le uscite
Ciò può confondere in un primo momento se l'output di una riga viene letto dall'input di un
altro ramo. Ci sarà una scansione prima che il secondo input diventi vero dopo che l'uscita è
stata impostata.
Un'altra regola con la programmazione ladder è la regola "Last One Wins". Se hai lo stesso
output in diverse posizioni del tuo ladder, lo stato dell'ultimo sarà quello a cui è impostato
l'output.

2. Lingue
La modalità più comune utilizzata quando si lavora con Classic Ladder è ladder . Classic
Ladder supporta anche il Diagramma funzionale sequenziale (Grafcet).

3. Componenti
Ci sono 2 componenti in Classic Ladder.
 Il modulo in tempo reale classicladder_rt
 La user space module di ClassicLadder (inclusa una GUI)

3.1. File
In genere i componenti ladder classici vengono inseriti nel file custom.hal se si lavora da una
configurazione generata da Stepconf. Questi non devono essere inseriti nel file
custom_postgui.hal o il menu dell'editor Ladder sarà disattivato.

Nota I file Ladder (.clp) non devono contenere spazi vuoti nel nome.

3.2. Modulo in tempo reale


Il caricamento del modulo in tempo reale di Classic Ladder (classicladder_rt) è possibile da
un file HAL o direttamente usando un'istruzione halcmd. La prima riga carica in tempo reale
il modulo Classic Ladder. La seconda riga aggiunge la funzione classicladder.0.refresh al
thread del servo. Questa riga rende l'aggiornamento di Classic Ladder alla velocità del thread
servo.
loadrt classicladder_rt
addf classicladder.0.refresh servo-thread
La velocità del thread in cui è in esecuzione Classic Ladder influisce direttamente sulla
reattività agli input e output. Se riesci a attivare e disattivare un interruttore più velocemente
rispetto a Classic Ladder, puoi dover accelerare il thread. Il più veloce Classic Ladder può
aggiornare i rami in un millisecondo. Puoi metterlo in un thread più veloce ma non si
aggiornerà più velocemente. Se lo inserisci in un thread più lento di un millisecondo, Classic
Ladder aggiornerà i rami più lentamente. Il tempo di scansione corrente verrà visualizzato
sul display della sezione, arrotondato a microsecondi. Se il tempo di scansione è più lungo di
un millisecondo, potresti ridurre il ladder o inserirla in un rung più lento.

3.3. Variabili
È possibile configurare il numero di ciascun tipo di oggetto ladder durante il caricamento del
modulo in tempo reale di Classic Ladder. Se non si configura il numero di oggetti ladder,
Classic Ladder utilizzerà i valori predefiniti.
Tabella 1. Conteggio Variabili predefinito

Nome dell'oggetto Nome variabile Valore predefinito


Numero di pioli (numRungs) 100

Numero di bit (numBits) 20

Numero di variabili word (numWords) 20

Numero di timer (numTimers) 10

Numero di temporizzatori IEC (NumTimersIec) 10

Numero di monostables (numMonostables) 10

Numero di contatori (numCounters) 10

Numero di pin di bit di ingresso HAL (numPhysInputs) 15

Numero di pin di bit di uscita HAL (numPhysOutputs) 15

Numero di espressioni aritmetiche (NumArithmExpr) 50

Numero di sezioni (numSections) 10

Numero di simboli (numSymbols) Auto

Numero di ingressi S32 (NumS32in) 10

Numero di uscite S32 (NumS32out) 10

Numero di ingressi Float (NumFloatIn) 10

Numero di uscite Float (NumFloatOut) 10

Gli oggetti di maggior interesse sono numPhysInputs, numPhysOutputs, numS32in e


numS32out.
La modifica di questi numeri cambierà il numero di pin di bit HAL disponibili.
numPhysInputs e numPhysOutputs controllano quanti pin HAL (on / off) sono disponibili.
numS32in e numS32out controllano quanti pin di HAL con segno intero (+ - numero intero)
sono disponibili.
Ad esempio (non hai bisogno di tutti questi per cambiarne solo alcuni):
loadrt classicladder_rt numRungs = 12 numBits = 100 numWords = 10
numTimers = 10 numMonostables = 10 numCounters = 10 numPhysInputs = 10
numPhysOutputs = 10 numArithmExpr = 100 numSections = 4 numSymbols = 200
numS32in = 5 numS32out = 5
Per caricare il numero predefinito di oggetti:
loadrt classicladder_rt

4. Caricamento del modulo utente di Classic Ladder


I comandi HAL Classic Ladder devono essere eseguiti prima che la GUI venga caricata o la
voce di menu Ladder Editor non funzioni. Se hai utilizzato Stepper Config Wizard, posiziona
tutti i comandi HAL di Classic Ladder nel file custom.hal.
Per caricare il modulo utente:
loadusr classicladder

È possibile caricare solo un file .clp. Se hai bisogno di dividere la tua scala usa
Nota Sections.
Per caricare un file ladder:
loadusr classicladder myladder.clp
Opzioni di caricamento della scala classica
 --nogui - (carica senza l'editor ladder) normalmente usato dopo che il debug è
terminato.
 --modbus_port = port - (carica il numero della porta modbus)
 --modmaster - (inizializza il master MODBUS) dovrebbe caricare il programma
ladder allo stesso tempo o TCP è la porta predefinita.
 --modslave - (inizializza lo slave MODBUS) solo TCP
Per utilizzare Classic Ladder con HAL senza LinuxCNC:
loadusr -w classicladder
L'opzione -w dice a HAL di non chiudere l'ambiente HAL fino a quando non viene
completato il caricamento del Classic Ladder.
Se si carica per la prima volta il programma ladder con l'opzione --nogui , quindi si carica
nuovamente Classic Ladder senza opzioni, la GUI visualizzerà l'ultimo programma ladder
caricato.
In AXIS è possibile caricare la GUI da File / Ladder Editor ...

5. La classica interfaccia utente di Ladder


Se si carica Classic Ladder con la GUI, verranno visualizzate due finestre: la sezione display e
la sezione manager.

5.1. Responsabile delle sezioni


Al primo avvio di Classic Ladder si ottiene una finestra vuota di Sections Manager.

Figura 1. Finestra di default del gestore delle sezioni


Questa finestra consente di nominare, creare o eliminare sezioni e scegliere la lingua
utilizzata da quella sezione. Questo è anche il modo in cui si nomina una subroutine per le
call coils.
5.2. Section Display
Al primo avvio di Classic Ladder si ottiene una finestra di visualizzazione della sezione vuota.
Viene visualizzato un rung vuoto.

Figura 2. Finestra di visualizzazione della sezione Diplay


La maggior parte dei pulsanti è auto esplicativa:
Il pulsante Vars serve per vedere le variabili, attivarle per visualizzarne una, l'altra,
entrambe, o nessuna delle finestre.
Il pulsante Config è usato per modbus e mostra il numero massimo di elementi ladder che
sono stati caricato con il modulo in tempo reale.
Il pulsante Symbols visualizzerà un elenco modificabile di simboli per le variabili
(suggerimento puoi nominare input, output, bobine, ecc.).
Il pulsante Quit chiuderà il programma utente che significa chiudere Modbus e il display. Il
programma ladder in tempo reale continuerà a funzionare in background.
La casella di controllo in alto a destra consente di selezionare se visualizzare nomi di variabili
o nomi di simboli
Si potrebbe notare che c'è una riga sotto il display del programma ladder . Questa è la barra
di stato che fornisce informazioni sugli elementi del programma ladder su cui si fa clic nella
finestra di visualizzazione. Questa riga di stato ora mostrerà i nomi dei segnali HAL per le
variabili% I,% Q e la prima% W (in un'equazione). Potresti vedere alcune etichette strane,
come (103) nei rung. Questo viene visualizzato (volutamente) a causa di un vecchio bug-
quando si cancellano elementi le versioni precedenti a volte non cancellavano l'oggetto con il
codice corretto. Potresti aver notato che il pulsante di connessione orizzontale lungo, a volte
non funzionava nelle versioni precedenti. Questo perché cercava il codice libero ma trovava
qualcos'altro. Il numero tra parentesi è il codice non riconosciuto. Il programma ladder
funzionerà ancora correttamente, per risolvere il problema cancellare i codici con l'editor e
salvare il programma.
5.3. Le finestre Variable
Si tratta di due finestre di variabili: la Bit Status Window (finestra di stato dei bit -
booleano) e la Watch Window (finestra di controllo - numero intero con segno). Il pulsante
Vars si trova nella finestra Section Display Window, attiva il pulsante Vars per visualizzare
l'uno, l'altro, entrambi, oppure nessuna delle finestre variabili.

Figura 3. Bit Status Window


La Bit Status Window mostra alcuni dati variabili booleani (acceso / spento). Si noti che
tutte le variabili iniziano con il segno %. Le variabili % I rappresentano i pin di bit di ingresso
HAL. Il %Q rappresenta la bobina del relè e i pin del bit di uscita HAL. La %B rappresenta
una bobina relè interna o un contatto interno. Le tre aree di modifica in alto consentono di
selezionare quali 15 variabili verranno visualizzate in ogni colonna. Ad esempio, se la colonna
% B Variable fosse alta 15 voci e si inserisse 5 nella parte superiore della colonna, verrebbero
visualizzate le variabili da %B5 a %B19. Le caselle di controllo consentono di impostare e
disattivare manualmente le variabili% B purché il programma ladder non le imposti come
output. Qualsiasi bit impostato come output dal programma quando Classic Ladder è in
esecuzione non può essere modificato e verrà visualizzato come selezionato se attivato e
deselezionato se disattivato.
Figura 4. Watch Window
La Watch Window (finestra di controllo) mostra lo stato delle variabili. La casella di
modifica accanto è il numero memorizzato nella variabile e la casella a discesa a fianco
consente di scegliere se il numero da visualizzare sia in esadecimale, decimale o binario. Se
nella symbol window (finestra dei simboli) sono definiti i nomi dei simboli per le variabili
word che mostrano e la casella di controllo dei simboli del display è selezionata nella finestra
di visualizzazione della sezione, verranno visualizzati i nomi dei simboli. Per modificare la
variabile visualizzata, digitare il numero della variabile, ad esempio %W2 (se la casella di
controllo dei simboli del display non è selezionata) o digitare il nome del simbolo (se la
casella di controllo dei simboli del display è selezionata) su un numero/nome di variabile
esistente e premere il tasto Invio.

5.4. Symbol Window


Figura 5. Finestra Symbols Names
Questa è una lista di nomi di simboli da utilizzare al posto di nomi di variabili da visualizzare
nella finestra della sezione quando la casella di controllo dei simboli del display è selezionata.
Aggiungi il nome della variabile (ricorda il simbolo % e le lettere maiuscole), il nome del
simbolo. Se la variabile ha un segnale HAL collegato ad esso (%I, % Q e % W - se hai caricato
il pin s32 con il modulo in tempo reale), la sezione dei commenti mostrerà il nome del
segnale HAL corrente o la sua mancanza. I nomi dei simboli dovrebbero essere mantenuti
corti per essere visualizzati meglio. Tieni presente che puoi visualizzare i nomi di segnale
HAL più lunghi di % I,% Q e% W variabili
facendo clic su di essi nella finestra della sezione. Tra i due, si dovrebbe essere in grado di
tenere traccia di ciò a cui è collegato il programma ladder!

5.5. La finestra dell'Editor


Figura 6. Finestra dell'Editor
 Aggiungi : aggiunge un rung dopo il rung selezionato
 Inserisci : inserisce un ramo prima del rung selezionato
 Elimina : elimina il rung selezionato
 Modifica : apre il rung selezionato per la modifica
A partire dall'immagine in alto a sinistra:
 Selettore oggetti, Gomma
 Ingresso NO, Ingresso NC, Ingresso Fronte di salita, Ingresso Fronte di discesa
 Connessione orizzontale, connessione verticale, connessione orizzontale lunga
 Timer IEC Block, Counter Block, Compare Variable
 Old Timer Block, Old Monostable Block (Questi sono stati sostituiti dal timer IEC)
 COILS - NO Output, NC Output, Set Output, Reset Output
 Jump Coil, Call Coil, assegnazione variabile
Una breve descrizione di ciascuno dei pulsanti:
 Selettore : consente di selezionare oggetti esistenti e modificare le informazioni.
 Gomma : cancella un oggetto.
 Contatto NO : crea un contatto normalmente aperto. Può essere un contatto di
ingresso HAL-pin esterno (% I), un contatto della bobina del bit interno (% B) o un
contatto della bobina esterna (% Q). Il contatto di ingresso pin HAL è chiuso quando il
pin HAL è vero. I contatti della bobina sono chiusi quando la bobina corrispondente è
attiva (il contatto %Q2 si chiude quando la bobina %Q2 è attiva).
 Contatto NC : crea un contatto normalmente chiuso. È lo stesso del contatto NO
eccetto che il contatto è aperto quando il pin HAL è vero o la bobina è attiva.
 Rising Edge Contact - crea un contatto che viene chiuso quando il pin HAL passa da
False a true o la bobina da non attiva a attiva.
 Falling Edge Contact : crea un contatto che viene chiuso quando il pin HAL passa da
true a false o la bobina da active a not.
 Connessione orizzontale : crea una connessione orizzontale agli oggetti.
 Connessione verticale : crea una connessione verticale con linee orizzontali.
 Horizontal Running Connection : crea una connessione orizzontale tra due oggetti ed
è un modo rapido per connettere oggetti che si trovano a più di un blocco di distanza.
 Temporizzatore IEC : crea un timer e sostituisce il timer .
 Timer : crea un modulo timer (deprecato, utilizzare invece il temporizzatore IEC).
 Monostabile : crea un modulo monostabile one-shot
 Contatore : crea un modulo contatore.
 Confronta : crea un blocco di confronto per confrontare la variabile con valori o altre
variabili. (ad es.% W1 <= 5 o% W1 =% W2) La comparazione non può essere
posizionata nella parte destra del display della sezione.
 Assegnazione variabile : crea un blocco assegnazione in modo da assegnare valori alle
variabili. (ad es. %W2 = 7 o %W1 = %W2) Le funzioni di ASSEGNAZIONE possono
essere posizionate solo nella parte destra del display della sezione.

5.6. Finestra di configurazione


La finestra di configurazione mostra lo stato attuale del progetto e ha le schede di
configurazione Modbus.
Figura 7. Finestra di configurazione

6. Oggetti ladder
6.1. CONTATTI
Rappresentazione di interruttori o contatti relè. Sono controllati dalla lettera e dal numero
variabile assegnati a loro.
La lettera variabile può essere B, I o Q e il numero può essere fino a un numero di tre cifre es.
%I2, %Q3 o %B123. La variabile I è controllata da un pin di ingresso HAL con un numero
corrispondente. La variabile B è per i contatti interni, controllata da una bobina B con un
numero corrispondente. La variabile Q è controllata da una bobina Q con un numero
corrispondente. (come un relè con più contatti). Ad esempio se HAL pin classicladder.0.in-
00 è vero allora %I0 NO il contatto sarebbe attivo (chiuso, vero, come lo vuoi chiamare). Se
la bobina %B7 è eccitata (attiva, vera, ecc.), allora il contatto NO B7 sarebbe attivo. Se la
bobina %Q1 è eccitata allora il contatto % Q1 NO sarà attivo (e il pin HAL classicladder.0.out-
01 sarebbe vero).
 NO contatto (Normalmente aperto) Quando la variabile è falsa, l'interruttore è
disattivato.

 Contatto NC - (Normalmente chiuso) Quando la variabile è falsa, l'interruttore è


attivo.
 Rising Edge Contact - Quando la variabile passa da false a true, l'opzione viene
attivata su PULSED.
 Contatto caduta - Quando la variabile cambia da vero a falso, l'interruttore è attivato
su PULSED.

6.2. TIMER IEC


Rappresentano nuovi timer per il conto alla rovescia. I temporizzatori IEC sostituiscono i
timer e i monostabili.
I temporizzatori IEC hanno 2 contatti.
 I - contatto di input
 Q - contatto di uscita
Ci sono tre modalità: TON, TOF, TP.
 TON - Quando l'input del timer è vero, il conto alla rovescia inizia e continua finché
l'input rimane true. Al termine del conto alla rovescia e finché l'input del timer è
ancora true, l'output sarà true.
 TOF - Quando l'input del timer è true, imposta l'output true. Quando l'input è false, il
timer esegue il conto alla rovescia quindi imposta l'output false.
 TP - Quando l'ingresso del timer è pulsato true o tenuto true, il timer imposta l'uscita
vera finché il timer non conta alla rovescia (un colpo).
Gli intervalli di tempo possono essere impostati in multipli di 100 ms, secondi o minuti.
Esistono anche variabili per i timer IEC che possono essere lette e/o scritte per confrontare o
utilizzare blocchi.
 % TMxxx.Q - timer completato (booleano, read write)
 % TMxxx.P – preset timer (read write)
 % TMxxx.V - valore del timer (read write)

6.3. TIMER
Rappresenta i timer per il conto alla rovescia. Questo è deprecato e sostituito da
temporizzatori IEC.
I timer hanno 4 contatti.
 E - enable (input) avvia il timer quando è true, reimposta quando diventa falso
 C - control (input) deve essere acceso per il timer da eseguire (in genere connettersi a
E)
 D - done (output) true quando il timer è scaduto e fino a quando E rimane true
 R - running (output) true quando il timer è in esecuzione
La base del timer può essere multipli di millisecondi, secondi o minuti.
Esistono anche variabili per i timer che possono essere lette e / o scritte per confrontare o
utilizzare blocchi.
 % Txx.R - Timer xx in esecuzione (booleano, sola lettura)
 % Txx.D - Timer xx done (Booleano, sola lettura)
 % Txx.V - Timer xx valore corrente (numero intero, sola lettura)
 % Txx.P - Timer xx preset (intero, lettura o scrittura)

6.4. monostabili
Rappresenta i timer one-shot originali. Questo è ora deprecato e sostituito da temporizzatori
IEC.
I monostables hanno 2 contatti, I e R.
 I - input (input) avvierà il timer mono in esecuzione.
 R - running (output) sarà vero mentre il timer è in esecuzione.
Il contatto I è sensibile al segnale in salita, ovvero inizia il timer solo quando si passa da falso
a vero (o viceversa). Mentre il timer è in esecuzione, il contatto I può cambiare senza alcun
effetto sul timer in esecuzione. R sarà vero e rimarrà vero fino a quando il timer non avrà
completato il conteggio a zero. La base del timer può essere multipla di millisecondi, secondi
o minuti.
Esistono anche variabili per monostables che possono essere lette e / o scritte in comparativi
o blocchi operativi.
 % Mxx.R - Monostabile xx in esecuzione (booleano, sola lettura)
 % Mxx.V - Valore attuale monostabile xx (intero, sola lettura)
 % Mxx.P - Preimpostazione monostabile xx (intero, lettura o scrittura)

6.5. CONTATORI
Rappresenta i contatori su/giù.
Ci sono 7 contatti:
 R - reset (input) resetterà il conteggio a 0.
 P - preset (input) imposterà il conteggio al numero preimpostato assegnato dal menu
di modifica.
 U -up count (input) aggiungerà uno al conteggio.
 D -down count (input) sottrarrà uno dal conteggio.
 E - under flow (output) sarà true quando il conteggio passa da 0 a 9999.
 D - done (output) sarà vero quando il conteggio è uguale al preset.
 F - overflow (output) sarà vero quando il conteggio passa da 9999 a 0.
I contatti di conteggio avanti e indietro sono sensibili ai cambi, ovvero contano solo quando
il contatto cambia da falso a vero (o disattivato se preferisci).
L'intervallo è compreso tra 0 e 9999.
Esistono anche variabili per contatori che possono essere letti e / o scritti in comparativi o
blocchi operativi.
 % Cxx.D - Counter xx done (Boolean, sola lettura)
 % Cxx.E - Counter xx overflow vuoto (booleano, sola lettura)
 % Cxx.F - Contatore xx overflow completo (booleano, sola lettura)
 % Cxx.V - Valore corrente contatore xx (intero, lettura o scrittura)
 % Cxx.P - Preset contatore xx (intero, lettura o scrittura)

6.6. COMPARE
Per confronto aritmetico. Variabile % XXX = a questo numero (o al numero valutato)
Il blocco compare è vero quando il confronto è vero. Puoi usare la maggior parte dei simboli
matematici:
 +, -, *, /, = (simboli matematici standard)
 <(minore di),> (maggiore di), <= (minore o uguale),> = (maggiore o uguale), <> (non
uguale)
 (,) separare nell'esempio di gruppi % IF1 = 2, e % IF2 <5 in pseudo-codice si traduce
in se % IF1 è uguale a 2 e % IF2 è minore di 5, quindi il confronto è vero. Notare la
virgola che separa i due gruppi di comparazioni.
 ^ (esponente),% (modulo), & (e), | (o),. -
 ABS (assoluto), MOY (medio francese), AVG (medio)
Ad esempio ABS (% W2) = 1, MOY (% W1,% W2) <3.
Nessuno spazio è consentito nell'equazione di confronto. Ad esempio% C0.V>% C0.P è
un'espressione di confronto valida mentre% C0.V>% CO.P non è un'espressione valida.
C'è una lista di Variabili nella pagina che può essere usata per leggere e scrivere sugli oggetti
ladder. Quando viene aperto un nuovo blocco di confronto, assicurati di eliminare il simbolo
# quando inserisci un confronto.
Per scoprire se la variabile di parola # 1 è inferiore a 2 volte il valore corrente del contatore #
0, la sintassi sarebbe:
%W1<2*%C0.V
Per scoprire se S32in bit 2 è uguale a 10 la sintassi sarebbe:
%EW2=10
Nota: Compare usa il segno uguale semplice e non il doppio uguale a cui i programmatori
sono abituati.

6.7. ASSEGNAZIONE VARIABILE


Per l'assegnazione di variabili, ad es. assegnare questo numero (o numero valutato) a questa
variabile % xxx, ci sono due funzioni matematiche MINI e MAXI che controllano una
variabile per valori massimi (0x80000000) e minimi (0x07FFFFFFF) (si pensi ai valori con
segno) e non consente di andare oltre.
Quando viene aperto un nuovo blocco di assegnazione delle variabili, assicurati di eliminare
il simbolo # quando inserisci un assegnazione.
Per assegnare un valore di 10 alla preselezione timer di IEC Timer0 la sintassi sarebbe:
%TM0.P=10
Per assegnare il valore di 12 a s32out bit 3 la sintassi sarebbe:
%QW3=12

Quando si assegna un valore a una variabile con il blocco di assegnazione delle


Nota variabili, il valore viene mantenuto fino a quando non si assegna un nuovo valore
utilizzando il blocco di assegnazione delle variabili. L'ultimo valore assegnato verrà
ripristinato all'avvio di LinuxCNC.
La seguente figura mostra un'Assegnazione e un Esempio di confronto. %QW0 è un bit
S32out e %IW0 è un bit S32in. In questo caso il pin HAL classicladder.0.s32out-00 verrà
impostato su un valore di 5 e quando il pin HAL classicladder.0.s32in-00 è 0, il pin HAL
classicladder.0.out-00 verrà impostato su True .

Figura 8. Esempio Assegna / Confronta


6.8. COILS
I COIL (bobine) rappresentano bobine tipo relè. Sono controllati dalla lettera e dal numero
variabile assegnati a loro.
La lettera variabile può essere B o Q e il numero può essere fino a un numero di tre cifre es.
%Q3 o %B123. Le bobine Q controllano i pin di uscita HAL, ad es. se %Q15 è eccitato, allora
l’HAL pin classicladder.0.out-15 sarà vero. I coil B sono bobine interne utilizzate per
controllare il flusso del programma.
 NO COIL - (una bobina del relè.) Quando la bobina è eccitata, il contatto NO sarà
chiuso (acceso, vero, ecc.)
 NC COIL - (una bobina di relè che inverte i suoi contatti). Quando la bobina è eccitata,
il contatto NO sarà aperto (spento, falso, ecc.)
 SET COIL - (una bobina relè con contatti a scatto). Quando la bobina è eccitata, il
contatto NO viene chiuso.
 RESET COIL - (una bobina di relè con contatti a scatto) Quando la bobina è eccitata È
N.O. il contatto verrà bloccato aperto.
 JUMP COIL - (una bobina goto ) quando la bobina è energizzata il programma ladder
salta su un ramo (nella sezione CURRENT) - i punti di salto sono indicati da
un'etichetta di ramo. (Aggiungi etichette del ramo nel display della sezione, riquadro
in alto a sinistra)
 CALL COIL - (una bobina di gosub) quando la bobina è eccitata il programma salta ad
una sezione di subroutine designata da un numero di subroutine - le subroutine sono
designate da SR0 a SR9 (designarle nel gestore di sezione)

Se si usa un contatto NC con una bobina NC, la logica funzionerà (quando


avvertimento la bobina è eccitata il contatto sarà chiuso) ma è davvero difficile da
seguire!
JUMP COIL
Una JUMP COIL viene utilizzata per saltare a un'altra sezione, come un goto nel linguaggio
di programmazione BASIC.
Se guardi in alto a sinistra nella finestra di visualizzazione delle sezioni vedrai una piccola
casella di etichetta e una casella di commento più lunga accanto. Ora vai su Editor →
Modifica quindi torna alla casella, digita un nome.
Vai avanti e aggiungi un commento nella sezione commenti. Questo nome etichetta è il solo
nome di questo ramo ed è utilizzato dalla JUMP COIL per identificare dove andare.
Quando si posiziona una JUMP COIL, aggiungerla nella posizione più a destra e modificare
l'etichetta sul rango a cui si desidera eseguire JUMP.
CALL COIL
Una CALL COIL è usata per andare ad una sezione di subroutine e poi tornare, come un
gosub nel linguaggio di programmazione BASIC.
Se vai nella finestra del gestore sezioni, premi il pulsante Aggiungi sezione. Puoi dare un
nome a questa sezione, selezionare la modalità che userà (ladder o sequenziale) e selezionare
il tipo (main o subroutine).
Selezionare un numero di subroutine (SR0 per esempio). Verrà visualizzata una sezione
vuota e sarà possibile creare la subroutine.
Al termine, torna al gestore di sezione e fai clic sulla tua sezione principale (nome predefinito
prog1).
Ora puoi aggiungere una CALL COIL al tuo programma. Le CALL COIL devono essere
posizionate nella posizione più a destra nel piolo.
Ricordarsi di cambiare l'etichetta con il numero di subroutine scelto in precedenza.

7. Variabili ClassicLadder
Queste variabili sono usate in COMPARE o OPERATE per ottenere informazioni, o cambiare
le specifiche, di oggetti ladder come cambiare un preset del contatore, o vedere se un timer
viene eseguito nel programma.
Elenco di variabili:
 % Bxxx - Memoria bit xxx (Boolean)
 % Wxxx - Memoria word xxx (numero intero con segno a 32 bit)
 % IWxxx - Memoria word xxx (S32 in pin)
 % QWxxx - Memoria word xxx (S32 out pin)
 % IFxx - Memoria word xx (Float in pin) (convertita in S32 in Classic Ladder)
 % QFxx - Memoria word xx (Float out pin) (convertita in S32 in Classic Ladder)
 % Txx.R - Timer xx in esecuzione (booleano, solo lettura utente)
 % Txx.D - Timer xx done (Boolean, solo lettura utente)
 % Txx.V - Timer xx valore corrente (intero, solo lettura utente)
 % Txx.P - Timer xx preset (intero)
 % TMxxx.Q - Timer xxx done (Boolean, read write)
 % TMxxx.P - Timer xxx preset (intero, lettura scrittura)
 % TMxxx.V - Valore xxx del timer (numero intero, scrittura lettura)
 % Mxx.R - Monostabile xx in esecuzione (booleano)
 % Mxx.V - Valore corrente monostabile xx (intero, solo lettura utente)
 % Mxx.P - preset monostabile xx (intero)
 % Cxx.D - Counter xx done (Boolean, solo lettura utente)
 % Cxx.E - Counter xx overflow vuoto (booleano, solo lettura utente)
 % Cxx.F - Contatore xx overflow completo (booleano, solo lettura utente)
 % Cxx.V - Contatore xx valore attuale (numero intero)
 % Cxx.P - Counter xx preset (intero)
 % Ixxx - Ingresso fisico xxx (booleano) (bit di input HAL)
 % Qxxx - Uscita fisica xxx (Boolean) (bit di uscita HAL)
 % Xxxx - Attività del passo xxx (linguaggio sequenziale)
 % Xxxx.V - Tempo di attività in secondi del passo xxx (linguaggio sequenziale)
 % Exx - Errori (booleano, leggere scrivere (verrà sovrascritto))
 Variabili indicizzate o vettoriali : si tratta di variabili indicizzate da un'altra variabile.
Alcuni potrebbero chiamare queste variabili vettoriali. Esempio: %W0 [%W4] => se
%W4 è uguale a 23 corrisponde a %W23

8. Programmazione GRAFCET
Questa è probabilmente la caratteristica meno utilizzata e più poco
avvertimento conosciuta di Classic Ladder. La programmazione sequenziale viene
utilizzata per assicurarsi che una serie di eventi ladder avvengano sempre
in un ordine prestabilito. I programmi sequenziali non funzionano da
soli. C'è sempre un programma ladder che controlla le variabili. Ecco le
regole base per i programmi sequenziali:
 Regola 1: Situazione iniziale - La situazione iniziale è caratterizzata dalle fasi iniziali
che sono per definizione nello stato attivo all'inizio dell'operazione. Ci deve essere
almeno un passo iniziale.
 Regola 2: R2, Cancellazione di una transizione: una transizione è abilitata o
disabilitata. Si dice che sia abilitato quando tutti i passi immediatamente precedenti
collegati al suo simbolo di transizione corrispondente sono attivi, altrimenti è
disabilitato. Una transizione non può essere cancellata a meno che non sia abilitata e
la sua condizione di transizione associata sia vera.
 Regola 3: R3, Evoluzione delle fasi attive - La cancellazione di una transizione porta
simultaneamente allo stato attivo dei passaggi immediatamente successivi e allo stato
inattivo dei passaggi immediatamente precedenti.
 Regola 4: R4, cancellazione simultanea delle transizioni - Tutte le transizioni
cancellate simultaneamente vengono cancellate simultaneamente.
 Regola 5: R5, Attivazione e disattivazione simultanea di una fase - Se durante
l'operazione, una fase viene simultaneamente attivata e disattivata, viene data priorità
all'attivazione.
Questa è la finestra dell'editor SEQUENTIAL A partire dall'immagine in alto a sinistra:
Freccia selettore, Gomma Passo ordinario, Passo iniziale (iniziale) Transizione, passaggio e
transizione Transizione Link-lato negativo, Transizione Link-Upside Pass-through Link-
Downside, Pass-through Link -Posta commento link a salto laterale [mostra programma
sequenziale]
 STEP ORDINARIO - ha un numero univoco per ognuno
 STEP INIZIALE - un programma sequenziale deve averne uno. Questo è dove il
programma inizierà.
 TRANSIZIONE : mostra la variabile che deve essere vera affinché il controllo passi al
passaggio successivo.
 PASSO E TRANSIZIONE - Combinati per comodità
 TRANSITION LINK-DOWNSIDE - divide il flusso logico in una delle due possibili
linee in base a quale dei prossimi passi è vero per primo (Think OR logic)
 TRANSITION LINK = UPSIDE : combina due (OR) linee logiche in una
 PASS-TRAMITE LINK-DOWNSIDE - divide il flusso logico in due righe che
ENTRAMBI devono essere true per continuare (Think AND logic)
 PASS-ATTRAVERSO LINK-UPSIDE : combina due linee logiche (logica AND)
concomitanti
 JUMP LINK : collega passaggi non sottostanti come collegare l'ultimo passaggio al
primo
 COMMENT BOX - utilizzato per aggiungere commenti
Per utilizzare i collegamenti, è necessario disporre di passaggi già inseriti. Seleziona il tipo di
collegamento, quindi seleziona i due passaggi o le transazioni una alla volta. Ci vuole pratica!
Con programmazione sequenziale: la variabile% Xxxx (ad esempio% X5) viene utilizzata per
verificare se un passaggio è attivo. La variabile% Xxxx.V (ad esempio% X5.V) viene utilizzata
per verificare quanto tempo è stato attivo il passaggio. Le variabili% X e% Xv sono utilizzate
nella logica LADDER. Le variabili assegnate alle transizioni (ad esempio% B) controllano se
la logica passerà al passaggio successivo. Dopo che un passaggio è diventato attivo, la
variabile di transizione che ne ha causato l'attivazione non ne ha più il controllo. L'ultimo
passaggio deve riportare JUMP LINK solo alla fase iniziale.

9. Modbus
Cose da considerare:
 Modbus è un programma per gli utenti in modo che possa avere problemi di latenza
su un computer molto carico.
 Modbus non è adatto per eventi in tempo reale difficili come il controllo della
posizione dei motori o per controllare l'arresto di emergenza.
 La GUI di Classic Ladder deve essere in esecuzione affinché Modbus sia in esecuzione.
 Modbus non è completamente finito quindi non esegue tutte le funzioni modbus.
Per far inizializzare MODBUS devi specificarlo durante il caricamento del programma dello
spazio utente di Classic Ladder.
Caricamento Modbus
loadusr -w classicladder --modmaster myprogram.clp
L'opzione -w fa in modo che HAL attenda fino alla chiusura di Classic Ladder prima di
chiudere la sessione in tempo reale. Classic Ladder carica anche uno slave Modbus TCP se si
aggiunge --modserver sulla riga di comando.
Funzioni Modbus
 1 - leggere bobine
 2 - leggi gli input
 3 - leggi i registri di attesa
 4 - leggere i registri di input
 5 - scrivere bobine singole
 6 - scrivere un registro singolo
 8 - test dell'eco
 15 - scrivere più bobine
 16 - scrivere registri multipli
Se non si specifica un - modmaster durante il caricamento del programma utente di Classic
Ladder, questa pagina non verrà visualizzata.

Figura 9. I / O di configurazione
Figura 10. Config Coms
 PORTA SERIALE - Per IP bianco. Per seriale la posizione / nome del driver seriale es.
/ dev / ttyS0 (o / dev / ttyUSB0 per un convertitore da USB a seriale).
 VELOCITÀ SERIALE - Dovrebbe essere impostato su velocità per cui lo slave è
impostato per - 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
sono supportati.
 PAUSA DOPO TRASMISSIONE - Metti in pausa (in millisecondi) dopo la
trasmissione e prima di ricevere risposta, alcuni dispositivi richiedono più tempo (ad
esempio convertitori da USB a seriale).
 PAUSA INTER-FRAME - Pausa (millisecondi) dopo aver ricevuto risposta dallo slave.
Questo imposta il ciclo di lavoro delle richieste (è una pausa per CIASCUNA richiesta).
 RICHIESTA LUNGHEZZA TIMEOUT - Lunghezza (millisecondi) di tempo prima che
decidiamo che lo slave non ha risposto.
 MODBUS ELEMENT OFFSET - utilizzato per bilanciare i numeri degli elementi di 1
(per le differenze di numerazione dei produttori).
 DEBUG LEVEL - Impostare questo su 0-3 (0 per interrompere la stampa delle
informazioni di debug oltre agli errori di mancata risposta).
 LEGGI COILS / INPUTS MAP TO - Seleziona quali variabili che leggeranno bobine /
ingressi verranno aggiornate. (B o Q).
 WRITE COILS MAP TO TO - Seleziona le variabili che scrivono bobine aggiornate.da
(B, Q, o I).
 LEGGI REGISTRI / HOLDING - Seleziona quali variabili che leggeranno i registri
verranno aggiornate. (W o QW).
 WRITE REGISTERS MAP TO - Seleziona le variabili da cui leggere i registri che
verranno aggiornati da. (W, QW o IW).
 SLAVE ADDRESS - Per seriale il numero ID di slave normalmente impostabile sul
dispositivo slave (in genere 1-256) Per IP l'indirizzo IP slave più facoltativamente il
numero di porta.
 ACCESSO TIPO - Seleziona il codice funzione MODBUS da inviare allo slave (ad es.
Quale tipo di richiesta).
 COILS / INPUT - Gli ingressi e le bobine (bit) vengono letti da / scritti su variabili I, B
o Q (selezione dell'utente).
 REGISTERS (WORDS) - Registers (Words / Numbers) mappano a variabili IW, W o
QW (selezione dell'utente).
 1 ° ELEMENTO MODBUS - L'indirizzo (o numero di registro) del primo elemento di
un gruppo. (ricordarsi di impostare correttamente MODBUS ELEMENT OFFSET).
 NUMERO DI ELEMENTI - Il numero di elementi in questo gruppo.
 LOGICA - Qui puoi invertire la logica.
 1st% I% Q IQ WQ MAPPED - Questo è il numero iniziale di% B,% I,% Q,% W,% IW
o% QW variabili mappate sul / dal gruppo di elementi modbus (a partire dal primo
modbus numero di elemento).
Nell'esempio sopra: numero di porta - per il mio computer / dev / ttyS0 era la mia porta
seriale.
La velocità seriale è impostata su 9600 baud.
L'indirizzo slave è impostato su 12 (sul mio VFD posso impostarlo da 1 a 31, il che significa
che posso parlare con un massimo di 31 VFD su un sistema).
La prima riga è impostata per 8 bit di input a partire al primo numero registro (registro 1).
Così registrare i numeri 1-8 sono mappato su variabili %B di classico Ladder a partire % B1 e
termina alle % B8.
La seconda linea è impostata per registrare 2 bit di uscita a partire dal nono numero (registro
9) così registrare numeri 9-10 vengono mappati sulla variabili %Q di Classic Ladder a partire
da % Q9 termina % Q10.
La terza riga è impostata per scrivere 2 registri (16 bit ciascuno) a partire da 0 numero
(registro 0) cosi registrare numeri 0-1 vengono mappati sulla variabili %W di classico Ladder
a partire da % W0 termina % W1 di registro.
È facile fare un errore "off-by-one" poiché a volte gli elementi modbus vengono referenziati a
partire da uno piuttosto che da 0 (in realtà dallo standard come dovrebbe essere!) È possibile
utilizzare il pulsante di opzione offset dell'elemento modbus per aiutare con questo.
I documenti per il tuo dispositivo slave modbus ti diranno come sono configurati i registri,
non esiste un modo standard.
I livelli SERIAL PORT, PORT SPEED, PAUSE e DEBUG sono modificabili per le modifiche
(quando si chiudono i valori della finestra di configurazione vengono applicati, anche se i
pulsanti Radio si applicano immediatamente).
Per utilizzare la funzione eco selezionare la funzione eco e aggiungere il numero slave che si
desidera testare. Non è necessario specificare alcuna variabile.
Il numero 257 verrà inviato al numero di slave specificato e lo slave dovrà inviarlo indietro.
per vedere il messaggio è necessario avere Classic Ladder in esecuzione su un terminale.

9.1. Impostazioni MODBUS


Seriale:
 Classic Ladder utilizza il protocollo RTU (non ASCII).
 8 bit di dati, nessuna parità viene utilizzata e 1 bit di stop è anche noto come 8-N-1.
 La velocità di trasmissione deve essere la stessa per slave e master. Classic Ladder
può avere solo una velocità di trasmissione in modo che tutti gli slave debbano essere
impostati alla stessa velocità.
 Pausa inter frame è il tempo di mettere in pausa dopo aver ricevuto una risposta.
 MODBUS_TIME_AFTER_TRANSMIT è la durata della pausa dopo l'invio di una
richiesta e prima di ricevere una risposta (ciò sembra essere di aiuto con i convertitori
USB che sono lenti).

9.2. Informazioni su MODBUS


 Classic Ladder può utilizzare ingressi / uscite distribuiti su moduli usando il
protocollo Modbus ("master": polling slave).
 Gli slave e il loro I / O possono essere configurati nella finestra di configurazione.
 Sono disponibili 2 modalità esclusive: ethernet usando Modbus / TCP e seriale usando
Modbus / RTU.
 Nessuna parità viene utilizzata.
 Se non è impostato alcun nome porta per seriale, verrà utilizzata la modalità TCP / IP
 L'indirizzo slave è l'indirizzo slave (Modbus / RTU) o l'indirizzo IP.
 L'indirizzo IP può essere seguito per il numero di porta da utilizzare (xx.xx.xx.xx:
pppp) altrimenti verrà utilizzata la porta 9502 per impostazione predefinita.
 Per i test sono stati utilizzati 2 prodotti: uno Modbus / TCP (Adam-6051,
http://www.advantech.com ) e uno seriale Modbus / RTU ( http://www.ipac.ws ).
 Vedi esempi: adam-6051 e modbus_rtu_serial.
 Link Web: http://www.modbus.org e questo interessante:
http://www.iatips.com/modbus.html
 MODBUS TCP SERVER INCLUSO
 Classic Ladder ha un server Modbus / TCP integrato. La porta predefinita è 9502. (lo
standard precedente 502 richiede che l'applicazione debba essere avviata con i
privilegi di root).
 Elenco delle funzioni Modbus supportate sono: 1, 2, 3, 4, 5, 6, 15 e 16.
 La tabella di corrispondenza di bit e parole di Modbus in realtà non è parametrica e
corrisponde direttamente alle variabili% B e% W.
Ulteriori informazioni sul protocollo modbus sono disponibili su Internet.
http://www.modbus.org/
9.3. Errori di comunicazione
Se si verifica un errore di comunicazione, verrà visualizzata una finestra di avviso (se la GUI
è in esecuzione) e %E0 sarà true. Modbus continuerà a provare a comunicare. L a%E0
potrebbe essere utilizzata per prendere una decisione in base all'errore. Un timer può essere
usato per fermare la macchina se scaduto, ecc.

9.4. Errori MODBUS


 Nei blocchi di confronto la funzione% W = ABS (% W1-% W2) è accettata ma non
viene calcolata correttamente. solo% W0 = ABS (% W1) è attualmente legale.
 Quando carica un programma ladder caricherà informazioni Modbus ma non dirà a
Classic Ladder di inizializzare Modbus. È necessario inizializzare Modbus quando si
carica la GUI per la prima volta aggiungendo --modmaster .
 Se il gestore delle sezioni viene posizionato nella parte superiore della visualizzazione
della sezione, viene fatto clic sul programma utente in modo anomalo attraverso la
barra di scorrimento e l'uscita.
 Quando usi --modmaster devi caricare il programma ladder allo stesso tempo,
altrimenti funzionerà solo TCP.
 leggere / scrivere più registri in Modbus ha errori di checksum.

10. Impostazione di Classic Ladder


In questa sezione verranno illustrati i passaggi necessari per aggiungere Classic Ladder a una
configurazione generata da Stepconf Wizard. Nella pagina Opzioni di configurazione
avanzate della procedura guidata Stepconf, selezionare "Includi PLC ladder classico".

Figura 11. Stepconf Classic Ladder


10.1. Aggiungi i moduli
Se hai utilizzato la procedura guidata Stepconf per aggiungere Classic Ladder, puoi saltare
questo passaggio.
Per aggiungere manualmente Classic Ladder devi prima aggiungere i moduli. Questo viene
fatto aggiungendo un paio di righe al file custom.hal.
Questa riga carica il modulo in tempo reale:
loadrt classicladder_rt
Questa linea aggiunge la funzione Classic Ladder al servo thread:
addf classicladder.0.refresh servo-thread

10.2. Aggiunta della logica ladder


Ora avvia la tua configurazione e seleziona "File / Ladder Editor" per aprire la GUI di Classic
Ladder. Dovresti vedere una finestra vuota di visualizzazione di sezioni e sezioni come
mostrato sopra. Nella finestra Visualizzazione sezione aprire l'Editor. Nella finestra Editor
seleziona Modifica. Ora viene visualizzata una finestra Proprietà e il display della sezione
mostra una griglia. La griglia è un gradino di scala. Il gradino può contenere rami. Un ramo
semplice ha un ingresso, una linea di connessione e un'uscita. Un ramo può avere fino a sei
rami orizzontali. Mentre è possibile avere più di un circuito in una corsa, i risultati non sono
prevedibili.

Figura 12. Sezione Display con griglia


Ora fai clic su NO Input nella finestra dell'Editor.
Figura 13. Finestra dell'editor
Ora clicca nella griglia in alto a sinistra per posizionare l'ingresso NO nella scala.

Figura 14. Sezione Display con input


Ripetere i passaggi precedenti per aggiungere un'uscita NO alla griglia in alto a destra e
utilizzare la connessione orizzontale per collegare i due. Dovrebbe apparire come il seguente.
In caso contrario, utilizzare la gomma per rimuovere sezioni indesiderate.
Figura 15. Sezione Display con ramo
Ora fai clic sul pulsante OK nella finestra dell'Editor. Ora il tuo display di sezione dovrebbe
assomigliare a questo.

Figura 16. Visualizzazione della sezione finita


Per salvare il nuovo file selezionare Salva come e dargli un nome. L'estensione .clp verrà
aggiunta automaticamente. Dovrebbe essere l'impostazione predefinita nella directory di
configurazione in esecuzione come luogo in cui salvarla.
Figura 17. Finestra di dialogo Salva come
Di nuovo, se hai usato la procedura guidata Stepconf per aggiungere Classic Ladder, puoi
saltare questo passaggio.
Per aggiungere manualmente una scala è necessario aggiungere una riga al file custom.hal
che caricherà il file ladder. Chiudi la tua sessione LinuxCNC e aggiungi questa linea al tuo file
custom.hal.
loadusr -w classicladder --nogui MyLadder.clp
Ora, se avvii la configurazione di LinuxCNC, anche il tuo programma ladder verrà eseguito.
Se selezioni "File / Ladder Editor", il programma che hai creato verrà visualizzato nella
finestra di visualizzazione della sezione.
Esempi di Classicladder
Sommario
1. Contatore di avvolgimento
2. Rifiuta impulsi extra
3. Arresto di emergenza esterno
4. Esempio di timer / funzionamento

1. Contatore ciclico
Per avere un contatore che si avvolge devi usare il pin preimpostato e il pin di reset. Quando
crei il contatore, imposta il preset sul numero che desideri raggiungere prima di eseguire il
wrapping attorno a 0. La logica è se il valore del contatore è sopra la preselezione, quindi
resettare il contatore e se il underflow è attivo, quindi impostare il valore del contatore sul
valore preimpostato. Come si può vedere nell'esempio quando il valore del contatore è
maggiore del contatore preimpostato, il reset del contatore viene attivato e il valore è ora 0.
L'uscita di underflow% Q2 imposterà il valore del contatore sul valore preimpostato durante
il conteggio all'indietro.

Figura 1. Contatore ciclico

2. Rifiuto impulsi extra


Questo esempio mostra come rifiutare gli impulsi extra da un input. Supponiamo che
l'impulso di ingresso %I0 abbia l'abitudine fastidiosa di dare un impulso in più che guasta la
nostra logica. Il TOF (Timer Off Delay) impedisce all'impulso in eccesso di raggiungere
l'uscita ripulita %Q0. Come funziona? Quando il timer riceve un input, l'uscita del timer è
attiva per la durata dell'impostazione del timer. Usando un contatto normalmente chiuso %
TM0.Q, l'uscita del temporizzatore blocca ogni ulteriore input verso la nostra uscita finché
non scade.
Figura 2. Reject Extra Pulse

3. Arresto di emergenza esterno


L'esempio dell'E-Stop esterno si trova nella cartella /config/classicladder/cl-estop. Usa un
pannello pyVCP per simulare i componenti esterni.
Per interfacciare un pulsante E-Stop esterno a LinuxCNC e far funzionare l'arresto di
emergenza esterno insieme all'E-Stop interno, è necessario un paio di collegamenti tramite
Classic Ladder.
Per prima cosa dobbiamo aprire il ciclo E-Stop nel file HAL principale e commentando
(aggiungendo il cancelletto come mostrato) o rimuovendo le seguenti linee.
# net estop-out <= iocontrol.0.user-enable-out
# net estop-out => iocontrol.0.emc-enable-in
Quindi aggiungiamo Classic Ladder al nostro file custom.hal aggiungendo queste due righe:
loadrt classicladder_rt
addf classicladder.0.refresh servo-thread
Quindi eseguiamo la nostra configurazione e costruiamo il ladder come mostrato qui.

Figura 3. Visualizzazione della sezione E-Stop


Dopo aver creato il ladder, seleziona Salva come e salva il ladder come estop.clp
Ora aggiungi la seguente riga al tuo file custom.hal.
# Carica la scala
loadusr classicladder --nogui estop.clp
Assegnazioni di I / O
 %I0 = Ingresso dal pulsante pyVCP E-Stop simulato (la casella di controllo)
 %I1 = Ingresso da E-Stop di LinuxCNC
 %I2 = Ingresso da E-Stop Reset Pulse di LinuxCNC
 %I3 = Ingresso dal pulsante di reset del pannello pyVCP
 %Q0 = Ouput a LinuxCNC per abilitare
 %Q1 = Uscita su pin di abilitazione scheda driver esterna (utilizzare un'uscita N/C se la
scheda ha un pin disabilitato)
Quindi aggiungiamo le seguenti righe al file custom_postgui.hal
# Esempio E-Stop utilizzando i pulsanti pyVCP per simulare componenti esterni

# Il tasto di controllo pyVCP simula un arresto di emergenza esterno


normalmente chiuso
net ext-estop classicladder.0.in-00 <= pyvcp.py-estop

# Richiedi E-Stop Enable da LinuxCNC


net estop-all-ok iocontrol.0.emc-enable-in <= classicladder.0.out-00

# Richiesta di abilitazione E-Stop da pyVCP o sorgente esterna


net ext-estop-reset classicladder.0.in-03 <= pyvcp.py-reset

# Questa riga resetta l'E-Stop da LinuxCNC


net emc-reset-estop iocontrol.0.user-request-enable => classicladder.0.in-02

# Questa riga consente a LinuxCNC di sbloccare l'arresto di emergenza in


Classic Ladder
net emc-estop iocontrol.0.user-enable-out => classicladder.0.in-01

# Questa linea accende l'indicatore verde quando esce da E-Stop


net estop-all-ok => pyvcp.py-es-status
Quindi aggiungiamo le seguenti righe al file panel.xml. Nota che devi aprirlo con l'editor di
testo e non con il visualizzatore HTML predefinito.
<pyvcp>
<vbox>
<label> <text> "E-Stop Demo " </text> </label>
<led>
<halpin> "py-es-status" </halpin>
<dimensione> 50 </size >
<on_color> "green" </on_color>
<off_color> "red" </off_color>
</led>
<checkbutton>
<halpin> "py-estop" </halpin>
<text> "E-Stop" </text>
</checkbutton>
</vbox>
<button>
<halpin> "py-reset"</halpin>
<text> "Reset" </text>
</button>
</pyvcp>
Ora avvia la tua configurazione e dovrebbe apparire così.

Figura 4. Arresto di emergenza AXIS


Notare che in questo esempio come nella vita reale è necessario azzerare l'arresto di
emergenza remoto (simulato dalla casella di controllo) prima che l'arresto di emergenza AXIS
o il reset esterno ti mettano in modalità OFF. Se è stato premuto il pulsante E-stop nella
schermata AXIS, è necessario premerlo nuovamente per cancellarlo. Non è possibile
ripristinare da esterno dopo aver eseguito un arresto di emergenza in AXIS.

4. Esempio di timer / funzionamento


In questo esempio stiamo usando il blocco Operate per assegnare un valore al preset del
timer in considerando se un input è on o off.
Figura 5. Esempio di timer / funzionamento
In questo caso, %I0 è true, quindi il valore predefinito del timer è 10. Se %I0 era falso, il
preset del timer sarebbe 5.

Potrebbero piacerti anche