INDICE
Terza
quarta
QUINTA
TERZA
•
•
•
•
•
•
•
•
•
•
•
•
modelli e sistemi
proprietà dei componenti
sistemi lineari
componenti elettrici
circuiti rc e rl
diodi e bjt
arresto e marcia di un motore
circuiti di interfaccia
laboratorio: tutto sui rele
pilotare un relè con arduino
555
laboratorio 555
• il pc: input e output, il c e la programmazione
• gli algoritmi
• la programmazione
MODELLI
DEFINIZIONE: un modello è una rappresentazione approssimata del sistema reale.
Un modello serve per trasmettere informazioni, per definire e risolvere problemi
NB: il grado di approssimazione dipende dal fine per cui il modello è costruito.
CLASSIFICAZIONE:
•Modello FISICO: consiste in una riproduzione in scala del sistema
•Modello SIMBOLICO: consiste nella rappresentazione del sistema mediante simboli
•GRAFICO: Es: schema a blocchi interconnessi
•MATEMATICO: stabilisce una relazione quantitativa tra le variabili del sistema
•Formula (Espressione analitica)
•Tabella
•Caratteristica: legame grafico tra due variabili
Modelli
Nel dominio del tempo il modello matematico di un sistema continuo è spesso fornito mediante
la rappresentazione ingresso/uscita, cioè dalle sue equazioni differenziali.
Per un sistema del 1° ordine:
E’ comodo studiare la risposta nel tempo ricorrendo anche alla
rappresentazione ingresso/uscita
nel dominio di Laplace, cioè
alla schematizzazione del sistema con blocchi e relative funzioni
di trasferimento:
SISTEMI
DEFINIZIONI
SISTEMA: insieme di elementi, parti, che interagiscono coordinati per svolgere una deteminata funzione.
COMPONENTI: parti di cui il sistema è costituito.
PARAMETRI: grandezze che esprimono delle proprietà specifiche di un sistema o di un componente.
VARIABILI: grandezze fisiche misurabili presenti nel sistema,
•di INGRESSO: indicano la quantità di energia, materia, informazione fornita al sistema
•di STATO: indicano la quantità di energia, materia, informazione accumulata nel sistema
•di USCITA: indicano la quantità di energia, materia, informazione ceduta dal sistema
STATO di un sistema: è definito dalla quantità e dalla distribuzione di energia, materia, informazione
presenti nel sistema (lo si deduce dal valore delle variabili di stato).
NB: non tutti i sistemi sono caratterizzato di uno stato.
SISTEMI LINEARI
Si hanno più modi per definire la linearità di un sistema:
- uscita proporzionale all’ingresso:
- rapporto tra l’uscita e l’ingresso (esauriti i transitori) è costante:
- caratteristica ingresso – uscita è una retta passante per l’origine:
Si hanno diversi tipi di non linearità nella relazione ingresso – uscita:
- Il valore dell’uscita dipende non solo da quello dell’ingresso, ma anche dalla tendenza di
quest’ultimo ad aumentare o diminuire.
- Sono presenti zone in cui nonostante rilevanti variazioni dell’ingresso, l’uscita resta
costante.
’- presente una zona di insensibilità dell’uscita alle variazioni dell’ingresso, superata tale
zona l’uscita segue l’ingresso, ma a questo punto con un certo ritardo.
L’effetto fondamentale della presenza di non linearità nel sistema consiste nella distorsione
armonica, cioè nella comparsa di armoniche non presenti nel segnale d’ingresso.
VARIABILI
Le variabili si possono classificare secondo criteri diversi.
Le variabili che descrivono le cause dei fenomeni sono dette di tipo POTENZIALE
Le variabili che descrivono l’effetto finale sono dette di tipo QUANTITA’.
Le variabili che descrivono il passaggio dalla causa all’effetto sono dette di tipo FLUSSO.
Differenza di
potenziale
Flusso
Quantità
Tensione
Corrente
Carica
Forza
Velocità
Spostamento
Termico
Differenza di
temperatura
Flusso termico
Calore
Idraulico
Differenza di
pressione
portata
Volume
SISTEMA
Elettrico
Meccanico
PROPRIETA’ ELEMENTARI DEI COMPONENTI
SISTEMI ELETTRICI
Il comportamento di un componente, o sistema, è normalmente descritto da più parametri.
I parametri elementari più importanti sono:
RESISTENZA: cioè l’attitudine del componente, sottoposto a una differenza di potenziale, di opporsi
alla formazione della variabile flusso.
In termini matematici:
CAPACITA’: cioè l’attitudine di un componente ad accumulare la quantità.
In termini matematici:
INDUTTANZA (o INERZIA): cioè l’attitudine di un componente di opporsi alle variazioni del
flusso nel tempo.
In termini matematici:
SISTEMI ELETTRICI
SISTEMI MECCANICI
SISTEMI LINEARI
Si hanno più modi per definire la linearità di un sistema:
• uscita proporzionale all’ingresso: y  k  x
• il rapporto tra l’uscita e l’ingresso (esauriti i transitori) è costante:
y
k/x
• la caratteristica ingresso – uscita è una retta passante per l’origine:
Una retta passante per l’origine ha equazione:
y  kx
Una retta non passante per l’origine ha equazione :y  k  x  q
il rapporto: y = k/x
non è costante.
y
Costante risulta invece il rapporto: x  k
In questo caso il sistema è LINEARE ALLE VARIAZIONI
Si hanno diversi tipi di non linearità nella relazione ingresso – uscita:
Il valore dell’uscita dipende non solo da quello
dell’ingresso, ma anche dalla tendenza di quest’ultimo ad
aumentare o diminuire.
Sono presenti zone in cui nonostante rilevanti variazioni
dell’ingresso, l’uscita resta costante.
E’ presente una zona di insensibilità dell’uscita
alle
variazioni dell’ingresso, superata tale zona l’uscita segue
l’ingresso, ma a questo punto con un certo ritardo.
L’effetto fondamentale della presenza di non linearità nel
sistema consiste nella distorsione armonica,
cioè nella comparsa di armoniche non presenti nel segnale
ingresso.
VARIABILI
Le variabili si possono classificare secondo criteri
diversi. Un modo è il seguente.
I fenomeni hanno delle cause.
Le variabili che descrivono queste cause sono dette di
tipo POTENZIALE e la causa è data dalla differenza di
potenziale.
Le variabili che descrivono l’effetto finale sono dette di
tipo QUANTITA’.
Le variabili che descrivono il passaggio dalla causa
all’effetto sono dette di tipo FLUSSO.
COMPONENTI E SISTEMI ELETTRICI
Differenza di potenziale V : Tensione elettrica
Flusso I :
Corrente elettrica
Quantità Q:
Carica elettrica
DEFINIZIONE: componente la cui proprietà principale è quella di opporsi alla formazione della corrente
elettrica, quando ai suoi terminali è applicata una tensione elettrica.
Il suo parametro principale è quindi la resistenza:
La resistenza si misura in Ohm:
Un resistore presenta una resistenza di 1  quando, sottoposto alla tensione di 1 V, permette lo scorrimento di
una corrente di 1 A
POTENZA DISSIPATA
Nei resistori non si accumula energia. Al passaggio della corrente, al loro interno avviene una
trasformazione energetica, in cui parte della potenza elettrica transitante è convertita in potenza
termica: il conduttore si scalda.
Il fenomeno fu studiato fin dalle origini dei circuiti elettrici, e nel 1837 J. P. JOULE lo quantificò con
la seguente formula: p(t) = R * i(t)2
riscaldamento di un conduttore per effetto del passaggio della corrente elettrica è noto come effetto
Joule.
il calore non è un’essenza della materia, bensì una manifestazione del lavoro meccanico.
vale la relazione: 1 cal = 4.187 J,
termico del lavoro
equivalente meccanico del calore 1 J = 0.239 cal, equivalente
L’energia è legata alla potenza secondo la seguente relazione:
Energia = Potenza x Tempo [ J ] = [ W ] *[ s ]
DERATING DELLA POTENZA
La potenza nominale di un resistore è riferita a una data temperatura ambiente. Se
questa è maggiore, il resistore
ha una maggiore difficoltà di raffreddamento, per cui occorre diminuire l’effetto Joule che
in esso ha luogo.
Ciò comporta una riduzione della corrente che si può far fluire nel resistore.
Per consentire il calcolo i costruttori forniscono un grafico di declassamento della
potenza del resistore in funzione della temperatura ambiente:
Esempio:
Resistore da 330 ohm, e 0.5 W a 70 °C
Se ne deduce una IMAX:
Tuttavia il resistore è inserito in un circuito la cui
temperatura ambiente raggiunge i 105 °C. Dal grafico del
costruttore si deduce che l’effetto Joule sopportabile scende al 38%
del valore nominale: 0.5·0.38 = 0.19 W.
La corrente massima risulta allora:
DEFINIZIONE: componente in grado di accumulare carica elettrica.
Il suo parametro principale è quindi la capacità, definita dalla legge del condensatore:
La capacità rappresenta quindi la carica
elettrica accumulata per un volt di tensione.
Si misura in Farad:
La corrente elettrica che carica e scarica un condensatore è desumibile dalla legge del
condensatore:
• Osservazioni:
• i(t) tanto maggiore quanto più velocemente varia v(t)
• pericoloso collegare il condensatore direttamente a un generatore di tensione (variazione
istantanea della vc(t))
Accumulando carica elettrica, il condensatore accumula energia elettrostatica:
NB: sia la carica che la tensione sono variabili di stato.
CARICA DEL CONDENSATORE
Se un condensatore viene collegato con una
batteria
attraverso fili ideali con resistenza nulla, il condensatore si
carica immediatamente, cioè in un tempo zero. Quando però nel
circuito è presente una resistenza la carica del condensatore viene
rallentata
Con il condensatore scarico e il deviatore
in posizione B, nel circuito non circola corrente e le tensioni su R e
su C sono nulle
Supponiamo ora di chiudere il
deviatore in A.
A questo punto il condensatore C è collegato alla batteria
E attraverso la resistenza R e nel circuito passa
corrente fino a quando il condensatore si carica ad una tensione pari a E
Immediatamente dopo la chiusura del deviatore
la tensione sul
condensatore è ancora nulla in quanto legata alla carica accumulata
sulle armature
Applicando la legge di K. alla maglia
E = VR + VC
- VC(t) =
E(1 + e-t/RC)
Nel momento della chiusura del tasto VC è zero, mentre VR ha un valore non nullo.
Siccome R è sottoposto a tensione, nel circuito passa, all'istante iniziale, una corrente I che può essere
calcolata con la legge di Ohm:
I = VR/R che carica il condensatore provocando una diminuzione della tensione sulla resistenza quando
C
è
completamente carico, la tensione VC raggiunge la tensione di batteria E, la tensione VR arriva a zero e la corrente si annulla
Un valore importante del circuito RC è la costante di tempo indicata con la
lettera greca tau (τ). La costante di tempo del circuito si calcola facendo il
prodotto della resistenza per la capacità:
τ = R.C
Più piccolo è il valore della τ più in fretta (in meno tempo) si carica il condensatore. Osserviamo subito che
il tempo di carica cresce all'aumentare di C e di R
Si dimostra che dopo un tempo pari a una costante di tempo la tensione sul
condensatore ha superato il 63% del proprio valore finale. Dopo un tempo circa
uguale a 5τ (cinque volte la costante di tempo) il condensatore si è caricato a più del
99% del valore finale.
SCARICA DEL CONDENSATORE
VC(t) = K e-t/RC = E e-t/RC
Corrente I, tensione VC
e tensione VR
durante la scarica hanno
tutte lo stesso andamento,
τ = R.C
ESERCIZIO
a) Determinare la tensione ai capi di un condensatore di 4 mF quando è caricato con 5 mC.
b) Trovare la carica accumulata su un condensatore di capacità pari a 50 pF quando si applica una tensione di 2KV.
a) C = 4 mF = 4*10-6 F
Q = 5 mC = 5*10-3 C
V = Q/C = (5*10-3)/(4*10-6) = (5*103)/4 = 1250 V = 1.25 KV
b) C = 50 pF = 50*10-12 F
V = 2KV = 2000 V
Q =C*V = (50*10-12 )* 2*103 = 10*10-8 = 0.1 mC
ESERCIZIO 1)
Si calcoli la costante di tempo di un circuito RC in cui C=100 mF e R = 220 K ed il tempo che esso impiega a caricarsi
fino al 50% della differenza di potenziale massima (f) fornita dalla batteria.
= RC = (200*103)*(100*10-6) s = 22 s
Posto Q(t) = f*C*(1-e-t/RC) pari al 50% del suo valore massimo:
f*C*(1-e-t/RC) = 0.5*f*C  e-t/RC = 0.5
t = -RC ln(0.5) = -22*(-0.693) s = 15.2 s
Per la proprietà dei logaritmi:
e-A/B = C  ln(e-A/B) = ln C  -A/B = ln C  A = -B *(ln C)
ESERCIZIO 2)
Un circuito consiste di un resistore collegato in serie con un condensatore di 0.5 mF ed ha una costante di tempo di
12 ms. Determinare il valore del resistore e la tensione ai capi del condensatore 7 ms dopo averlo collegato ad una
batteria di 10V.
Ricaviamo R dalla costante di tempo:R = /C = (12*10-3)/(0.5*10-6) = 24 k
sappiamo che durante il processo di carica la tensione varia come V(t)=f*(1-e-t/).
Occupiamoci dapprima della parte esponenziale:
Quindi:
V= 10*(1-e-0.583) = 10*(1-0.558) = 4.42 V
-t/ = -(7*10-3)/(12*10-3) = -0.583
Studiare il comportamento di un sistema equivale a esaminare
come varia il suo stato in funzione degli ingressi, cioè come
variano le sue variabili di stato.
Il modello matematico deve quindi legare le variabili di stato
agli ingressi.
Il punto di partenza sono le leggi fisiche.
circuito è formato da due componenti, uno dei quali in grado di
accumulare energia: il condensatore. Come variabile di stato si
assume normalmente la tensione vC(t), e il circuito si considera
alimentato mediante la tensione e(t).
La legge fisica che lega la vC(t) alla e(t) è la legge di Kirchhoff alla maglia:
Le variabili presenti nel modello devono rappresentare ingressi e variabili di stato (o uscite). Nell’equazione di Kirchhoff
occorre quindi scrivere i(t) in funzione di e(t) e/o vC(t):
Dalla legge del condensatore:
Sostituendo, e dopo pochi passaggi:
Equazione differenziale
Osservazioni:
• l’incognita, cioè vC(t), è una funzione; la soluzione quindi non è un numero, bensì una formula
• l’incognita compare con le sue variazioni nel tempo (per via della presenza
dell’accumulatore di energia), e per questo l’equazione è detta differenziale
• l’esistenza di un solo serbatoio di energia fa si che vi sia una sola variabile di stato, vC(t), e
per questo il circuito è
detto del 1° ordine
• l’incognita compare sempre con esponente 1, si tratta quindi di una equazione lineare (da cui:
circuito lineare)
• i parametri R e C sono costanti nel tempo, per cui i, circuito è stazionario
• tutti i termini rappresentano una tensione, per cui il prodotto RC deve avere le dimensioni di
un tempo; è chiamato costante di tempo.
SOLUZIONE NUMERICA
La soluzione numerica consiste nella trasformazione dell’intervallo infinitamente piccolo dt in un intervallo
finito t (passo di integrazione):
Osservazione: l’errore di calcolo è tanto più piccolo quanto minore è il passo di integrazione.
ESEMPIO:
R = 40 ohm , C = 50 mF, e(t) = 12 V.
Per la scelta del passo di integrazione  t si segue il seguente criterio: una frazione della
costante di tempo.
Soluzione:
Δt = (1/5) 
vc (V)
i (A)
12
0.00
0.300
0.4
12
2.40
0.240
0.4
0.8
12
4.32
0.4
1.2
12
0.4
1.6
0.4
t
e(t)
0.0
0.4
Δt = (1/10) 
t
e(t)
vc(t)
i (A)
0.0
12
0.00
0.300
0.2
0.2
12
1.20
0.270
0.192
0.2
0.4
12
2.28
0.243
5.86
0.154
0.2
0.6
12
3.25
0.219
12
7.08
0.123
0.2
0.8
12
4.13
0.197
2.0
12
8.07
0.0983
0.2
1.0
12
4.91
0.177
0.4
2.4
12
8.85
0.0786
0.2
1.2
12
5.62
0.159
0.4
2.8
12
9.48
0.0629
0.2
1.4
12
6.26
0.143
0.4
3.2
12
9.99
0.0503
0.2
1.6
12
6.83
0.129
0.4
3.6
12
10.4
0.0403
0.2
1.8
12
7.35
0.116
0.4
4.0
12
10.7
0.0322
0.2
2.0
12
7.82
0.105
SOLUZIONE ANALITICA
Nel caso di una tensione di alimentazione e(t) = E = costante, l’equazione differenziale presenta la
seguente soluzione:
NB: la corrente ha un andamento opposto a quello della vC(t):
Osservazione:
i(t) ha un picco massimo quando vC(t) è minima;
il picco di i(t) viene prima quello di vC(t).
NB: i(t) può essere calcolata (conoscendo vC(t) )
anche facendo riferimento alla legge di Ohm.
Negli istanti di discontinuità della e(t) occorre
distinguere tra un momento immediatamente
prima
- t0 e un momento immediatamente dopo
t0+:
ESERCIZIO: proprietà filtrante rispetto alle brusche variazioni di tensione
1808: il prof (ad Halle: chimico, fisico e matematico) Johann
Schweigger nota che inprossimità di un conduttore percorso da
corrente l’ago magnetico viene deviato.
1820: Schweigger costruisce una bobina mobile con indicatore per
rilevare il
passaggio di corrente. Seebek lo chiamò
“moltiplicatore”.
1825: William Sturgeon costruisce il primo elettromagnete
(conduttore avvolto su ferro, non isolato).
1827: Joseph Henry potenzia l’elettromagnete con più spire isolate.
1830: Legge dell’induzione elettromagnetica
CIRCUITO RL SERIE: CHIUSURA
Quando l’interruttore S chiude o (apre) il circuito: l’L
impedisce
alla
corrente
di
aumentare
(o diminuire)
istantaneamente, perché la variazione di i genera una
f.e.m. indotta che si oppone alla variazione della corrente
stessa.
1) Consideriamo il caso in cui il circuito venga chiuso Ossia:
t= 0 i = 0
i

R
(1 e
 Rt
L
)
L  L / R
Durante la fase transitoria si ha un altra
corrente, detta extracorrente di chiusura
CIRCUITO RL SERIE: APERTURA
Dove i0=R La resistenza passa da R ad R’(>> R) costante durante il transitorio
 t
 R t


i  e L  e 
L
R
R
 ' L  L / R '  
iL 
L
 i(t)
R
extracorrente di apertura, diversa da zero x un tempo molto bretve
ESEMPIO:
R = 1.5 ,
L = 3 H, e(t) = 20 V,
i(0) = 0 A.
Per la scelta del passo di integrazione t si segue il seguente criterio: una frazione della costante di tempo.
Soluzione:
DIODO RADDRIZZATORE
• Il diodo raddrizzatore a giunzione (o semplicemente diodo) è un
componente elettronico a due terminali (bipolo), la cui funzione è quella di
permettere il flusso di corrente elettrica in un verso e di bloccarla
nell'altro. Il simbolo circuitale del diodo esprime chiaramente questa
funzione: il triangolo indica la freccia di direzione in cui il flusso di
corrente è possibile. I due terminali del diodo vengono detti anodo
(A) e catodo (K).
• La figura qui sotto mette a confronto il simbolo circuitale del diodo con
l'aspetto tipico di un diodo reale. Si noti che il catodo viene di solito
marcato sul componente per mezzo di una fascia di differente colore:
Si osservi attentamente quanto segue:
v2 = 0 V
v1 = E = 9 V i2 = 0 A
i1 = E/R1 = 9/300 = 30 mA i3 = i1 = 30 mA


i1=i2= E / (R1+R2) = 9/900 = 10 mA
v1 = i1 * R1 = 10 mA * 300 Ω = 3 V
v2 = vd = i2 * R2 = 600 Ω * 10 mA = 6 V
in polarizzazione diretta è nota la tensione ai
capi del diodo (vale zero), mentre la corrente nel
diodo dipende dal circuito in cui il diodo è inserito;
in polarizzazione inversa è nota la corrente nel
diodo (vale zero), mentre la tensione ai capi del
diodo dipende dal circuito in cui il diodo è inserito.
TENSIONE DI SOGLIA
Affinche il diodo conduca
soglia.
occorre che la tensione applicata superi un valore non nullo, detto tensione di
Il valore della tensione di soglia è diverso a
seconda
del
materiale
a semiconduttore con cui è
stato realizzato il diodo. Per i diodi al silicio il valore è tipicamente compreso fra 0,6 e 0,8 V. I diodi al
germanio hanno invece una tensione di soglia più bassa, intorno agli 0,2-0,4 V.
Quando E supera la tensione di soglia, il diodo entra in zona di polarizzazione diretta e comincia a
condurre corrente, in questa zona la tensione rimane pressoché costante e sempre uguale alla tensione di
soglia Vs
Possiamo sostituire il diodo con un generatore di tensione equivalente di valore pari alla tensione di
soglia sul diodo. Supponendo Vs = 0,7 V per il nostro diodo, abbiamo:
V2 = Vs = 0,7 V
i2 = V2/R2 = 0,7 V/ 600 Ω = 1,16 mA
i1 = v1/R1 = 8,3/300 = 27,6 mA
v1 = E - V2 = 9 - 0,7 = 8,3 V
MISURA DELLA CARATTERISTICA INGRESSO- USCITA DEL
(TRANSCARATTERISTICA)
resistenza di protezione Rp fra
il
diodo e il generatore.
Tale resistenza ha il compito di
assorbire la tensione in eccesso,
limitando
l’assorbimento
di
corrente del diodo
DIODO
In corrispondenza di una certa V la corrente
inversa nel diodo aumenta molto rapidamente;
tale valore
limite viene
detto tensione di
breakdown o di rottura, in quanto
porta
generalmente
alla distruzione del componente
(intorno a – 100 V)
Si evidenzia il comportamento non lineare del diodo
TRANSISTOR BJT NPN E PNP
Iltransistor
a giunzione bipolare è un componente a tre morsetti denominati con base
(B),
collettore (C) ed emettitore (E) . Ci sono due tipi di BJT: il BJT npn e il BJT pnp. Essi differiscono per il
simbolo elettrico e per il versi dei parametri elettrici
Per trovare l’mettitore conviene fare riferimento ai fogli tecnici del
componente
(datasheet)
oppure usare un multimetro. La figura
seguente mostra
l'uso
di
un
multimetro
in configurazione
ohm-metro
per determinare qual è il collettore e qual è l'emettitore
di un BJT npn:
La
misura
si
basa
sul principio che ha la resistenza misurata fra il collettore e la base e fra
l’emettitore e base in un NPN e molto
elevata; Viceversa la resitenza misurata con i terminali al contrario e
molto bassa
LE TRE ZONE DI FUNZIONAMENTO DI UN BJT
Il BJT può lavorare in tre zone
di funzionamento
principali (regions of operation), dette
rispettivamente:
 zona di interdizione (cutoff region)
 zona attiva
(o
lineare
o amplificazione, forward active region)
 zona di saturazione (saturation region)
Nel
seguito
esamineremo dettagliatamente il comportamento del BJT nelle tre zone e i metodi
di calcolo da usare per determinare in quale zona sta funzionando il BJT.
In zona di interdizione non BJT non conduce correnti
n zona attiva il BJT si comporta come un amplificatore di corrente: la corrente di collettore Ic è legata
alla corrente di base Ib e aumenta al crescere di quest'ultima;
In zona di saturazione i lBJT si comporta come
un
conduttore
quasi ideale (un filo) collegato fra collettore ed emettitore: in queste condizioni la tensione Vce è molto
bassa (idealmente zero) e non vale più la relazione di proporzionalità fra Ib e Ic.
ESEMPIO: Controllo marcia/arresto di un motore
.
Quando la bobina:
• richiede una alimentazione > 5 V, oppure
• assorbe una corrente > 40 mA
È necessario interporre tra Arduino e bobina uno stadio di interfaccia.
Descrizione:
Transistor BJT npn (2N1711)
BJT ON
bobina eccitata,
motore in marcia
Per accensione BJT necessaria : (VBE )SAT ∼ 0.9 - 1.3 V
Tensione di controllo fornita da Arduino: 5 V, quindi
IB ∼ (5 – 0.9) / 1k = 4.1 mA < 40 mA
NB: IBOBINA < (IBJT)MAX = 500 mAdc per 2N1711)
(
BJT OFF
bobina diseccitata, motore fermo
(NB :
VBOBINA <(VBJT_CE_OFF)MAX
= 80 Vdc 2N1711)
Diodo (1N4007)
Ha funzione protettiva (per BJT e bobina) contro la sovratensione provocata dalla bobina
al momento dello spegnimento del BJT (e = - dV/dt)
Bobina
Rappresenta l’interfaccia di potenza. Occorre prestare attenzione alla corrente assorbita
dal motore, che deve essere sopportabile dal contatto di potenza del relé.
Motore
Può essere sia DC che AC.
circuiti di interfaccia
Interfacciamento con Motori
Il transistor NPN viene utilizzato come interruttore ON-OFF per fornire la corrente
desiderata alla
bobina del relè. È necessario il diodo di ricircolo
in quanto la corrente
che attraversa la
bobina induttiva quando viene diseccitata non viene istantaneamente ridotta a zero. Quando l'ingresso
alla base è impostato a livello ALTO, il transistor è acceso "ON". La corrente passa attraverso la bobina
del relè e suoi contatti e si ha il pilotaggio del motore.
Quando l'ingresso alla base transistori è BASSO, il transistor è spento "OFF" e il motore si arresta con i
contatti del relè aperti. Qualsiasi forza contro-elettromotrice generata disattivando la bobina scorre
attraverso il diodo di ricircolo e lentamente decade a zero prevenendo danni al transistore. Inoltre, il
MOSFET essendo isolatonon viene influenzato da alcun rumore o picchi di tensione generati dal
funzionamento del motore.
circuiti di interfaccia
INTERFACCIAMENTO IN INGRESSO
l tipo più semplice e più comune di interfacciamento di imput
è l'interruttore a
pulsante in cui
l'operatore può cambiare lo stato di un ingresso semplicemente azionando un interruttore, premendo
un pulsante o muovendo un magnete sul sensore reed.
interfacciamento con
un singolo interruttore
Un resistore di pull-up è necessario per tenere il livello
di tensione di uscita al valore desiderato (in questo
esempio, + 5v) quando l'interruttore è aperto e ad
evitare il
corto circuito dell'alimentazione quando
è chiuso.
La dimensione del resistore di pull-up dipende dalla
corrente del circuito quando l'interruttore è aperto
Se assumiamo una porta logica TTL digitale
che richiede in input
60 micro-amp (60uA),
questa provoca una caduta di tensione attraverso il resistore di: 60uA x 10k = 0,6 V , producendo un
ingresso di tensione "livello alto« di 5,0-0,6 = 4.4V , che è ben entro le specifiche di ingresso di una
porta TTL digitale standard.
Invertendo il resistore con l'interruttore si ha la configurazione di pull-down
Diversamente dal resistore di pull-up che viene utilizzato per limitare la corrente, lo scopo principale di un
resistore di pull-down è di mantenere il terminale di uscita, V OUT a 0V . in questo caso si può utilizzare
una resistenza molto più piccola con l'inconveniente che a quando l'interruttore è chiuso si può avere un
elevata dissipazione di potenza nella resistenza
Sensori / traduttori
interfacciamento con DIP switch
Poiché i contatti degli interruttori meccanici sono progettati per aprire e chiudere rapidamente si
hanno transitori di chiusura
che possono produrre una
serie di impulsi o picchi di tensione
prima della chiusura definitiva dell'interruttore
Ci sono diversi modi che consentono di risolvere il rimbalzo dell'interruttore
1) Carica e scarica con un condensatore
antirimbalzo con porte NAND
con porte NOR
interfacciamento ottico
circuiti di interfaccia
Per isolare elettricamente un circuito da un altro si puo ricorrere agli isolatori ottici che forniscono
un elevato grado di isolamento elettrico tra i terminali di ingresso e di uscita,
che richiedono una
minima di corrente di ingresso (in genere solo 5mA) e che possono essere gestiti da una qualsiasi
porta logica un isolatore ottico è costituito da un LED che produce luce infrarossa e da un
dispositivo fotosensibile a semiconduttore che viene utilizzato per rilevare il fascio infrarossa
emessa.
Poiché l'ingresso è un LED una resistenza serie, R S è necessaria per
limitare la corrente del LED
Gli isolatori opto-triac consentono il comando di carichi fino a 400 v
con un assorbimento di corrente di 100 mA
Questo tipo di configurazione
a
optoisolatore
costituisce la base di un'applicazione del relè a stato
solido che può essere usato per controllare qualsiasi
rete AC direttamente dall'interfaccia di uscita di un
mico-controllore, PIC o circuito digitale, rotella del
mouse, ecc.
LABORATORIO: TUTTO SUI RELE
RELE’ è un dispositivo elettromeccanico in grado di azionare dei contatti
elettrici di potenza (cioè, di chiudere o aprireun circuito mediante lo
spostamento di uno o più contatti elettrici)
Relè elettromeccanico
VEDIAMO COME È FATTO UN RELÈ
IL FUNZIONAMENTO
E’ costituito da una bobina ad elevato n° di spire (avvolte su materiale
ferromagnetico) che, se
percorsa da corrente provoca l’attrazione di un
meccanismo (ancora) che determina la chiusura o l’apertura dei contatti.
TIPOLOGIE COSTRUTTIVE
• I relè si dividono in due blocchi fondamentali:
– Lato comando ( o lato eccitazione) costituito dalla:
• Bobina di eccitazione;
• Nucleo magnetico;
• Ancora mobile. (di forma piatta, a cerniera,
girevole e oscillante)
– Lato potenza ( o lato contatti) costituita dai
contatti elettrici di potenza.
LATO COMANDO
•Bobina
di
eccitazione:
realizzata
con filo di rame
smaltato avvolto su un supporto
isolante;
•Nucleo magnetico: di forma
cilindrica o piatta, realizzato in
ferro
dolce
a
struttura
massiccia per DC e laminata
per AC;
•Ancora mobile: realizzata in
ferro dolce o acciaio dolce;
LATO CONTATTI
•Contati: realizzati con argento e oro per basse potenze; leghe di
argento e argento-ossido di cadmio per potenze notevoli
•Molle portacontatti: realizzati in lega di rame-zinco-nichel devono
possedere una elevata elasticità da rimanere invariata anche dopo un
lungo periodo di funzionamento.
PRINCIPIO DI FUNZIONAMENTO
CON ACCENSIONE DA DUE O PIÙ PUNTI
TIPI DI RELÈ
•
Neutro: se il suo funzionamento NON DIPENDE dal verso della corrente nella bobina;
•
Polarizzato: se il suo funzionamento DIPENDE dal verso della corrente nella bobina;
•
Monostabile: se la posizione dei contatti si mantiene
SOLO per la durata dell’eccitazione
della bobina;
•
Bistabile: se la posizione dei contatti si mantiene ANCHE dopo l’eccitazione della bobina ed
occorre una nuova eccitazione per far tornare i contatti nella posizione di partenza.
TIPI DI RELÈ
RELÈ: PARAMETRI CARATTERISTICI
•
Tensione di eccitazione: tensione nominale necessaria per l’eccitazione della bobina del relè;
•
Corrente di eccitazione: corrente assorbita dalla bobina del relè durante la sua eccitazione;
•
Tipo di eccitazione: AC (alternate current);DC (direct current)
•
Durata elettrica: massimo numero di manovre con carico elettrico inserito;
•
Durata meccanica: massimo numero di manovre senza carico elettrico inserito;
• Frequenza di commutazione: numero massimo di commutazioni al secondo
CARATTERISTICHE DEI RELÈ
RELÈ: PARAMETRI CARATTERISTICI
•
Tensione di contatto: massima tensione nominale fra i contatti quando sono aperti;
•
Corrente di contatto: massima corrente che può circolare fra
•
Resistenza della bobina: rapporto tra tensione di eccitazione e la corrente;
i contatti quando sono chiusi;
I contatti possono assumere 3 posizioni di base a seconda del tipo di applicazione cui
sono destinati:
• NC (Normally Closed): i contatti sono chiusi a relè diseccitato; essi si aprono in seguito
all’eccitazione della bobina;
• NO (Normally Open): i contatti sono aperti a relè diseccitato; essi si chiudono in seguito
all’eccitazione della bobina;
• SC (SCambio): a relè diseccitato alcuni contatti sono chiusi e altri aperti; all’eccitazione del
relè i contatti chiusi si aprono e quelli aperti si chiudono.
COMPORTAMENTO IN
CONDIZIONI DI PRESENZA DELLA
TENSIONE DI INGRESSO
2 TIPOLOGIE DI RELÈ
Relè bistabili (detti anche ritenuta o ad impulsi
Nei relè blstabili le posizioni di riposo (per esempio, contatti
aperti) e di lavoro (per esempio, contatti chiusi) ) sono
entrambi stabiliti anche in assenza di alimentazione della
bobina di eccitazione di ciascun intervento di apertura e di
chiusra dei relè è ottenuto alimentandola bobina stessa per
un breve istante (mediante un impulso di corrente).
Il mantenimento del contatti nella posizione di lavoro,
anche al cessare dell'alimentazione, e assicurato da un
sistema di ritenuta dì natura meccanica
IL CIRCUITO DI
COMANDO
RELÈ INTERRUTTORE AD ALIMENTAZIONE
DIRETTA
L’alimentazione della bobina coincide con tensione di rete
RELÈ INTERRUTTORE AD ECCITAZIONE
SEPARATA
L’alimentazione della bobina è a bassa tensione
PILOTARE UN RELÈ CON
ARDUINO
PILOTARE UN RELÈ CON
ARDUINO
PILOTARE UN RELÈ CON
ARDUINO
PILOTARE UN RELÈ CON
ARDUINO
PILOTARE UN RELÈ CON
ARDUINO
PILOTARE UN RELÈ CON
ARDUINO
PILOTARE UN RELÈ CON
ARDUINO
PILOTARE UN RELÈ CON
ARDUINO
CALCOLO DELLA RESISTENZA SULLA
BOBINA
CALCOLO DELLA RESISTENZA SULLA
BOBINA
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL CIRCUITO
IL PROGRAMMA
ESERCITAZIONI PROPOSTE
NE555
CIRCUITO INTEGRATO 555
L’integrato 555 ideato nei primi anni ‘70 è un temporizzatore di estrema precisione, versatile e di grande
semplicità di utilizzo.
Trova impiego in svariate applicazioni dell’elettronica analogica.
Il suo nome è dovuto alla presenza al suo interno di tre resistenze da 5 kW.
CIRCUITO INTEGRATO 555
Lo schema a blocchi dell’integrato a tecnologia bipolare è costituito da:
3 resistori da 5 kW,
due comparatori,
un flip-flop del tipo SR,
un BJT
un buffer di uscita, in grado di erogare una corrente massima di 200 mA.
I tre resistori realizzano un partitore resistivo in grado di fornire le tensioni di riferimento 2/3 di Vcc e
1/3 di Vcc, rispettivamente al comparatore 1 e al comparatore 2.
Le uscite dei comparatori sono collegate agli ingressi di Reset e di Set del flip-flop, la cui uscita
complementare pilota la base del BJT.
555 come astabile
Supponiamo che inizialmente il condensatore C sia scarico: gli ingressi dei due comparatori sui
piedini 2 e 6 si trovano a livello basso.
Il comparatore 1 dà in uscita un livello basso, quindi il reset del flip-flop è a livello basso; il
comparatore 2 dà in uscita un livello alto, settando il flip-flop e portando l'uscita Q a 1 e Q negato a
0.
Sul piedino 3 si ha Vout = H.
Il BJT è interdetto, quindi il piedino 7 si trova isolato da massa.
C inizia a caricarsi attraverso la serie di Ra ed Rb.
Quando Vc raggiunge il valore di 1/3 di Vcc, il comparatore 2 commuta e si porta a livello basso
(S=0) ma il flip-flop non commuta perché anche R=0, ed il condensatore continua a caricarsi.
Quando Vc raggiunge i 2/3 di Vcc, il comparatore 1 commuta, portando la sua uscita a livello alto
resettando il flip-flop (R=1) e portando l’uscita negata a livello alto, che satura il transistor.
Sul piedino 3 si ha ora Vout=L.
Il piedino 7 risulta collegato a massa e il condensatore si scarica attraverso la resistenza Rb.
Quando Vc scende al di sotto di 1/3 di Vcc, il comparatore 2 commuta, settando il flip flop, portando la
sua uscita a livello H e l’uscita negata a livello L.
Ora si ha Vout=H e il BJT risulta quindi interdetto, il piedino 7 risulta non più a massa, permettendo a
C di ricaricarsi, ripetendo il ciclo precedente.
• 555 come monostabile
• In condizioni di riposo l’ingresso positivo (V+) del comparatore 1 è mantenuto a + Vcc tramite la
resistenza Ra, mentre l’ingresso negativo (V-) è posto a (2/3)Vcc.
• L’uscita del comparatore 1 è alta e resetta il flip-flop, portando l’uscita negata del flip-flop a livello alto.
• L’ingresso negativo del comparatore 2 viene mantenuto, mediante un segnale di ingresso, ad un valore di
tensione maggiore di 1/3 di Vcc.
• L’uscita del comparatore è quindi Low.
• In queste condizioni si ha quindi il reset del flip-flop a livello alto e il set a livello basso, saturando il BJT.
• Nell’istante in cui all’ingresso negativo del comparatore 2 si ha una tensione negativa, inferiore a 1/3
di Vcc, la sua uscita va H, settando il flip-flop e interdicendo il BJT, permettendo al condensatore C di
caricarsi.
• Il condensatore inizia quindi a caricarsi attraverso la resistenza Ra.
Appena Vc che è anche quella del piedino positivo del primo comparatore, raggiunge i 2/3 di Vcc, l’uscita
del comparatore va H facendo condurre il transistor.
C si scarica rapidamente attraverso la bassa resistenza di uscita del BJT, restando scarico fino all’arrivo
del nuovo impulso.
LABORATORIO
555-astabile
555-monostabile
ASTABILE
ASTABILE
1)
ν= 25Hz, T=40ms
2)
C=10µF
3)
R2=1430Ω
4)
R1=2860Ω
∆t_off=10ms, ∆t_on=30ms
Ton = 0.693 (R1+R2)C
Toff = 0.693*R2C
∆t_on ∆t_of
T
MONOSTABILE
ASTABILE
MONOSTABILE
T=1.1*R*C=1.1*(20kΩ)*(1µF)~22ms
T
Il BJT Q1 in conduzione (saturazione) possiamo supporlo
equivalente ad una resistenza di bassissimo valore (2 ohm) ,
mentre quando non è in conduzione (interdizione) il suo
valore possiamo ritenerlo equivalente ad un resistenza di alto
valore >(10 Kohm).
Durante la conduzione del BJT
l’induttanza a regime si
comporta come un corto circuito, per cui la I = 12V/(118 +
2 OHM) = 100mA .
Il diodo ,polarizzato inversamente, non conduce corrente
Vce =1 * + 2Ω = 100 mA* 2 = 0.2 v
Nell’istante in cui il BJT commuta e va in interdizione, la sua resistenza equivalente sarà di 10 KΩ.
L’induttanza della bobina mantiene la stessa corrente di prima della commutazione ,diminuendo il
suo valore gradualmente con costante di tempo L / R, per cui ,almeno istantaneamente, sarà la VCE
=VR = R x I =10 K * 100mA = 1000 Volt.
Questa sovratensione, presente ai capi del BJT lo danneggerebbe, ma il diodo essendo adesso
polarizzato direttamente, entra in conduzione istantaneamente e con la sua VD = 0,5 Volt, impone
un abbassamento immediato della tensione VCE = 1000 Volt ad un valore a regime Vce = Vcc /(118
+10KΩ)*10KΩ = 11,86 Volt
Possiamo quindi affermare che la funzione del diodo D1 è quella di proteggere il transistore dalla
presenza di una elevata sovratensione presente tra il suo collettore ed emettitore ( VCE )
nell’istante della commutazione saturazione → interdizione
In questo caso il diodo è in polarizzazione diretta e quando il BJT è in conduzione avremmo nel
ramo una corrente
I= Vce/Rbce = Vce –VdRbce = 12 – 0.2/2 5,75 A
Sia il diodo che il BJT potrebbero non sopportare questo alto valore di corrente e danneggiarsi.
Oltretutto il diodo non avrebbe più la funzione di protezione contro la sovratensione (1000Volt)
dovuta all’induttanza della bobina durante la commutazione ON ®OFF
Per VIN > VCC il diodo D3 è polarizzato direttamente, quindi è in conduzione.
Sarà
quindi VIN - VCC = VR8 + VD3 ®
(Vin –Vcc) = (Vin –V2) + (V2 – Vcc)
(Vin –Vcc) = (Vin –V2 – Vd3)
(V2 = = (Vcc +Vd3)
(V2 = = (Vcc +0.5)
Per VIN < 0Volt (valori della tensione d’ingresso
negativi) è invece polarizzato direttamente il diodo
D4 che sarà quindi in conduzione.
Si avra
-Vin = -Vre –Vd4
-Vin = (-Vin –(-V2) – Vd4)
-Vin = -Vin +V2 _Vd4
V2 = -0.5 v
In questo caso lo stato d’uscita ON del timer viene determinato dal tempo necessario al
condensatore C7 a raggiungere un valore di 9,6 Volt , diverso dal valore precedente di 8 Volt
(2/3 Vcc),con un’alimentazione Vcc=12 Volt e senza la resistenza R1 aggiunta.
Conseguenza di ciò avremmo un tempo ON del timer diverso (maggiore) da quello definito dalla
espressione T = 1,09(R2+ R3)*C7
7. Quali sarebbero i tempi massimi e minimi con un condensatore C7 da 1 μF?
T = 1.09´ (R2 + R3) ´C7
Tmax= 1,09*10^6 *10^5*10^-6 = 1,199 sec
Tmin 1,09*(10^5* 10^-6 = 0.109 sec
8. Che cosa succede se si scambiano R4 e il pulsante S1?
La V2 =2,9V è minore dei 4 volt presenti all’ingresso + del comparatore B ,per cui il FFsarebbe
sempre attivo all’ingresso S (start) e l’uscita del timer sarebbe sempre ON.
Finito un ciclo ON, il FF si verrebbe a trovare con i due ingressi S=1 e R=1; condizione di blocco per
il funzionamento del FF.
Viceversa ,premendo il pulsante, il pin 2 sarebbesempre agganciato alla Vcc e l’uscita del timer
sarebbe sempre OFF
9. Che cosa succede se non si salda il condensatore C5 ?
Il pin 4 del reset sarebbe sempre disattivato perché agganciato a Vcc ed il timer all’accensione non
avrebbe momentaneamente l’uscita forzata a 0 ma uno stato ON o OFF casuale.
10. Con l’uscita del 555 (pin 3) è possibile pilotare una porta logica TTL ? A quali condizioni?
Si a condizione che la Vcc= 5 Volt oppure si inserisca in uscita (pin 3) un partitore
resistivo che limiti la Vout a 5 Volt.
11. Dove altrimenti sarebbe possibile collegare il diodo LED di segnalazione?
Avendo un diodo led in conduzione una corrente Imax= 20 mA , può essere pilotato direttamente in uscita
(pin 3), potendo quest’uscita pilotare carichi fino a 100 mA.
12. Dire almeno un caso in cui è indispensabile la presenza del relè
L’uso del relè è indispensabile quando si devono pilotare carichi che prevedono unassorbimento di corrente
oltre i 100mA (sia in tensione continua che alternata), quando ecessitano di una tensione d’alimentazione
in alternata (per qualsiasi valore); peresempio l’uso del timer per l’accensione delle luci delle scale in un
condominio;
13. Che cosa succederebbe se al posto di R8 saldassimo una resistenza da 10 Kohm?
La V2 = 6 V sarebbe sempre superiore ai 4 V ( 1/3 Vcc) presen
all’ingresso V+ del comparatore B e di conseguenza non
avrebbe mai la commutazione dell’uscita del suddet
comparatore , necessaria per attivare lo stato d’uscita ON d
timer.
14. Quali sono i valori corretti di tensione da applicare al pin 2 del 555 per avviare la temporizzazione? Perché?
La commutazione dell’uscita del timer da OFF a ON avviene quando il valore della V2 ( pin 2 del 555 ) scende sotto il
valore di riferimento di 4 Volt (1/3 Vcc) , quindi per valori che vanno do 0 Volt a 4 Volt ,perché solo in queste condizioni il
comparatore B può commutare e dare all’ingresso S (start ) del FF l’impulso necessario per la commutazione dello stato
logico d’uscita ( Q ). Quindi per 0V <V2<Vcc
15. Cosa potrebbe accadere se non ci fosse il resistore R3 in serie al trimmer R2 ?
Il resistore R3 in serie al trimmer R2, oltre ad regolare il tempo in cui l’uscita del timer è ON funge da
resistenza di carico per il BJT interno all’Ic 555.Nel caso in cui il trimmer fosse cortocircuitato R2 = 0 ohm (
Tmin ), senza la R2 il BJT si verrebbe a trovare con una resistenza di carico Rc = 0 danneggiandosi perché
attraversato da un’alta corrente Icarico.
16. Che cosa succede se si scambiano fra di loro R6 e C5 ?
Per essere attivo il reset, il pin 4 deve essere a potenziale 0 Volt. Con la configurazione seguente,
all’accensione del circuito, inizialmente il C5 è scarico (cortocircuito ) ( Vc = 0 ), la V4 sarà a potenziale Vcc e
quindi il reset non è attivo.
Di conseguenza l’ OUT del timer può assumere uno stato ON o OFF casuale.
Quando il condensatore si sarà caricato non permetterà il passaggio di corrente
e di conseguenza la caduta di tensione nella R6 sarà VR6 = 0 Volt e quindi il
reset sarà da questo istante in poi sempre attivo e bloccherà l’OUT del timer
sempre a 0 Volt.
17. Dire almeno un caso in cui sarebbe stato possibile pilotare un carico senza relè
Per alimentare ed attivare per un tempo T , l’accensione di lampade o semplici
apparecchiature elettriche o elettroniche che non richiedono una corrente superiore a 100 mA ( lettori mp3, diodi Led,
piccoli motorini in corrente continua, lampeggiatori in bassa tensione continua, ecc.. )
18. Che cosa accade se D4 viene invertito?
Il diodo D4 in questo caso risulta polarizzato direttamente ed in
conduzione tramite la R5.
La VD4 = 0,5 Volt impone questo valore all’ingresso del pin 2 ( V2 =
0,5 Volt) , interpretatodal Ic 555 come un livello (V2<4Volt) atto
a provocare lo start ( livello ON in uscita ) che simanterrà in
modo ripetitivo indipendentemente dallo stato del pulsante.
Oltretutto il D4 nonesplicherà più la sua principale funzione di
protezione dell’ingresso da valori di tensione negativi ( Vin < -0,5
Volt )
19. Perché C1 e C2 sono stati utilizzati in parallelo anziché uno solo dei due?
C1 ( 0,1 uF ) serve a filtrare disturbi di alta frequenza presenti nella linea di alimentazione :
C2 ( 100 uF ) ha una funzione di filtro di livellamento della Vcc.
20. Se la linea che collega il pulsante all’ingresso del circuito è abbastanza lunga ,quali problemi
potrebbero sorgere? Come risolverli?
Se il pulsante di start è posto in posizione remota rispetto al circuito, con percorsi adiacenti a quelli della rete
elettrica ogni qualvolta si accende un elettrodomestico (Aspirapolvere, lavatrice , ecc.. ) i disturbi provocati
dalle spazzole dei motori elettrici ,captati per induzione dai fili del pulsante sono sufficienti ad attivare il timer
rendendolo quindi poco affidabile.
Per esempio , una Zin = 1K (impedenza d’ingresso dell’apparecchiatura) attraversata da una corrente indotta
(disturbo) di 1 mA , avrebbe ai suoi capi una Vin= Zin*I = 1K*1mA = 1 Volt , ma se la Zin = 100K la Vin
=100K * 1mA = 100 Volt. E’ importante quindi, al fine di ridurre l’effetto dei disturbi di linea che la Zin sia la più
bassa possibile. A tal fine si è realizzato uno stadio d’ingresso a bassa impedenza costituito da R4, C3, seguito
da un filtro passivo composto da R5, C4.
IL PC: INPUT E OUTPUT
Generalità
architettura a BUS
Classificazione delle memorie
Porte seriali
architettura del software
Linguaggi di programmazione
Il linguaggio C
Gli algoritmi
LA PROGRAMMAZIONE
GENERALITA
Nel 1946 fu costruito l’ENIAC, primo calcolatore elettronico, realizzato interamente a valvole.
Tuttavia l’organizzazione era sostanzialmente la stessa del MARK 1.
John von Neumann (1903 – 1957), matematico di origine ungherese, naturalizzato americano,
aveva visto funzionare il Mark 1 a Los Alamos nel 1944, dove veniva utilizzato per i calcoli
necessari per la bomba atomica. Neumann non rimase soddisfatto del funzionamento del Mark 1
per :
• dati e istruzioni non venivano inseriti attraverso le stesse unità di ingresso e non
venivano memorizzati nella stessa memoria
• l’esecuzione di un programma richiedeva la continua presenza di operatori umani.
Nel 1946 von Neumann pubblicò un articolo in cui proponeva una macchina alternativa, in cui:
• dati e istruzioni dovevano essere immessi attraverso le stesse unità di ingresso e
dovevano essere memorizzati nella stessa memoria
• per l’esecuzione di un programma, si doveva caricarlo interamente in memoria.
Nel 1947 era stato costruito il primo transistor, ma il primo calcolatore a transistor risale al 1959, realizzato dall’IBM.
Negli anni ’60 l’integrazione dei componenti elettronici su un unico chip di silicio divenne molto grande, tanto che nel
1971 si arrivò a costruire il primo microprocessore (μP, CPU) nei laboratori della Intel per opera di Federico Faggin.
Il μP racchiudeva diversi blocchi dell’architettura di von Neumann:
NB:
la piccola parte di memoria incorporata nel μP è denominata ‘cache’.
Nel 1975 fu costruito il primo calcolatore con μP. Si costruirono grandi calcolatori destinati ai centri
di ricerca e a grandi utenze in generale (unico calcolatore con molti terminali: multiplazione a
divisione di tempo).
Nell’agosto del 1981 l’IBM presentò sul mercato un piccolo calcolatore destinato all’uso
personale: il PC. I PC , in quanto macchine economiche, nacquero con due difetti che li
caratterizzano tuttora: non sono
• deterministici: non garantiscono un tempo massimo in cui la routine sarà eseguita;
• real time: velocità di risposta (esecuzione routine) non all’altezza di quella del processo
esterno da controllare.
ARCHITETTURA A BUS
Il bus è un canale di comunicazione formato da più linee condivise da tutti i componenti del sistemi.
Hard disk
Caratteristiche:
• è possibile un solo trasmettitore (Tx) per volta: in caso contrario, nella più innocua delle ipotesi, il livello
logico della linea potrebbe essere incerto
• sono possibili più ricevitori (Rx) contemporaneamente; esiste un limite massimo al numero dei Rx
dipendente dal fan-out del trasmettitore
• il grande vantaggio del bus è la sua espandibilità, cioè la possibilità di aggiungere ulteriori componenti nel
sistema mantenendo inalterato il circuito esistente.
Il bus può essere diviso in tre parti funzionali:
• address bus: linee che portano l’informazione dell’indirizzo del componente
• data bus: linee su cui viaggiano i dati che i componenti del sistema si scambian
• control bus: linee su cui viaggiano i segnali di comando che gestiscono l’accesso al bus.
L’accesso al bus dei componenti, come Tx o come Rx, è gestito dal master (spesso un μP).
In generale si hanno due tecniche di accesso al bus:
•
Polling: il master sonda periodicamente, in sequenza, lo stato di tutti i componenti, se
qualcuno ha bisogno di impegnare il bus, viene accontentato.
Vantaggio: semplicità hardware
Svantaggio: possibili tempi lunghi di attesa di accesso.
• Interrupt: il componente che deve impegnare il bus invia una comunicazione al PIC (es: 8259),
il quale esamina tutte le richieste e invia al master la richiesta con priorità più alta; il master, sulla
base delle proprie esigenze interne può accogliere o meno la richiesta; nel caso la accolga chiede
al PIC il codice del componente che ha chiesto l’impegno del bus e invia i relativi segnali di comando.
CLASSIFICAZIONE DELLA MEMORIA in un PC
Classificazione per tipologia secondo:
• il tipo di accesso:
• sequenziale: nastri, alcuni registri
• casuale (RAM): dischi (magnetici e ottici), chip seminconduttori
• l’uso:
• solo lettura (ROM): chip sminconduttori, CD-ROM
• lettura/scrittura: dischi (magnetici e ottici), chip seminconduttori
• la conservazione dei dati dopo aver tolto l’alimentazione:
• non volatile: chip semiconduttori, dischi, nastri
• volatile:
• statica (SRAM): più veloce e più costosa,
• dinamica (DRAM): bisogno di continuo rinfresco, maggiore integrazione
cache: è chiamata di 1° livello.
buffer memory: memoria tampone (SRAM), disposta vicina al μP,
lavora a una frequenza più alta di quella di lavoro (cache di 2° livello).
working memory: memoria di lavoro (DRAM), memoria in cui è
caricato il programma per l’esecuzione.
bulk memory: memoria di massa (dischi), per la funzione di
archivio.
PORTE seriali e parallela in un PC
Trasmissione parallela: tutti i bit del dato sono trasmessi contemporaneamente, ciascuno sulla
propria linea.
Es: RS 232, la cui massima
velocità di trasmissione nei PC
è in genere di 115 200 baud (bit
al secondo: bps oppure b/s)
NB: a fronte di un disturbo, solo la linea di segnale può variare il suo potenziale (la linea di
ritorno è vincolata a 0 V) e ciò potrebbe alterare il valore del bit.
8
Porte in un PC - USB
Es: USB (Universal Serial Bus), nuovo standard, che nei PC sta sostituendo sia le vecchie porte sia parallele che seriali.
I nuovi chip e la trasmissione differenziale consentono velocità molto alte:
USB 1.0 1.5 Mb/s
1.1 12 Mb/s
2.0 480 Mb/s
3.0 4.8 Gb/s
Vantaggio della trasmissione differenziale: un disturbo elettromagnetico colpisce in ugual misura i
due conduttori (entrambi liberi di variare il loro potenziale) per cui la differenza dei potenziali non
cambia.
ARCHITETTURA SOFTWARE di un PC
Il software di un PC è organizzato su più livelli:
FIRMWARE (BIOS per PC IBM compatibili):
consiste in programmi
(routine, cioè procedure) fornite dal costruttore del PC. All’atto
dell’avviamento le routine del firmware programmano i chip del sistema,
testano la memoria e caricano in memoria il sistema operativo.
SISTEMA OPERATIVO: consiste in una collezione di programmi utili alla
gestione delle risorse del computer, che dispensano l’utente dalla fatica di
dover scriverli in proprio. Si tratta di programmi scritti facendo ricorso
alle routine del firmware.
PACCHETTI SOFTWARE APPLICATIVI: i programmi messi a disposizione
dal sistema operativo (es: editor di testo) sono spesso poveri di
funzionalità. Facendo ricorso alle routine del firmware e del sistema
operativo si sono costruiti quindi dei programmi molto più ricchi, già
pronti per l’utente.
SOFTWARE DI SVILUPPO:
sono linguaggi di programmazione, che
permettono la creazione di applicazioni nuove. Spesso infatti le esigenze
degli utenti non possono essere soddisfatte dai pacchetti applicativi già
esistenti.
LINGUAGGI DI PROGRAMMAZIONE
Il primo linguaggio di programmazione è stato il linguaggio macchina: codice operativo e dati
erano rappresentati da sequenze di 0 e 1.
Esempio: per μP compatibili con l’8086 della Intel l’operazione ‘metti il numero 4 nel registro
AX’ costringeva i programmatori a scrivere il seguente codice:
1011 1000 0000 0100
Con il conseguente problema di frequenti errori di scrittura e scarsa leggibilità
La soluzione fu trovata nella codifica esadecimale: B 8 0 4
Si producevano meno errori, ma permaneva la scarsa leggibilità.
Con la codifica esadecimale, dopo aver scritto il programma (codice sorgente) si rende
necessaria una decodifica in binario del codice esadecimale.
Il passo successivo fu la creazione di linguaggi di programmazione con codici
mnemonici (assembly): MOV AX, 4
L’istruzione diveniva più chiara: il codice operativo MOV esprime chiaramente il senso dell’operazione
(mnemonico).
I linguaggi assembly sono definiti di basso livello, in quanto richiedono comunque la piena
conoscenza del microprocessore da programmare.
La trasformazione del codice sorgente (estensione .asm) in binario è svolta da un programma
chiamato assembler, il quale si occupa anche di controllare la sintassi. L’assembler crea un file binario
con estensione .obj (file oggetto). Se il programma sorgente è formato da più file, l’assembler
esamina un file per volta. E’ successivamente compito di un altro programma, il linker, collegare i vari
file oggetto e aggiungere il codice delle librerie utilizzate.
Il linker crea il file eseguibile (.exe) senza fissare un indirizzo assoluto cui il programma sarà caricato
nella memoria RAM. Si è voluto lasciare al sistema operativo la libertà di caricare il file eseguibile
nella zona di memoria al momento più conveniente. Un programma che permette questo al sistema
operativo si dice rilocabile.
Difficoltà presenti nella programmazione in
assembly:
• la realizzazione di programmi complessi
rende molto impegnativa la programmazione
• l’obbligo per il programmatore della piena
conoscenza del μP che dovrà eseguire Il
programma.
Per superare le difficoltà proprie della programmazione assembly sono stati creati linguaggi di programmazione
evoluti (detti anche di alto livello: Basic, C, Pascal, …).
Presentano il vantaggio
• di consentire la programmazione anche a utenti senza alcuna conoscenza dell’hardware del computer
• di implementare istruzioni compatte (facendo ricorso a librerie) che riducono il lavoro del programmatore.
Questi vantaggi sono ottenuti al costo di uno sfruttamento meno ottimale delle risorse del computer (per la
caratteristica di essere one-to-many e per la presenza di codice superfluo).
La traduzione del file sorgente in eseguibile può essere realizzata con programmi:
I programmi
interpreti sono ottimizzati per una veloce fase di messa a punto del programma che
si sta scrivendo (debugging) , ma ogni volta che occorre eseguire un file sorgente lo si deve
trasformare in eseguibile. Sul disco non resta alcun file oggetto o eseguibile. I linguaggi di
programmazione i cui programmi sono eseguiti per mezzo di un interprete sono detti linguaggi
interpretati (es: Basic, Html).
I programmi compilatori sono invece ottimizzati per l’avviamento veloce dell’esecuzione dei file
eseguibili, in quanto memorizzano su disco sia i file oggetto (.obj) che quelli eseguibili (.exe),
sono però più lenti in fase di messa a punto. I linguaggi di programmazione i cui programmi sono
eseguiti per mezzo di un compilatore sono detti linguaggi compilati.
Per il linguaggio di programmazione C, si sono costruiti normalmente solo compilatori per cui lo
si considera un linguaggio compilato.
Confronto Interprete – Compilatore:
L’esecuzione di un programma sorgente mediante un interprete è meno efficiente, poiché
impegna più memoria ed è meno veloce in quanto il codice macchina è generato durante
l’esecuzione stessa.
L’esecuzione tramite un compilatore parte invece da un codice già in linguaggio macchina,
che viene caricato e immediatamente eseguito.
Tuttavia un interprete consente una maggiore flessibilità nella fase di scrittura e prova di un
programma.
Negli ultimi anni si è sviluppato un approccio ibrido: software di sviluppo che consentono sia
l’interpretazione che la compilazione del codice sorgente.
IL LINGUAGGIO
La prima versione del linguaggio C fu realizzata nel 1972, da Dennis Ritchie, presso i Bell
Laboratories (AT&T). Ritchie si fondò su lavori precedenti, costruendo un linguaggio capace di
implementare molti più tipi di dati (interi, reali, caratteri, strutture).
Il C pur essendo un linguaggio di programmazione di alto livello conservò la prerogativa dei
linguaggi assembly, che interagivano direttamente con l’hardware della macchina (per questo
fu spesso indicato come di medio livello). Molte istruzioni in C (es: incremento e decremento)
sono direttamente traducibili in singole istruzioni di linguaggio macchina. Il C fu pensato come
un linguaggio di programmazione per esperti.
Il C si rivelò un linguaggio potente, efficiente, con sintassi compatta e fu molto apprezzato
in ambito industriale e scientifico.
Col C fu riscritto il sistema operativo Unix.
Il proliferare di più versioni del C, con conseguenti problemi di portabilità, fece si che nel 1990
fu definito lo standard ANSI C.
Nel 1998 fu definito uno standard ISO/IEC del C++.
1
IL COMPILATORE DEV-C++
Il compilatore Dev-C++ consente la programmazione anche secondo il C standard (ANSI C). All’apertura del programma
(icona
) si presenta la seguente finestra:
Il nuovo file è automaticamente nominato “Untitled1”: lo si può salvare subito assegnandogli il nome
desiderato, oppure al momento della compilazione.
E’ utile evidenziare il numero di riga. Per farlo: dal menu
Tools  Editor Options  Display
A questo punto spuntare l’opzione Line Numbers e chiudere con OK.
STRUTTURA DI UN PROGRAMMA
Un programma in C è diviso in due parti:
• sezione dichiarativa: in cui il programmatore indica i sottoprogrammi (librerie) e i dati che
intende utilizzare
• Chiamate a librerie esterne (#include): il preprocessore (precompilatore), prima
di avviare la fase della compilazione vera e propria sostituisce la riga con l’intero
contenuto del file.
#include
#include
<stdio.h>
“stdio.h”
la ricerca del file è effettuata all’interno della cartella standard
la ricerca del file è effettuata prima nella stessa cartella del file sorgente, poi in
quelle standard
• Definizione delle costanti (#define):
#define
•
•
MAX 100
il preprocessore sostituisce il valore di MAX (cioè 100) in tutti i
punti del programma in cui è presente
Dichiarazione delle variabili:
int x;
float y;
le variabili dichiarate in questa sezione hanno validità globale
•sezione esecutiva: in cui viene scritto il codice degli algoritmi che si intende far eseguire. Si tratta
della scrittura di funzioni. In tutti i programmi deve essere presente la funzione main().
NB: le variabili dichiarate all’interno delle funzioni hanno validità solo in ambito locale e si
sovrappongono e annullano le variabili globali con lo stesso nome.
Il programma precedente, scritto senza commenti risulta:
NB: è importante ricordare che con le istruzioni di assegnamento:
a = b;
z = x + y;
si carica nella variabile indicata a sinistra il valore dell’espressione a destra.
Il programma può essere mandato in esecuzione anche con i seguenti comandi:
• Menu Execute -- Compile & Run
• Da tastiera: F9
•
7
TIPI DI DATI
Quando il C fu scritto si decise di non fissare con
uno standard l’impegno di memoria dei tipi di
dati. Questa flessibilità consente di sfruttare al
meglio le caratteristiche dei diversi compilatori e
sistemi operativi.
NB: in C non sono definite variabili booleane. Per
le condizioni di VERO e FALSO si ricorre alle
variabili intere:
0 FALSE
0 TRUE






Programmare significa determinare quali operazioni eseguire e in quale sequenza per raggiungere la
soluzione
Perché il programmatore possa istruire il calcolatore sulle operazioni da fare serve un linguaggio noto ad entrambi che
sia da interfaccia fra i due operatori sapendo che:
 Il calcolatore comprende solo sequenze di zeri e
uno (ad es. la sequenza 1001001 potrebbe significare, per un
ipotetico
calcolatore, “fai la somma”): linguaggio macchina
 Il programmatore comprende le parole “fai la somma” (mentre 1001001 non significa nulla per lui): linguaggio umano
L’interfaccia « traduttore» è un linguaggio di programmazione ad alto livello (HLL) che può essere definito con:
 Interprete: Le istruzioni del codice sorgente vengono ad
una ad una tradotte in linguaggio macchina e subito
eseguite dalla CPU
 compilatoreTutto il codice sorgente viene tradotto in linguaggio macchina e memorizzato in un file detto programma
(o file o codice) eseguibile
In un HLL il programmatore non ha necessità di programmare le operazioni di base (ad es. leggere un numero dalla
tastiera, calcolare la radice quadrata, visualizzare una parola, ecc.) che sono programmate e compilate dal produttore
del traduttore e sono a disposizione del programmatore sotto forma di funzioni
I codici eseguibili (quindi già tradotti in linguaggio macchina) che realizzano queste operazioni vengono raggruppati in
file detti librerie (collezioni di funzioni di base)
Il processo di creazione di un eseguibile a partire dai sorgenti (build) è composto da 2 fasi:
- La compilazione che traduce il codice C in linguaggio macchina ottenendo il file oggetto:
- il linking: il file oggetto e le librerie vengono unite (collegate – link) in modo da ottenere un unico file eseguibile


Il compilatore verifica la correttezza del codice C e produce due tipi di errori:
Error: errori sintattici, impediscono la generazione del codice eseguibile
Warning: errori non sintattici che non impediscono la generazione del codice eseguibile; segnalano un possibile
problema che il compilatore risolve in base a regole generiche che potrebbero non essere quella corrette
Gli algoritmi
ALGORITMI, PROGRAMMI E DATI
Algoritmo = insieme di istruzioni che indicano come svolgere operazioni complesse su dei dati attraverso successioni di
operazioni elementari
Programma = algoritmo in un linguaggio
“comprensibile” dal computer.
Dato = informazione da elaborare rappresentata in un formato che consenta al programma di operare su di essa
Controllo del programma
L’ordine con cui le diverse operazioni devono essere eseguite è specificato da particolari costrutti linguistici, detti strutture di
controllo.
Si hanno tre strutture fondamentali:
sequenza
selezione (o scelta)
iterazione (o ciclo)
La sequenza indica una successione di operazioni che devono essere eseguite una dopo l’altra,
La selezione (o scelta) permette a un programma di proseguire secondo uno tra due (o più) flussi di istruzioni alternative
L’iterazione (o ciclo, o loop) consiste nella ripetizione di una o più istruzioni,.
I diagrammi a blocchi
• Il linguaggio dei diagrammi a blocchi è un possibile formalismo per la descrizione di algoritmi
• Il diagramma a blocchi, o flowchart, è una rappresentazione grafica dell’algoritmo
• Un diagramma a blocchi descrive il flusso delle operazioni da eseguire per realizzare la trasformazione,
definita nell’algoritmo, dai dati iniziali ai risultati
• Ogni istruzione dell’algoritmo viene rappresentata all’interno di un blocco elementare, la cui forma grafica è
determinata dal tipo di istruzione
• I blocchi sono collegati tra loro da linee di flusso, munite di frecce, che indicano il susseguirsi di azioni
elementari
I diagrammi a blocchi
• L’insieme dei blocchi elementari che descrivono un algoritmo deve soddisfare le
seguenti condizioni:
 ciascun blocco di azione o di lettura/scrittura ha una sola freccia entrante ed una sola freccia
uscente
 ciascun blocco di controllo ha una sola freccia entrante e due frecce uscenti
 ciascuna freccia entra in un blocco oppure si innesta in un’altra freccia
 ciascun blocco è raggiungibile dal blocco iniziale
 il blocco finale è raggiungibile da qualsiasi altro blocco
Diagramma a blocchi per la selezione, in un mazzo
di chiavi, di quella che apre un lucchetto
ESERCIZI DI SVILUPPO DI ALGORITMI ORIENTATI ALLA PROGRAMMAZIONE
•
•
•
•
Partiamo dall’analisi del problema
Scriviamo la specifica funzionale
Introduciamo i contenitori di dati necessari e le relative operazioni elementari
Scriviamo l’algoritmo che opera su tali dati con un diagramma di flusso
Problema: telefonata
Descrizione:
vogliamo chiamare un abbonato con il telefono.
Requisiti, in cui prevediamo i diversi casi:
la telefonata viene eseguita con successo
messaggio “telefonata riuscita”
la telefonata non può essere portata a termine
messaggio “telefonata non riuscita”
A) PROBLEMA MAGGIORE
• Descrizione: vogliamo il maggiore tra due numeri interi, x e y.
• Requisiti in cui prevediamo i diversi casi:
– se x - y > 0, il maggiore è x
– se x - y < 0, il maggiore è y
– se x - y = 0, x e y sono uguali
Esempio: lati di un triangolo. Come esempio di selezioni binarie in cascata si può considerare il seguente
PROBLEMA: “scrivere un algoritmo che consenta di stabilire se tre numeri, a, b, c possono essere i lati di un triangolo”.
ALGORITMO: come è noto, in un triangolo la somma di due lati qualsiasi è maggiore del terzo
Perciò dovranno essere contemporaneamente soddisfatte le tre condizioni:
a + b > c
a + c > b
b + c > a
LA PSEUDOCODIFICA
La pseudocodifica è un linguaggio per la descrizione di algoritmi secondo le regole della programmazione
strutturata
•
La descrizione di un algoritmo in pseudocodifica si compone di due parti...
la dichiarazione delle variabili usate nell’algoritmo
la descrizione delle azioni dell’algoritmo
• Tipo delle variabili
 Il tipo di una variabile indica l’insieme dei valori che possono essere assegnati a quella variabile
 Su costanti e variabili di un tipo è possibile effettuare le operazioni che sono proprie di quel tipo e
tutte le operazioni di confronto
 Sono permessi i seguenti 4 tipi: integer, real, boolean, stringq
Per realizzare i cicli la maggior parte dei linguaggi (tra cui il C) dispone dei tre costrutti specifici
for , while , do-while
il cui uso costituisce uno dei fondamenti della cosiddetta programmazione strutturata che consentono di evitare
l’istruzione di salto, sconsigliata dai principi della programmazione strutturata
Iterazione enumerativa (for). Applicata ad una somma
for esamina il valore di una espressione di controllo o condizione, e se la trova diversa da zero (o “vera”) esegue una o più
istruzioni, altrimenti esce dal ciclo.
Le istruzioni vengono eseguite un numero prefissato di volte, dopo di che si ha l’uscita dal ciclo..
Iterazione. Affinché l’iterazione sia costituita da un numero finito di passi è necessario che nella linea di collegamento
sia inserito un simbolo di decisione che contenga la condizione di uscita dal ciclo.
Tale blocco di controllo si dice guardia, e si può trovare prima /dopo del gruppo di istruzioni che costituiscono il ciclo
Esempio: Somma dei primi n numeri naturali. Le pseudo istruzioni sono le seguenti:
leggi n;
somma = 0;
for (i=1; i<=n;
i=i+1)
somma = somma + i;
Il costrutto while inizia esaminando il valore di una espressione di controllo o
condizione.
Se essa è diversa da zero (ossia è vera) le istruzioni del ciclo vengono eseguite, altrimenti si ha
l’uscita dal ciclo.
Dopo le istruzioni del ciclo ne viene eseguita una che altera il valore dell’espressione di controllo, e
quando questa risulta uguale a zero si ha l’uscita del ciclo.
Iterazione con guardia alla fine (do-while). Il ciclo do-while inizia con la parola do, seguita dalla o
dalle istruzioni da eseguire, e termina con la parola while seguita dalla condizione che deve
essere verificata per la ripetizione del ciclo.
Esso realizza il diagramma di flusso già visto
LA PROGRAMMAZIONE
Introduzione
funzioni di Imput/output
variabili, dati e costanti, input e output
il controllo di flusso
Strutture iterative
Vettori
stringhe e caratteri
sottoprogramma
esercizi
AMBIENTE DI SVILUPPO: GEANY 1) NUOVO -- SCRITTURA FILE DI TESTO
2) SALVA COME  ESTENSIONE .c, .cpp, .pas ec
3) compila  compila  esegui






Programmare significa determinare quali operazioni eseguire e in quale sequenza per raggiungere la
soluzione
Perché il programmatore possa istruire il calcolatore sulle operazioni da fare serve un linguaggio noto ad entrambi che
sia da interfaccia fra i due operatori sapendo che:
 Il calcolatore comprende solo sequenze di zeri e
uno (ad es. la sequenza 1001001 potrebbe significare, per un
ipotetico
calcolatore, “fai la somma”): linguaggio macchina
 Il programmatore comprende le parole “fai la somma” (mentre 1001001 non significa nulla per lui): linguaggio umano
L’interfaccia « traduttore» è un linguaggio di programmazione ad alto livello (HLL) che può essere definito con:
 Interprete: Le istruzioni del codice sorgente vengono ad
una ad una tradotte in linguaggio macchina e subito
eseguite dalla CPU
 compilatoreTutto il codice sorgente viene tradotto in linguaggio macchina e memorizzato in un file detto programma
(o file o codice) eseguibile
In un HLL il programmatore non ha necessità di programmare le operazioni di base (ad es. leggere un numero dalla
tastiera, calcolare la radice quadrata, visualizzare una parola, ecc.) che sono programmate e compilate dal produttore
del traduttore e sono a disposizione del programmatore sotto forma di funzioni
I codici eseguibili (quindi già tradotti in linguaggio macchina) che realizzano queste operazioni vengono raggruppati in
file detti librerie (collezioni di funzioni di base)
Il processo di creazione di un eseguibile a partire dai sorgenti (build) è composto da 2 fasi:
- La compilazione che traduce il codice C in linguaggio macchina ottenendo il file oggetto:
- il linking: il file oggetto e le librerie vengono unite (collegate – link) in modo da ottenere un unico file eseguibile


Il compilatore verifica la correttezza del codice C e produce due tipi di errori:
Error: errori sintattici, impediscono la generazione del codice eseguibile
Warning: errori non sintattici che non impediscono la generazione del codice eseguibile; segnalano un possibile
problema che il compilatore risolve in base a regole generiche che potrebbero non essere quella corrette
STRUTTURA DI UN PROGRAMMA
Un programma in C è diviso in due parti:
• sezione dichiarativa: in cui il programmatore indica i sottoprogrammi (librerie) e i dati che
intende utilizzare
• Chiamate a librerie esterne (#include): il preprocessore (precompilatore), prima
di avviare la fase della compilazione vera e propria sostituisce la riga con l’intero
contenuto del file.
#include
#include
<stdio.h>
“stdio.h”
la ricerca del file è effettuata all’interno della cartella standard
la ricerca del file è effettuata prima nella stessa cartella del file sorgente, poi in
quelle standard
• Definizione delle costanti (#define):
#define
•
•
MAX 100
il preprocessore sostituisce il valore di MAX (cioè 100) in tutti i
punti del programma in cui è presente
Dichiarazione delle variabili:
int x;
float y;
le variabili dichiarate in questa sezione hanno validità globale
•sezione esecutiva: in cui viene scritto il codice degli algoritmi che si intende far eseguire. Si tratta
della scrittura di funzioni. In tutti i programmi deve essere presente la funzione main().
NB: le variabili dichiarate all’interno delle funzioni hanno validità solo in ambito locale e si
sovrappongono e annullano le variabili globali con lo stesso nome.
ESEMPIO ; Programma che evidenzia alcune opzioni di visualizzazione dei numeri reali







Funzioni di I/O per numeri
Per utilizzare le funzioni di Input/Output bisogna includere il file di intestazione (header file) denominato <stdio.h>
<stdio.h> contiene la sintassi d’uso di varie funzioni e la definizione di alcune costanti simboliche (#define), (EOF) usata da
alcune funzioni per segnalare la fine dell’input o del file
Sintassi:
---------------------------------------------------------------------------------------------------------scanf(stringa di formato, lista di variabili)
scanf("%d", &i);
Legge valori dalla tastiera e li assegna alle variabili indicate nella lista di variabili &i
Per ciascuna variabile c’è il corrispondente tipo nella stringa di formato scanf("%d%d",&a, &b);
Input da tastiera : scanf("%d", &i) Notare che
- la variabile i è preceduta dal carattere &
- La funzione precedente "%d", assegna alla variabile i il valore intero letto dalla tastiera
-----------------------------------------------------------------------------printf(stringa di formato, lista di espressioni)
printf("valore digitato: %d", i);
 Visualizza il testo indicato nella stringa di formato con i valori elencati nella lista di espressioni a, b
 Ciascun valore della lista di espressioni viene visualizzato sostituendolo alla corrispondente direttiva di conversione nella stringa di
formato printf("Lat: %d, Lon: %d\n", a, b);
Output su video printf("%d", i) notare che:
- la variabile i non è preceduta dal carattere &
- la funzione precedente «d» visualizza un numero intero: contenuto nella variabile i
In conclusione per rappresentare una o piu variabili si deve prenotare la posizione che le variabili devono occupare all’interno
del messaggio per mezzo di specificatori di formato
Lo specificatore di formato è un
simbolo, (d: intero, f: float, c: char, ecc) preceduto da % associato al tipo di variabile da
rappresentare in funzione delle esigenze del programmatore
d: specificatore di formato, i: variabile
scanf("%d", &i);
L’esecuzione di questa istruzione fa
sì che il sistema attenda in input un
dato da parte dell’utente.
LETTURA E STAMPA
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i; // istruzione dichiarativa
// istruzioni operative
printf("digita un numero ");
scanf("%d", &i); //legge i
printf("valore digitato: %d\n", i);
/* istruzione di ritorno al sistema operativo */
return EXIT_SUCCESS;
}
Il primo esperimento Si vuole scrivere un programma in linguaggio C che chieda all’utente di introdurre da tastiera due
numeri interi e visualizzi il valore della loro somma sul video
 premessa
 I numeri richiesti vengono immagazzinati nella memoria centrale del calcolatore (RAM)
 Ciascun numero sarà immagazzinato in una piccola porzione di memoria detta variabile costituita da un certo numero di
byte
 A ogni variabile il programmatore dà un nome per potersi riferire ad essa
 Anche il risultato della somma dovrà essere immagazzinato nella memoria del calcolatore in una variabile, quindi avremo:
1.Chiedere il primo numero e metterlo in una variabile di nome A
2.Chiedere il secondo numero e metterlo in una variabile di nome B
3.Calcolare la somma di A e B e mettere il risultato in una variabile di nome S
4.Visualizzare il contenuto della variabile
Assegnazioni di variabili
 Assegnare un valore ad una variabile significa memorizzare in essa un valore
 Per assegnare un valore si usa il simbolo ‘=’:
X = 12
 Il valore può essere il risultato di un calcolo:
S = A+B
questo indica che in Sviene memorizzato il valore risultante dal calcolo A+B
 Il segno = significa “prende il valore di”:
S prende il valore del risultato di A+B
 Ogni volta che si assegna un valore ad una variabile, il contenuto precedente viene perso
Definizione delle variabili
 Tutte le variabili utilizzate nel programma devono essere definite
 Le definizioni vanno collocate tutte insieme
prima delle istruzioni eseguibili:
int A, B, S // intindica che A, Bed Ssono variabili adeguate a contenere valori interi
scanf("%d", &A);
scanf("%d", &B);
S = A + B;
printf("%d", S);

IL PRIMO ESPERIMENTO
Le istruzioni che costituiscono il programma devono essere racchiuse tra parentesi graffe per formare un blocco. Se questo è l’unico
presente, deve essere chiamato main:
 Per far terminare il programma, si usa l’istruzione return (seguita da un numero, in genere 0) collocata alla fine del blocco main
 Per utilizzare le funzioni di input/output (I/O) è necessario che all’inizio del file C sia indicato il nome del file di intestazione che le
descrive (stdio.h) con la direttiva #include:
#include <stdio.h>
main()
{
int A, B, S;
scanf("%d", &A);
scanf("%d", &B);
S = A + B;
printf("%d", S);
return 0;
}
 Sebbene non obbligatorio secondo lo standard, molti compilatori segnalano un errore se main non è preceduto da int
#include <stdio.h>
int main()
Miglioramento input
 Quando il programma parte, non informa l’utente di essere in attesa che egli introduca due valori da sommare
 E’ utile far precedere ciascuna scanf da un’istruzione printf che informi l’utente su che cosa egli debba fare:
printf("Introduci 1o valore: ");
scanf("%d", &A);
printf("Introduci 2o valore: ");
scanf("%d", &B);

IL PRIMO ESPERIMENTO:
Miglioramento output
 Il risultato del calcolo viene mostrato a video come semplice numero, ma è preferibile aggiungere una scritta che ne specifichi
il significato
 Si può aggiungere tale scritta tra le virgolette della stessa printfche visualizza S:
printf("La somma vale: %d", S);
Soluzione finale
#include <stdio.h>
int main()
{
int A, B, S;
printf("Primo valore? ");
scanf("%d", &A);
printf("Secondo valore? ");
scanf("%d", &B);
S = A + B;
printf("La somma vale: %d", S);
return 0;
}
/* LISTATO 1.5 Calcolo area rettangolo */
#include <stdio.h>
int base, altezza, area;
main()
{
printf("AREA RETTANGOLO\n\n");
printf("Valore base: ");
scanf("%d", &base);
printf("Valore altezza: ");
scanf("%d", &altezza);
area = base*altezza;
printf("Base: %d\n", base);
printf("Altezza: %d\n", altezza);
printf("Area: %d\n", area);
}
APPROFONDIMENTI printf
#define BASE 3
Grazie a questa istruzione, all’interno del programma potremo utilizzare BASE al posto del valore intero 3.
La definizione stessa di costante implica che il suo valore non può essere modificato: BASE può essere utilizzata
in un’espressione a patto che su di essa non venga mai effettuato un assegnamento.
Il programma del paragrafo precedente potrebbe quindi essere trasformato in quello del Listato 1.4
/* LISTATO 1.4: Calcolo area rettangolo, prova utilizzo
costanti */
#include <stdio.h>
#define BASE 3
#define ALTEZZA 7
main()
{
int area;
area = BASE * ALTEZZA;
printf("Base: %d\n", BASE);
printf("Altezza: %d\n", ALTEZZA);
printf("Area: %d\n", area);
}
Per fare in modo che il programma precedente calcoli l’area del
rettangolo con base 102 e altezza 34, è sufficiente modificare le
linee dov’è presente l’istruzione define:
#define BASE 102
#define ALTEZZA 34
Per lasciare una linea vuota si deve inserire un ulteriore \n nell’istruzione printf all’interno di doppi apici:
printf("AREA RETTANGOLO\n\n").
Il primo \n fa andare il cursore a linea nuova dopo la visualizzazione di AREA RETTANGOLO, il secondo \n
lo fa scorrere di un ulteriore linea.
se si vuole lasciare una linea prima della visualizzazione si fa precedere \n ad AREA RETTSANGOLO
printf("\nAREA RETTANGOLO\n\n\n");
E possibile inserire il salto in qualsiasi posizione all’interno dei doppi apici, come nel seguente esempio:
printf("AREA \nRET\nTAN\nGOLO");
che provoca in fase di esecuzione la visualizzazione:
AREA RET TAN GOLO
Si possono stampare più variabili con una sola printf, indicando prima tra doppi apici i formati in cui si
desiderano le visualizzazioni e successivamente i nomi delle rispettive variabili.
L’istruzione
printf("%d %d %d", base, altezza, area);
inserita alla fine del programma precedente stamperebbe, se i dati immessi dall’utente fossero ancora 10
e 13:
10 13 130
Per raffinare ulteriormente l’uscita di printf, si possono naturalmente inserire degli a capo a piacere:
printf("%d\n%d\n%d", base, altezza, area);
che hanno come effetto
10
13
130
All’interno dei doppi apici si possono scrivere i commenti che devono essere stampati. Per esempio, se la
visualizzazione della terza variabile deve essere preceduta da Area:, l’istruzione diventa la seguente:
printf("%d\n%d\nArea: %d", base, altezza, area);
10
13
Area: 130
Analogamente si può procedere con le altre variabili:
che darà in uscita
printf("Base: %d\nAltezza: %d\nArea: %d", base, altezza, area);
Si tratta dunque di inserire i vari messaggi che devono apparire sul video tra doppi apici, prima o dopo i simboli che
descrivono i formati degli oggetti da visualizzare.
Così come \n effettua un salto a linea nuova, la sequenza \t provoca l’avanzamento del cursore di uno spazio di
tabulazione:
printf("Base: %d\tAltezza: %d\tArea: %d", base, altezza, area); produce come uscita
E possibile inserire nella printf, al posto delle variabili, delle espressioni, di tipo specificato dal formato
10*13);
printf("Area: %d",
Il %d ci indica che il risultato dell’espressione è di tipo intero; l’istruzione stamperà 130. Un’espressione può
naturalmente contenere delle variabili: printf("Area: %d", base*altezza);
Si può definire all’interno di una istruzione printf anche il numero di caratteri riservati per la visualizzazione
di un valore, nel seguente modo:
printf("%5d%5d%5d", base, altezza, area);
Il %5d indica che verrà riservato un campo di cinque caratteri per la visualizzazione del corrispondente valore,
che sarà sistemato a cominciare dall’estrema destra di ogni campo:
Inserendo poi un carattere - dopo il simbolo di percentuale e prima della lunghezza del campo il valore viene
sistemato a cominciare dall’estrema sinistra della maschera.
L’istruzione printf("%-5d%-5d%5d", base, altezza, area);
Scrivere un programma che chieda di introdurre 3 numeri A, B e C dalla tastiera e successivamente visualizzi il risultato dei
seguenti calcoli:
1) A–B
2) A–B+C
3) A–B–C
2. Scrivere un programma che chieda due numeri e li memorizzi nelle variabili A e B. Il programma deve ora scambiare il contenuto di
A e di B (es. se inizialmente A contiene 12 e B 27, dopo lo scambio A contiene 27 e B 12).
#include <stdio.h>
int main()
{
int A, B, C, X, Y, Z;
printf("Primo valore? ");
scanf("%d", &A);
printf("Secondo valore? ");
scanf("%d", &B);
printf("Terzo valore? ");
scanf("%d", &C);
X = A-B;
printf("Risultato 1 = %d\n", X);
Y = A-B+C;
printf("Risultato 2 = %d\n", Y);
Z = A-B-C;
printf("Risultato 3 = %d\n", Z);
return 0;
}
#include <stdio.h>
int main()
{
int A, B, Temp;
printf("Primo valore? ");
scanf("%d", &A);
printf("Secondo valore? ");
scanf("%d", &B);
Temp = A;
A = B;
B = Temp;
printf("%d\n", A);
printf("%d\n", B);
return 0;
}

La soluzione con 2 variabili temporanee è
meno efficiente (usa una variabile in più
ed
esegue
un’operazione
di
assegnamento in più) e non è quindi
preferibile:
TempA = A;
TempB = B;
A = TempB;
B = TempA;
SEQUENZE DI ESCAPE
• le funzioni di output (come printf) hanno il compito di
stampare a video (o, a seconda dei casi, in uno specifico
stram) la STRINGA racchiusa tra parentesi tonde.
Una stringa è una sequenza di CARATTERI racchiusa tra
virgolette.
Si definiscono caratteri:
- lettere (a, X, é...)
- cifre (0, 1, 2...)
- simboli (+, £, *...)
- sequenze di escape (o di controllo)
In particolare, le sequenza di escape sono sequenze di
caratteri che provocano particolari comportamenti della
funzione printf. Ad esempio, la sequenza 'n' fa sì che il
cursore si posizioni nella posizione iniziale della riga
successiva dello schermo.
Riporto qui di seguito l'elenco completo delle sequenza di
escape
•
•
La programmazione per moduli: file HEADER
La scrittura delle funzioni all’interno dello stesso file che le richiama non consente ad altri file il loro utilizzo.
Per ovviare a questo inconveniente si sposta il codice della funzione in altro file: il file header.
Si tratta di file con estensione … .h.
ESEMPIO:funzione potenza()
In alternativa si può lasciare nel file header le direttive al preprocessore e la dichiarazione
dei prototipi delle funzioni, e spostare in altro file c la definizione delle funzioni.
ESEMPIO precedente:
LA PROGRAMMAZIONE IN LINGUAGGIO C
1. VARIABILI
2. DATI E COSTANTI
3. IMPUT E OUTPUT DI DATI
La
Tipi di dati di base
variabile è una porzione di memoria dove collocare il dato
In C esistono diversi tipi di variabili, che servono per rappresentare tipi di dato diversi, dai grossi numeri ai testi. Alcuni linguaggi permettono
la dichiarazione di variabili generiche, ma poter assegnare a ciascun dato il tipo di variabile adeguato, consente anche una migliore
gestione della memoria (alla fonte).
Nella tabella seguente sono mostrati i vari tipi, la parola chiave C che li identifica (char per carattere, int per intero, etc.), la tipologia di
informazioni che rappresentano ed il numero di byte necessari per la loro rappresentazione in C:
Specicatori di tipo delle variabili:
I void: tipo di dato indefinito, ovvero non specificato,
I char: rappresenta i caratteri nel set a disposizione sul calcolatore,
I int: rappresenta numeri interi,
I float: numeri in virgola mobile (decimali) a precisione singola,
I double: rappresenta numeri virgola mobile a precisione doppia.
Modicatori di tipo: modicano il range di valori ammissibili
per il tipo
I short: riduce il numero di valori memorizzabili,
I long: aumenta il numero di valori memorizzazabili,
I signed: il tipo di dato e dotato di segno,
I unsigned: il tipo di dato non e dotato di segno.
Modificatori
del tipo di accesso: const volatile
I
- una variabile di tipo const, e non può essere modificata dal
programma, ma gli si può assegnare un valore iniziale che sarà
mantenuto per tutta la durata dell'esecuzione del programma.
const int x = 5;
- Il modificatore volatile viene utilizzato per indicare al compilatore
che il valore di una variabile può essere modificato in modo non
esplicitamente specificato dal programma.
In C il char è considerato un intero per cui
int j
J = ‘A ‘+ ‘B2 ‘= IN ASCII = 65 + 66
I tipi di dati primari, eccetto il tipo void, ammettono dei modificatori di tipo. Tali
modificatori (signed, unsigned, long, short) sono impiegati per adattare con
maggiore precisione i tipi di dati fondamentali alle esigenze del programmatore
che influiscono sull’economia complessiva del programma (velocita,occupazione
di memoria, tempo di esecuzione)
Esempio
Si vogliono memorizzare 2 milioni di valori interi compresi tra 0 e 100. I valori sono compatibili (ossia nel range) di tutti i tipi di dati
visti, dai char (arrivano almeno fino a 127) ai long double, ad esempio si considerino le due soluzioni seguenti:
 si usa il tipo char: si occupano 2 MB e i calcoli sono veloci
 si usa il tipo double: si occupano 16 MB e i calcoli sono molto più lenti (senza alcun vantaggio rispetto al caso
precedente)





Inizializzazione delle variabili
L’assegnazione esplicita del valore iniziale alle variabili contestualmente alla definizione è detta inizializzazione
I valori usati per inizializzare possono essere espressioni che utilizzano variabili già inizializzate
int x = 12,
y = 27*3*x;
double pigreco = 4.0*atan(1.0);
atan = arctg
const double Pi = 3.141592653;
const double Pi = 4.0*atan(1.0);
const può essere messo prima o dopo il nome di tipo a cui si riferisce. const int x = 12; o int const x = 12;
ESEMPIO
/* Programma che acquisisce da tastiera due numeri, li somma e visualizza il risultato su monitor */
#include <stdio.h>
#include <stdlib.h> float
x, z;
int y;
int main()
{ printf(“\aInserisci un valore per la variabile x: ");
/* Con \a si fa emettere un beep */
scanf("%f", &x); /* funzione che acquisisce da tastiera un numero reale e lo pone all'indirizzo della variabile x. */
printf(“\aInserisci un valore per la variabile y: ");
scanf("%d", &y);
z = x + y;
printf(“La somma risulta z = x + y = %f", z);
system(“pause”);
}
CONVERSIONE di TIPO delle variabili
Il compilatore del C non esegue alcun controllo sul tipo dei dati: se si attribuisce un numero
reale ad una variabile intera si commette un errore che il compilatore non segnala.
Esempi:
int x = 2;
int x =
2.4;
in x viene correttamente caricato il valore 2
in x viene caricata solo la parte intera: 2; la parte decimale 4 non viene
presa in considerazione
float x = 2;
float x =
2.7;
in x viene correttamente caricato il valore 2
in x viene correttamente caricato il valore 2.7;
L’assenza di controllo sul tipo di dati può creare qualche problema in alcune operazioni aritmetiche.
Occorre tenere presente che il compilatore C opera sempre con la seguente sequenza:
• prima di eseguire l’operazione , esamina gli operandi, che devono essere dello stesso tipo, se
non lo sono converte il tipo minore nel tipo maggiore e solo dopo esegue l’operazione;
• il risultato dell’operazione è fornito con lo stesso tipo degli operandi.
Esempi:
int x = 3; float
y = 5.6; int
z = x + y;
Gli operandi sono di tipo diverso: il tipo minore (int) viene convertito
nel tipo maggiore(float), la somma si svolge quindi con due valori float,
il risultato però è caricato in una variabile tipo intero z, e ciò comporta
la perdita della parte decimale: in z risulta memorizzato il numero 8.
NB: Per risolvere il problema, la variabile z deve essere dichiarata float.
int x = 7;
int y = 2;
float z = x / y;
Gli operandi (x e y) sono dello stesso tipo: intero. Il compilatore C
fornisce il risultato come intero: 3 invece che 3.5 e nella variabile z, pur
essendo di tipo float, viene caricato il numero 3.
Per far si che la divisione fornisca il risultato con la virgola (tipo float), i
suoi operandi devono essere variabili (o numeri) reali.
NB: una possibile soluzione è la seguente: float z = (1.0 * x) / y;
prima si esegue la moltiplicazione, per cui il compilatore trasforma il contenuto della x da
valore intero a valore float (da 7 a 7.0) e fornisce il risultato come float (7.0);
successivamente deve essere eseguita una divisione tra un float e un int , per cui prima il valore
int (2) è convertito in float (2.0); il risultato (3.5) è quindi fornito come float e nella variabile z
viene correttamente memorizzato il valore 3.5.
In alternativa si deve operare una conversione esplicita in float di uno dei due operandi:
esempio:
float z = (float) x / y;
In questo caso: x è prima convertito in float e poi reso disponibile per la divisione.
NB: x è convertito in float solo per quella istruzione, nelle istruzioni successive resta int.
ESEMPIO: programma che esegue una divisione tra una costante tipo intero e una variabile tipo intero
#include <stdio.h>
#include <stdlib.h>
const x = 7;
/* la variabile x è dichiarata costante , cioè di sola lettura (solo per i tipi
int e char) il tentativo di modificarla provoca un messaggio di errore */
int y, z;
float w, q;
int main()
{ printf("Inserire un valore per y: ");
scanf("%d", &y);
z = x/y; w
= x/y;
q = (float)x/y;
/* float davanti alla costante x converte quest’ultima in variabile reale */
printf(“Risultati della divisione:\nz = %d \nw = %f
system(“pause”);
}
\nq = %f \n\n”, z, w, q);
Direttiva
#define
Con la direttiva #define si assegna un valore a un simbolo. Il preprocessore, nella fase
preliminare alla compilazione, sostituisce il simbolo presente nel codice della funzione main con il
valore assegnato.
La direttiva #define non occupa memoria.
Esempi di direttive #define:
#define MAX 20
NB: l’alternativa con const MAX = 20 avrebbe richiesto un impegno di memoria.
#define MAX 31.4 Definizione di costanti reali
#define x 24*1.5
Il simbolo x indica una moltiplicazione
#define messaggio printf(“Sistema pronto!”)
Il simbolo messaggio indica la visualizzazione di un testo
#define TEST0(x) printf(“\nValore di x: %d, x”)
#define avviso “Si è verificato un errore!”
#define pari(x)
x%2 == 0
Controllo sull’uguaglianza a zero di x ; ma è più sicuro scrivere: ((x)%2 == 0)
ESEMPIO : Applicazione di macro realizzate con la direttiva #define
#include <stdio.h>
#include <stdlib.h>
#define testo1 “Inserire un numero intero:
” carica(x) scanf(“%d”, &x)
#define
#define testo2(x) printf(“\nNumero inserito: x = %d\n”, x)
int a;
int main()
{ printf(testo1);
carica(a);
testo2(a);
system(“pause”); }
ESEMPIO: programma che utilizza la scrittura compatta degli operatori aritmetici
L’esecuzione del programma genera la seguente finestra:
OSSERVAZIONI
• Sono possibili assegnazioni multiple: x = y =9;
• Istruzione da evitare: x = x++; è indefinita e il programma smette di funzionare
• Gli operatori aritmetici (+, -, *, /) e di confronto hanno precedenza rispetto agli operatori logici
Il NOT logico ha precedenza rispetto all’AND logico, il quale ha precedenza rispetto all’OR logico
Approfondimenti: Enumerazioni

Un’enumerazione serve per definire una lista di identificatori aventi valori costanti di tipo int

Sintassi:









enum [nome] {cost1, cost2, ...};
enum boolean {FALSE, TRUE);
definisce le due costanti:
 FALSE (con valore 0)
I nomi delle costanti vengono in genere scritti in maiuscolo
Al primo identificatore viene assegnato il valore 0, al secondo identificatore 1, e così via
I valori delle costanti possono ripetersi, anche nella stessa numerazione
enum a {A=1, B=1, C=2, D=2, ecc.};
Costanti simboliche
E’ possibile dare un nome (un identificatore) ad una quantità costante, questo nome è detto simbolo (per convenzione in
maiuscolo)
Prima della compilazione, il preprocessore cerca i simboli definiti con direttive #define:
#define nome sequenza_di_caratteri
e sostituisce ogni occorrenza del simbolo nome con la corrispondente sequenza_di_caratteri
#define TRUE
1
Esempi
#define
#define
FALSE 0
DIM
80
Nell’esempio il preprocessore cerca ogni occorrenza di DIM e la sostituisce con 80 (i due caratteri 8 e 0), quindi una riga
di codice come la seguente:
int vett[DIM];
viene trasformata in:
int vett[80];
prima della compilazione vera e propria
Esercizi
Scrivere un programma che chieda 4 numeri double e ne calcoli la media (double) con 2 decimali.
2. Scrivere un programma che chieda un valore double e lo visualizzi con le 3 specifiche di conversione %f, %e e %g.
1.
#include <stdio.h>
int main()
{
double a, b, c, d;
double media;
printf("Primo valore: ");
scanf("%lf", &a);
printf("Secondo valore: ");
scanf("%lf", &b);
printf("Terzo valore: ");
scanf("%lf", &c);
printf("Quarto valore: ");
scanf("%lf", &d);
media = (a+b+c+d)/4;
printf("La media e': %.2f\n",
media);
return 0;
}
#include <stdio.h>
int main()
{
double x;
printf("Introduci un valore: ");
scanf("%lf", &x);
printf("Visualizzazione con %%f: %f\n",
x);
printf("Visualizzazione con %%e: %e\n",
x);
printf("Visualizzazione con %%g: %g\n",
x);
return 0;
}
Listato 1.6: programma completo che utilizza
la funzione abs().
/* LISTATO1.6: Esempio utilizzo di abs() */
#include <stdio.h>
#include <math.h>
main()
{
int a, b, segmento, lunghezza;
printf("\n\nLUNGHEZZA
SEGMENTO\n");
printf("Primo estremo: ");
scanf("%d", &a);
printf("Secondo estremo: ");
scanf("%d", &b);
segmento = a-b;
lunghezza = abs(segmento);
printf("Lunghezza
segmento:
lunghezza);
%d\n",
Un esempio di funzione C predefinita è
abs(i), che prende il nome da
absolute: se dopo la parola abs(),
all’interno delle parentesi tonde, viene
inserito un numero intero, la funzione
abs()
ne restituisce il
valore assoluto, che è quindi possibile
catturare assegnandolo a una variabile o
utilizzandolo
direttamente all’interno
di un’espressione.
Se quindi w e j sono variabili di tipo
intero, l’istruzione
w =
abs(j); assegna a w il valore
assoluto di j. All’interno delle parentesi
tonde può essere inserito direttamente un
valore, come nel caso
w = abs(3);
che assegna a w il valore 3, o come nel
caso
w = abs(-186); che assegna a w il
valore 186.
per poter utilizzare tale funzione si deve
dichiarare esplicitamente nel programma,
prima del main, l’inclusione del
riferimento a tale libreria.
#include <math.h>
math.h
Espressioni e funzioni matematiche
ESPRESSIONI NUMERICHE
somma
sottrazione
moltiplicazione
divisione
resto della divisione intera
+
*
/
%
Operatori unari: un solo operando


x
x
x
x
x
=
=
=
=
=
2
a + b;
a - b;
a * b;
a / b;
a % b;
La divisione tra interi produce risultato intero con
troncamento della parte frazionaria
Il resto può essere calcolato solo con operandi di
tipo intero (non floating-point)
Precedenza degli operatori
1

3

Le regole di precedenza (o priorità) specificano in
quale ordine vengono eseguiti i calcoli
Raggruppati in livelli di priorità decrescente:
1.
+ –
2. ()
3. * / %
4. + –

 segno
 somma e sottrazione
Esempi
x = a+b*c;
x = (a+b)*c;
x = a + -b;
 prima la moltiplicazione
 prima la somma
 a + (-b)
Operatori di assegnamento
La forma di assegnamento: variabile op= espressione essendo op un operatore del C, equivale a:
variabile = variabile op espressione x += 5;
equivale a x = x + 5;

Operatori ++ e ––

Incrementano/decrementano di 1 una variabile: ++a;
 ++a incrementa a di 1 prima che a venga utilizzata nel calcolo (incremento prefisso)
a++ incrementa a di 1 dopo che a è stata utilizzata nel calcolo (incremento postfisso)
 ––a e a–– decrementano a di 1
 Esempi:
a = 5;
x = ++a;
ora a vale 6 e x vale 6
a = 5;
x = a++;
ora a vale 6 e x vale 5
Funzioni matematiche




Richiedono che venga indicato il file di intestazione (header file) <math.h> che ne descrive la sintassi
Se i valori passati non sono di tipo double, vengono automaticamente promossi a tale tipo (per effetto del
prototipo <math.h>)
Le funzioni trigonometriche usano i radianti (180o =  rad)
Valori casuali



La funzione rand ogni volta che viene chiamata produce un diverso valore intero compreso tra 0 e RAND_MAX (estremi
inclusi) con distribuzione uniforme
x=rand()
Valori logici
Il valore 0 equivale a falso, Ogni valore 0 equivale a vero
Quindi nelle espressioni relazionali scrivere
!=0 è opzionale:
if (trovato) ... equivale a if (trovato != 0) ...
Operatori logici: Operatori (in ordine di priorità
decrescente):
NOT, ha priorità superiore agli operatori relazionali e
aritmetici If( !(a>b) )...
AND, ha priorità inferiore agli operatori relazionali e
Espressioni logiche:Si possono usare le parentesi
per cambiare l’ordine di valutazione delle operazioni
aritmetici if ( a>b && c!=0 ) ...
OR, ha priorità inferiore agli operatori relazionali e
aritmetici if ( a>b || c!=0 ) ...

Esempi
if ( a>b || c<d && a!=0 ) ... equivale a:


if (trovato == 0)
... equivale a:

e quindi, essendo il !=0 sopprimibile, a:
if ( a>b ||
(c<d && a!=0) ) ...
if ( !(trovato != 0) )... Il valore 0 equivale a falso,
Ogni valore 0 equivale a vero
if (!trovato)...
Attenzione: è errato scrivere una condizione come a < b < c, occorre spezzarla come a<b && b<c
Valutazione minima di && e ||


Gli operatori &&e ||vengono valutati sempre da sinistra a destra
La valutazione delle espressioni termina non appena è possibile
stabilire se la condizione è complessivamente vera o falsa:

if (cond1 && cond2 && cond3 && ...) ...
Se cond1 è falsa (0), non si valutano le condx successive e complessivamente la condizione dà 0 (falso)
if (cond1 || cond2 || cond3 || ...) ...
Se cond1 è vera (!=0), non si valutano le condx successive e complessivamente la condizione dà 1 (vero)

Espressioni relazionali

Confrontano due valori, I valori possono essere espressioni

Se il risultato è vero danno risultato 1 (non un generico valore diverso da 0), se falso danno 0


Operatori: ==  uguale
!=  diverso
maggiore
>=  maggiore o uguale
<
Hanno priorità inferiore alle operazioni aritmetiche
prima calcola le espression
i
a-5e 12*x
poi
 minore
if (a-5 >= 12*x)...
ne fa il confronto

Hanno priorità maggiore degli operatori di assegnamento

x = 5 > 2;
prima fa il confronto tra 5 e 2 poi

<=  minore o uguale
ne assegna il risultato
int x;
a x
>

Scrivere un programma che chieda 4 numeri int, ne calcoli la media,
la memorizzi in una variabile float e la visualizzi con 2 decimali.
1.
Scrivere un programma che chieda un valore double di temperatura in
gradi Fahrenheit e calcoli i valori delle corrispondenti temperature in
gradi Celsius e Kelvin (entrambi con parte frazionaria).C  5/9 *(F 32), K
 C  273.15
#include <stdio.h>
int main()
{
double f, c, k;
printf("Temperatura in gradi Fahrenheit: ");
scanf("%lf", &f);
c = 5.0/9.0 * (f-32);
k = c + 273.15;
printf("Celsius: %f\nKelvin: %f\n", c, k);
return 0;
}
/* Considerazioni: c = 5/9 * (f-32);
da' sempre 0 perche' 5 e 9 sono interi e la divisione tra
interi da' risultato intero con troncamento (appunto 0)
c = (f-32) * 5/9; con il float il risultato ò è corretto,*/
#include <stdio.h>
int main()
{
int a, b, c, d;
float media;
printf("Primo valore: ");
scanf("%d", &a);
printf("Secondo valore: ");
scanf("%d", &b);
printf("Terzo valore: ");
scanf("%d", &c);
printf("Quarto valore: ");
scanf("%d", &d);
media = (a+b+c+d)/4.0F;
printf("La media e': %.2f\n", media);
return 0;
}
/* Considerazioni: media = (a+b+c+d)/4.0; media = (float)(a+b+c+d)/4;
media = (float)(a+b+c+d)/4.0F; media = ((float)a+b+c+d)/4; */
IL CONTROLLO DI FLUSSO
STRUTTURE
Il C è un linguaggio di programmazione strutturato, nel senso che il flusso delle operazioni da
eseguire è gestito mediante strutture, tra le quali molto importanti sono:
Strutture SELETTIVE:
• IF … ELSE
• SWITCH
Strutture ITERATIVE (RICORSIVE):
• Ciclo WHILE
• Ciclo FOR
18
Struttura IF … ELSE
Quando l’esecuzione di un certo codice è subordinata a una condizione, si ricorre alla struttura
else. La struttura può essere utilizzata in più modi:
if (condizione)
{
………
Se la condizione è vera viene eseguito il codice compreso tra le parentesi graffe
}
ESEMPIO:
programma che esegue un controllo rispetto a una soglia
#include <stdio.h>
#include <stdlib.h>
const soglia = 10; /* la variabile soglia è dichiarata costante , cioè di sola lettura; il tentativo di
modificarla provoca un messaggio di errore */
int y;
int main()
{ printf("Inserire un valore per y: ");
scanf("%d", &y);
if(y > soglia)
{ printf("Valore non valido. Supera quello della soglia! \n"); }
system(“pause”);
}
if …
Struttura alternativa
if (condizione)
Se la condizione è vera si esegue il codice immediatamente seguente
{
………
altrimenti si esegue il codice che segue ‘else’
}
else
{
………
}
ESEMPIO: programma che verifica un valore rispetto a una soglia.
#include <stdio.h>
#include <stdlib.h> int soglia = 10, y;
int main()
{ printf("Inserire un valore per y: "); }
scanf("%d", &y);
if(y > soglia)
{ printf("Valore non valido. Supera quello della soglia!"
}
else
{ printf("Valore valido.");
}
system(“pause”);
}
Struttura alternativa
Struttura alternativa
if (condizione1)
………
{
}
ESEMPIO: programma che esegue un controllo con più condizioni else if (condizione2)
{………
}
#include <stdio.h>
#include <stdlib.h> int main(){
if (condizione1)
{
………
}
else if (condizione2)
{
………
}
else
………
{
}
unsigned int y;
printf("Inserire un valore intero per y: "); scanf("%d", &y);
if(y < 6 && y >= 1)
/* per maggiore chiarezza: if((y < 6) && (y >= 1)) */
{printf("Profitto INSUFFICIENTE!\n"); }
else if (y == 6)
{printf("Profitto SUFFICIENTE!\n"); }
else if (y >=7 && y <= 10)
{printf(“AVANTI COSI!\n"); }
else
{printf(“Valore al di fuori del range consentito!\n"); }
system(“pause”);
}
ESERCIZIO:
scrivere un programma che acquisisce due
numeri interi da tastiera se entrambi maggiori di 13, calcola e
visualizza la media aritmetica altrimenti individua e visualizza
il numero maggiore
ALGORITMO
ALGORITMO: Sequenza di passi per ottenere la
soluzione di un problema o classe di problemi.
Introduzione
La scrittura di un programma non deve avvenire di getto, perché bisogna sempre approfondire prima la
problematica che il programma deve risolvere.
In generale la risoluzione di un generico problema mediante l’uso del calcolatore passa per tre fasi
fondamentali:
• Analisi del problema
• definizione completa del problema
• ricerca di eventuali algoritmi già esistenti
• individuazione delle variabili (ingresso, intermedie, uscita)
• valutazione dell’opportunità di ricorrere al calcolatore
• Definizione dell’algoritmo per la soluzione automatica
L’algoritmo deve contemplare tutti i casi che con i dati di ingresso possono presentarsi.
Un modo comodo e chiaro per descrivere la sequenza di passi che costituiscono l’algoritmo è dato
dai
diagrammi di flusso (flow charts).
NB: possono esistere più algoritmi che risolvono lo stesso problema, ma con efficienza diversa.
• Implementazione dell’algoritmo su calcolatore
Consiste nella traduzione di un algoritmo in sequenza di istruzioni appartenenti a un determinato
linguaggio di programmazione.
ESECUZIONE CONDIZIONALE
Le selezioni condizionali permettono di decidere l’attivazione di parti (diverse) di codice, in base al valore di un’espressione
Costrutto if-else
Costrutto if




Permette l’esecuzione di un blocco di
codice solo se si verifica una certa
Il flow-chart corrispondente è:
Selezione a più rami
condizione
SE (condizione è vera)
ALLORA esegui istruzioni
// maggiore fra due
numeri
#include <stdio.h>
int main()
{
int a, b;
scanf("%d",&a);
scanf("%d",&b);
Esempio
if (a > b)
Programma che chiede un numero e
printf("%d",a);
se è positivo scrive “positivo”
altrimenti nulla.
else
scanf("%d",&n);
printf("%d",b);
if (n > 0)
return 0;
{
printf("positivo\n");
}
}
scanf("%d", &n);
if (n > 0)
printf("positivo\n");
else
if (n < 0)
printf("negativo\n");
Costrutto
if interno
else
printf("nullo\n");
printf("FINE\n");
Quando n > 0 non valuta l’altro controllo
I blocchi di istruzioniQualsiasi istruzione può essere sostituita
da un blocco di istruzioni
Un blocco di istruzioni deve essere contenuto all’interno di
parentesi graffe: il corpo di una funzione è un caso particolare
di blocco di istruzioni
 Per eseguire in modo condizionale
più di una singola istruzione è (necessario e) sufficiente
racchiudere l’insieme di istruzioni in un blocco
LISTATO N. 3
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
main()
{
double num;
printf("introdurre un numero non negativo: ");
scanf("%lf", &num);
/* Lo specificatore %lf indica un tipo double */
if (num<0)
printf("errore nei dati di ingresso: il numero è negativo.
\n");
else
printf("la radice quadrata è:%f \n", sqrt(num));
printf("il quadrarto di %lf è: %lf \n", num, num*num);
printf("il cubo di %lf è: %lf \n", num, num*num*num);
exit(0);
}
Scrivere un programma che legge un carattere,
stampandolo se è una lettera dell’alfabeto, ignorandolo in
caso contrario
Note:
Esiste la funzione di libreria isalpha() che restituisce un valore
diverso da 0 se l’argomento è una lettera dell’alfabeto
L’uso di una chiamata di funzione come espressione condizionale
è comune in C
LISTATO N. 2
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> /* incluso per la funzione
isalpha */
main()
{
char ch;
printf("introdurre un carattere: ");
scanf("%c", &ch);
if (isalpha(ch))
printf("%c", ch);
else
printf("%c non è un carattere alfabetico|n", ch);
exit(0);
}
ISTRUZIONI IF INNESTATE
• Una singola istruzione if permette al programma di scegliere fra due alternative. Talvolta è necessario specificare
alternative successive: dopo aver preso la decisione_1, è necessario valutare la decisione_2, la decisione_3, etc.
• Questa tipologia di controllo del flusso richiede un costrutto if innestato (o annidato)
• Esempio ealizzare una funzione che, dati tre interi, ne determina il massimo/minimo
• Nelle istruzioni if annidate sorge il problema di far corrispondere ad ogni clausola else l’opportuna istruzione if
• Regola: Una clausola else viene sempre associata all’istruzione if più vicina fra quelle precedenti  ad ogni
istruzione if può corrispondere una sola clausola else
• Per facilitare la programmazione, è opportuno indentare correttamente i vari if:
Una clausola else dovrebbe sempre essere posta allo stesso livello di indentazione dell’if associato
#include <stdio.h>
int main()
{
int a, b, c;
scanf("%d%d%d",&a,&b,&c);
if (a > b)
if (a > c)
printf("%d",a);
else
printf("%d",c);
else
if (b > c)
printf("%d",b);
else
printf("%d",c);
return 0; }
int min(a, b, c)
int a, b, c;
{
if (a<b)
if (a<c)
return a;
else
return c;
else if (b<c)
return b;
else
return c;
}
/* LISTATO 4: CALCOLA LE RADICI DI UN'EQUAZIONE DI SECONDO GRADO. */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float a, b, c, delta;
printf ("scrivi a, b, c: ");
scanf ("%f %f %f", &a, &b, &c);
delta = b*b - 4*a*c;
if (delta == 0)
{
/* radici coincidenti */
printf ("radici coincidenti: x0 = x1 = %f", -b/(2*a));
}
else
{
if (delta > 0) {
/* radici reali distinte */
printf ("radici reali distinte: x0 = %f, x1 = %f",
(-b + sqrt (delta))/(2*a), (-b - sqrt (delta))/(2*a));
}
else {
/* radici complesse */
printf ("radici complesse coniugate: \n"
"parte reale = %f, parte immaginaria = +/- %f",
-b/(2*a), sqrt (-delta)/(2*a));
} }
return EXIT_SUCCESS;
}
/*Scrivere un programma che richiesto all'utente un
numero intero stabilisca se e' pari o dispari.
Suggerimento: l’operatore modulo, x%y, restituisce il
resto della divisione intera di x per y */
#include <stdio.h>
main()
{
int a;
printf("inserisci numero:");scanf("%d",&a);
if (a%2==0)
printf("numero pari");
else
printf("numero dispari");
getchar();
}
Scrivere un programma che chieda
due numeri da tastiera e dei due
visualizzi il maggiore
#include <stdio.h>
int main()
{
double a, b;
printf("Introduci il primo valore:
");
scanf("%lf", &a);
printf("Introduci il secondo valore:
");
scanf("%lf", &b);
if (a >= b) /* oppure solo > */
printf("%f\n", a);
else
printf("%f\n", b);
return 0;
}
Scrivere un programma che chieda un numero da
tastiera e stampi sul video se è pari o dispari
(consiglio: calcolare il resto).
#include <stdio.h>
int main()
{
int a;
printf("Introduci il valore:
");
scanf("%d", &a);
if (a % 2 == 0)
printf("Pari\n");
else
printf("Dispari\n");
return 0;
}
Scrivere un programma che chieda tre numeri da
tastiera e li stampi in ordine decrescente.
#include <stdio.h>
int main()
{ double a, b, c;
printf("Introduci il primo valore: ");
scanf("%lf", &a);
printf("Introduci il secondo valore: ");
scanf("%lf", &b);
printf("Introduci il terzo valore: ");
scanf("%lf", &c);
if (a > b && a > c) /* verifica se a e' > di entrambi */
if (b > c)
printf("%f %f %f\n", a, b, c);
else printf("%f %f %f\n", a, c, b);
else if (b > c) /* a non e' il piu' grande, o e' b o e' c */
if (a > c)
printf("%f %f %f\n", b, a, c);
else printf("%f %f %f\n", b, c, a);
else
/* non puo' che essere c */
if (a > b)
printf("%f %f %f\n", c, a, b);
else printf("%f %f %f\n", c, b, a);
return 0; }
. Si vogliono dividere gli allievi di un corso in tre squadre denominate
ROSSA, VERDE e BLU secondo il loro numero di matricola. L’assegnazione
avviene con il seguente criterio: l’allievo con matricola 1 va nella squadra
ROSSA, quello con matricola 2 nella VERDE, quello con matricola 3 nella
BLU, quello con matricola 4 nella ROSSA, quello con 5 nella VERDE ecc.
Il programma deve chiedere il numero di matricola dell’allievo e
indicare a quale squadra è assegnato. Usare il costrutto if.
#include <stdio.h>
int main()
{
int matricola;
printf("Introduci il numero di matricola:
");
scanf("%d", &matricola);
if (matricola % 3 == 1)
printf("ROSSA\n");
else if (matricola % 3 == 2)
printf("VERDE\n");
else
printf("BLU\n");
return 0;
}
. Scrivere un programma che chieda da tastiera
di introdurre un numero intero corrispondente
ad
un
voto
e
stampi
a
video
“Insufficiente” se è inferiore a 18,
“Appena sufficiente” (18),
“Basso” (19-20),
“Medio” (21-23),
“Buono” (24-26),
“Alto” (27-29),
“Massimo”
(30)
“Impossibile” (tutti gli altri)
#include <stdio.h>
int main()
{
int voto;
printf("Introduci il voto: ");
scanf("%d", &voto);
if (voto <= 0)
printf("Impossibile\n");
else if (voto < 18)
printf("Insufficiente\n");
else if (voto == 18)
printf("Appena sufficiente\n");
else if (voto <= 20)
/* inutile scrivere
anche voto > 18 */
printf("Basso\n");
else if (voto <= 23)
printf("Medio\n");
else if (voto <= 26)
printf("Buono\n");
else if (voto <= 29)
printf("Alto\n");
else if (voto == 30)
printf("Massimo\n");
else
printf("Impossibile\n");
return 0;
}
#include <stdio.h>
int main()
{
char l;
printf("MENU DI PROVA\n");
printf("a) Per immettere dati\n");
printf("b) Per determinare il maggiore\n");
printf("c) Per determinare il minore\n");
printf("d) Per ordinare\n");
printf("e) Per visualizzare\n");
printf("Scelta: ");
scanf("%c",&l);
fflush(stdin);
switch(l)
{
case ('a'):
{
printf("\nIn esecuzione l'opzione a");
break;
}
case ('b'):
{
printf("\nIn esecuzione l'opzione b");
break;
}
case ('c'):
{
printf("\nIn esecuzione l'opzione c");
break;
}
case ('d'):
{
printf("\nIn esecuzione l'opzione d");
break;
}
L’istruzione switch
case ('e'):
{
printf("\nIn esecuzione l'opzione
e");
break;
}
default:
{
printf("\nOpzione inesistente!");
break;
}
}
getchar();
}
#include <stdio.h>
int main() {
int cost;
char c;
printf("Inserisci il costo del biglietto\n");
scanf("%d",&cost);
fflush(stdin);
printf("Inserisci la tua eventuale condizione particolare:\n");
printf("1.'S'tudente\n2.'P'ensionato\n3.'D'isoccupato\n4.'N'essumo di
questi\n");
scanf("%c",&c);
fflush(stdin);
switch(c) {
case 'S':
printf("L'importo da pagare e' %d",cost-((cost*15)/100));
break;
case 'P':
printf("L'importo da pagare e' %d",cost-((cost*10)/100));
break;
case 'D':
printf("L'importo da pagare e' %d",cost-((cost*25)/100));
break;
default:
printf("L'importo da pagare e' %d",cost);
break;
}
getchar(); }
Su una linea ferroviaria, rispetto alla tariffa piena,
gli utenti pensionati usufruiscono di uno sconto del
10%, gli studenti del 15% e i disoccupati del 25%.
Codificando i pensionati con P, gli studenti con una
S e i disoccupati con una D, scrivere un
programma che richiesto il costo di un biglietto e
l'eventuale condizione particolare dell'utente,
visualizzi
l'importo
da
pagare.
Si vogliono dividere gli allievi di un corso in tre squadre denominate ROSSA,
VERDE e BLU secondo il loro numero di matricola. L’assegnazione avviene
con il seguente criterio: l’allievo con matricola 1 va nella squadra ROSSA,
quello con matricola 2 nella VERDE, quello con matricola 3 nella BLU,
quello con matricola 4 nella ROSSA, quello con 5 nella VERDE
#include <stdio.h>
int main()
{
int matricola;
printf("Introduci il numero di matricola: ");
scanf("%d", &matricola);
switch (matricola % 3)
{
case 1:
printf("ROSSA\n");
break;
case 2:
printf("VERDE\n");
break;
default:
printf("BLU\n");
break;
}
return 0; }
. Scrivere un programma che chieda da tastiera di introdurre un numero intero corrispondente ad
un voto e stampi a video “Insufficiente” se è inferiore a 18, “Appena sufficiente” (18)
“Basso” (19-20), “Medio” (21-23), “Buono” (24-26), “Alto” (27-29), “Massimo” (30)
“Impossibile” (tutti gli altri)
#include <stdio.h>
int main()
{ int voto;
printf("Introduci il voto: ");
scanf("%d", &voto);
switch (voto)
{
case 18:
printf("Appena sufficiente\n");
break;
case 19: case 20:
printf("Basso\n");
break;
case 21:
case 22:
case 23:
printf("Medio\n");
break;
case 24:
case 25:
case 26:
printf("Buono\n");
break;
case 27:
case 28:
case 29:
printf("Alto\n");
break;
case 30:
printf("Massimo\n");
break;
default:
if (voto > 0 && voto < 18)
printf("Insufficiente\n");
else
printf("Impossibile\n"); break;
return 0; }
STRUTTURE ITERATIVE
Ciclo WHILE


Fa eseguire un blocco di codice fintanto
ché una certa condizione è vera
Valuta la condizione prima di
eseguire il blocco
Ciclo FOR

Ciclo DO-WHILE
Il flow-chart corrispondente è il
seguente:


Fa eseguire un blocco di codice fintanto ché
una certa condizione è vera
Valuta la condizione dopo aver eseguito il
blocco


Se la condizione è inizialmente falsa,
il blocco non viene eseguito neppure
una volta
somma = 0;
scanf("%d", &v);
while (v != 0)
{
somma += v;
scanf("%d", &v);
}
printf("Somma:%d", somma);
ciclo FOR:
for (i=0; i<=1000; i++)
printf("%d", i);
fino a quando i, che viene
via via incrementata, è
minore o uguale a 1000 viene
stampata la variabile i
Anche se la condizione è inizialmente falsa,
il blocco viene eseguito almeno una volta
somma = 0;
do
{
scanf("%d", &v);
somma += v;
}while (v != 0);
ESEMPI ITERATIVI: CICLO FOR
Scrivere un programma che calcoli la
media (con parte frazionaria) di 100
valori introdotti dalla tastiera.
.
#include <stdio.h>
#define N 100
int main()
{
int v, somma;
int i;
somma = 0;
for (i=1; i<=N; i++)
{
printf("Inserire il %do valore: ", i);
scanf("%d", &v);
somma += v;
}
printf("Media: %f\n",
(double)somma/N);
return 0;
}
. Scrivere un programma che chieda
quanti
siano i valori che verranno
introdotti dalla tastiera, li chieda tutti e
ne stampi la somma e la media.
#include <stdio.h>
int main()
{
int v, somma;
int i, n;
somma = 0;
printf("Quanti valori? ");
scanf("%d", &n);
for (i=1; i<=n; i++)
{
printf("Inserire il %do valore: ", i);
scanf("%d", &v);
somma += v;
}
printf("Somma: %d\n", somma);
printf("Media: %f\n", (double)somma/n);
return 0;
}
ESEMPI ITERATIVI: CICLO FOR
Scrivere un programma che richieda N numeri da
tastiera e ne calcoli il valore massimo
#include <stdio.h>
int main()
{
int v, max;
int i, n;
printf("Quanti? ");
scanf("%d", &n);
Scrivere un programma che calcola i primi N numeri di Fibonacci,
con N introdotto dalla tastiera. I numeri di Fibonacci sono una
sequenza di valori interi che inizia con i due valori fissi 1 e 1 e
ogni successivo valore è la somma dei due precedenti.
Ad esempio i primi 10 numeri di Fibonacci sono: 1 1 2 3 5 8
13 21 34 55.
#include<stdio.h>
int main()
{
int i, n;
double a, b, c;
printf("Inserire il 1o valore: "); /* chiede il primo valore
*/
scanf("%d", &v);
max = v;
/* il primo valore e' anche l'attuale max */
for (i=1; i<n; i++) /* parte da 1 e non da 0 perche' il
primo */
{
/* e' gia' stato letto */
printf("Inserire il %do valore: ", i+1);
scanf("%d", &v);
if (v>max)
max = v;
}
printf("Massimo: %d\n", max);
/* tipi con ampio range */
printf("Quanti numeri? ");
scanf("%d", &n);
a = 1;
b = 1;
for (i=0; i<n; i++)
{
c = a + b;
printf("%.0f ", a);
a = b;
b = c;
}
printf("\n");
return 0;
}
return 0;
}
Esempi iterativi: ciclo for
/*Scrivere un programma che richiesto all'utente
/*Scrivere un programma che visualizzi * un numero m calcoli la somma dei primi m
il quadrato dei primi 24 numeri
elementi
naturali*/
* della serie armonica (1/k, per k che va da 1 a
#include <stdio.h>
#define DIM 24
main()
{
int i;
for(i=1;i<=24;i++)
printf("%3d al quadrato:
%3d\n",i,i*i);
getchar();
}
m)*/
#include <stdio.h>
int main()
{
int m;
float k,S=0.0;
printf("m: ");
scanf("%d",&m);
fflush(stdin);
for(k=1;k<=m;k++)
S=S+1/k;
printf("sommatoria: %f",S);
getchar();
}
ESEMPI ITERATIVI: WHILE
Si scriva un programma che calcoli il fattoriale di un numero
intero N dato dalla tastiera. Si ricordi che il fattoriale di un
numero n (simbolo n!) viene calcolato con la seguente
formula:
n! = n ·(n–1)·(n–2)· ... ·2 ·1.
fibonacci
#include<stdio.h>
int main()
{
double n, a, b, c;
range, anche n */
printf("Massimo numero? ");
scanf("%lf", &n);
#include<stdio.h>
int main()
{
int n;
double fatt;
a = 1;
b = 1;
if (n>=1)
printf("1 1 ");
c = a + b;
while (c<=n)
{
printf("%.0f ", c);
a = b;
b = c;
c = a + b;
}
printf("\n");
printf("Numero di cui calcolare il fattoriale: ");
scanf("%d", &n);
fatt = 1;
while (n>0) /* n>1 e' ancora meglio: inutile molt. per 1
*/
fatt *= n--;
printf("Fattoriale: %.0f\n", fatt);
return 0;
}
/* tipi con ampio
return 0;
}
Esempi iterativi: while
#include <stdio.h>
int main() {
int n, m, n1, m1; printf("Inserisci due numeri naturali : ");
scanf("%d%d", &n, &m);
n1 = n; m1 = m;
while (n1 != m1) {
if (n1 < m1)
m1 = m1 - n1;
else
n1 = n1 - m1; }
printf("Il massimo comun divisore con il metodo euclideo tra %d e %d e' %d\n", n, m, n1);
return 0; }
#include <stdio.h>
int main()
{
int n, m, t;
printf("Inserisci due numeri naturali : ");
scanf("%d%d",&n,&m);
if (n < m)
t = n;
else
t = m;
while (n % t != 0 || m % t != 0)
t = t - 1;
printf("Il massimo comun divisore tra %d e %d e' %d\n", n, m, t); return 0;
}
ESEMPI ITERATIVI_ DO WHILE
Si scriva un programma dove il calcolatore determini casualmente un numero intero
compreso tra 0 e 99 e chieda all’utente di trovare il numero stesso. Ad ogni input
dell’utente il calcolatore risponde con “troppo alto” o “troppo basso”, finché non
viene trovato il valore corretto. Per generare valori casuali si utilizza la funzione
rand.
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define MAXVAL 99
int main()
{
int x, v;
srand(time(NULL));
x = rand() % (MAXVAL+1);
do
{
printf("Introduci un valore intero tra 0 e %d: ", MAXVAL);
scanf("%d", &v);
if (v<x)
printf("Troppo basso!\n");
else if (v>x)
printf("Troppo alto!\n");
}while(x!=v);
printf("Trovato!\n");
return 0;
}
// FATTORIALE
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i;
long int nfatt;
printf ("inserisci n: ");
scanf ("%d", &n);
i = 1;
nfatt = 1;
while (i <= n)
{
nfatt = nfatt * i;
i++;
}
printf ("n! = %ld", nfatt);
return EXIT_SUCCESS;
}
getchar() legge dati il cui tipo non è noto a priori e li fornisce sotto forma di char
Quando getchar() raggiunge la fine del file, viene restituito un valore speciale, detto EOF: un nome costante,
definito in stdio.h, che solitamente vale 1
In questo caso, il carattere di fine stringa è \n
#include <stdio.h>
#include <stdlib.h>
/* Conta il numero di spazi contenuti in una stringa
* immessa da terminale */
int main()
{
int ch, numerispazi=0;
printf("introdurre una frase:\n");
ch = getchar();
while(ch!='\n')
{
if(ch==' ')
numerispazi++;
ch = getchar();
}
printf("il numero di spazi è: %d\n",
numerispazi);
#include <stdio.h>
#include <stdlib.h>
/* Conta il numero di spazi contenuti in una stringa
* immessa da terminale */
int main()
{
int ch, numerispazi=0;
printf("introdurre una frase:\n");
ch = getchar();
do {
ch = getchar();
if(ch==' ')
numerispazi++;
ch = getchar();
}
while(ch!='\n');
printf("il numero di spazi è: %d\n", numerispazi);
exit(0);
}
exit(0);
}
I CICLI INNESTATI
• I costrutti iterativi possono essere innestati
a qualunque livello di profondità
• Il ciclo di livello nesimo deve terminare la
propria esecuzione prima che il ciclo al
livello n1 possa riprendere l’iterazione
Lo specificatore di formato %5d forza la
funzione printf() a stampare 5 caratteri
per ogni intero: se il numero richiede
meno di 5 caratteri, viene preceduto da un
numero appropriato di spazi bianchi
#include <stdio.h>
#include <stdlib.h>
/* Stampa una tavola pitagorica mediante cicli
innestati */
int main()
{
int j, k;
printf(" 1 2 3 4 5 6 7 8 9 10\n");
printf("________________________________\n");
for(j=1; j<=10;j++)
{
printf("%5d|",j);
for(k=1; k<=10;k++)
printf("%5d",j*k);
printf("\n");
}
exit(0); }
Le istruzioni break e continue, goto
Le istruzioni break devono essere evitate, quando possibile: producono salti (incondizionati) e rendono il programma di difficile lettura e
comprensione
L’istruzione continue deve essere evitata, quando possibile, perché, come break, altera il flusso di controllo naturale (attraverso un
salto incondizionato
È possibile scrivere cicli con modalità alternative, che non prevedono l’uso di break; break è invece “insostituibile” nel caso di switch
L’istruzione goto ha lo scopo di trasferire il controllo del flusso in un punto particolare, identificato da un’etichetta o label
La label è un nome seguito da “:” e deve essere contenuta nella stessa funzione che contiene il goto che vi fa riferimento
Il goto deve essere
usato solo quando il codice risultante guadagna in efficienza senza perdere troppo in leggibilità
VETTORI
VETTORI
Lavorando con una variabile semplice, ad ogni ripetizione del ciclo il nuovo valore viene sovrascritto sul vecchio,
perdendolo definitivamente. E’ possibile conservare i valori precedenti ricorrendo ai vettori.
I vettori sono un insieme di numeri, ordinato. Ciascun elemento del vettore è individuato da un proprio indirizzo. Il primo
elemento del vettore ha indirizzo 0.
Codice C :
Esempio: il numero 21 risulta essere il 4° elemento (indirizzo 3) del vettore y.
Per utilizzare gli elementi del vettore nelle operazioni è sufficiente richiamarli nel modo
seguente: Esempio: per disporre del valore del 5° elemento del vettore si deve scrivere:
x[4].
NB: I vettori sono molto utili quando si deve memorizzare una grande quantità di numeri.
Memorizzando i numeri in un vettore è possibile utilizzarli per elaborazioni successive col vantaggio di
poter usufruire della struttura dei cicli.
FUNZIONI
Quando si hanno sequenze di istruzioni che possono
• ripetersi nello stesso programma, o
• essere comuni a più programmi
conviene isolare tale codice e identificarlo come sottoprogramma.
In C ciò si realizza mediante la scrittura di funzioni. La sintassi è la seguente:
NomeFunzione (parametri)
{ ………………….
codice
…………………
}
Le variabili si distinguono in globali e locali.
Le variabili globali (dichiarate nella sezione dichiarativa del programma):
• se non definite, sono inizializzate a zero
• possono essere lette e modificate da tutte le funzioni
• conservano il valore, eventualmente modificato, fino al termine del programma.
Le variabili locali (dichiarate all’interno delle funzioni):
• se non definite, hanno inizialmente valore incerto
• possono essere lette e modificate solo all’interno della funzione in cui sono dichiarate
• al termine dell’esecuzione della funzione il loro valore non è più disponibile (se non indicate in return).
•
ESEMPIO: funzione potenza()
NB
E’ possibile indicare con uno stesso nome sia una variabile globale che una locale: non vi è pericolo di
interferenza in quanto quella locale maschera, all’interno della funzione in cui è dichiarata, quella
globale e la funzione lavora con la sola variabile locale.
programma precedente non fornisce una risposta corretta nel caso in cui
•
sia la base che l’esponente sono uguali a zero
•
l’esponente è negativo
Una possibile correzione è la seguente:
Il
In alternativa si può inserire tutto il codice di controllo nella funzione potenza():
ESEMPIO:
funzione CaricaVettore()
Array
Un vettore è una struttura di dati composta da un numero determinato di elementi tutti dello stesso tipo, ognuno
dei quali è individuato da un indice specifico. I vettori si dicono variabili strutturate mentre all’opposto tutte le
variabili semplici siano anche dette non strutturate. Il tipo dei dati contenuti nel vettore viene detto tipo del vettore,
ovvero si dice che il vettore è di quel particolare tipo.
Dunque per il vettore, come per qualsiasi altra variabile, devono essere definiti il nome e il tipo; inoltre si
deve esplicitarne la lunghezza, cioè il numero di elementi che lo compongono.
Una scrittura possibile è perciò la seguente:
int a[6];
Come sempre in C, prima deve essere dichiarato il tipo (nell’esempio int), poi il nome della variabile (a),
successivamente tra parentesi quadre il numero degli elementi (6) che dev’essere un intero positivo. Questa
dichiarazione permette di riservare in memoria centrale uno spazio strutturato come in Figura
Per accedere a un singolo elemento di a si deve specificare il nome del vettore seguito dall’indice dell’elemento
posto tra parentesi quadre. L’array a è composto da sei elementi e l’indice può quindi assumere i valori: 0, 1, 2, 3, 4,
e 5
Le istruzioni a[0] = 71;
a[1] = 4; assegnano al primo elemento del vettore a il valore 71 e al secondo 4.
Se b è una variabile intera (cioè dello stesso tipo del vettore), è possibile assegnare il suo valore a un elemento di a
e viceversa:
a[3] = b;
In generale un singolo elemento dell’array può essere utilizzato esattamente come una variabile semplice.
Nell’espressione
b = b + a[0] * a[5];
il valore di b è sommato al prodotto tra il primo e il sesto elemento di a e il risultato è assegnato a b.
Spesso l’array viene trattato all’interno di iterazioni; infatti risulta semplice far riferimento a suoi elementi
incrementando ciclicamente il valore di una variabile intera e utilizzandola come indice. Esempio di iterazione:
Inizializzazione dell'array
for(i=0; i<=5; i++) {
printf("Inser. intero: ");
scanf("%d", &a[i]);
L’indice
i
dell’array
a
è
/* LISTATO 4.1: Memorizza in un array di interi il punteggio raggiunto da sei
inizializzato a 0 e assume a ogni
studenti e ne determina il maggiore, il minore e la media
*/
iterazione successiva i valori 1, 2,
#include <stdio.h>
3, 4, 5 .
main()
{
int voti[6];
/* Ricerca del maggiore*/
int i, max, min; float media;
max = a[0];
printf("VOTI STUDENTI\n\n");
for(i=1; i<=5; i++)
/* Immissione voti */
if(a[i]>max) max = a[i];
for(i=0; i<=5; i++) {
printf("Voto %dº studente: ", i+1);
: la variabile max
viene inizializzata al valore del
scanf("%d", &voti[i]);
primo elemento del vettore, quello con indice zero.
}
/* Ricerca del maggiore */ max = voti[0];
for(i=1; i<=5; i++) if(voti[i]>max)
max = voti[i];
/* Ricerca del minore */ min = voti[0];
for(i=1; i<=5; i++) if(voti[i]<min)
min = voti[i];
/* Calcolo della media */ media = voti[0];
for(i=1; i<=5; i++)
media = media + voti[i];
media = media/6;
printf("Maggiore: %d\n", max); printf("Minore: %d\n", min); printf("Media: %f\n", media);
}
Il blocco
del
for richiede
all’utente l’immissione di sei valori
che vengono
assegnati
sequenzialmente,
mediante
l’istruzione scanf, agli elementi del
vettore.
Se quindi vengono inseriti in
sequenza i valori 9, 18, 7, 15, 21
e 11, dopo l’esecuzione del ciclo il
vettore si presenterà in memoria
come in Figura
Si noti che la richiesta dei voti all’utente viene fatta evidenziando il numero d’ordine che corrisponde al valore
dell’indice aumentato di una unità.
printf("Voto %dº studente: ", i+1);
Alla prima iterazione appare sullo schermo:
Voto 1º studente:
Considerazioni analoghe a quelle fatte per il calcolo del maggiore valgono per il minimo e la media.
I calcoli potevano essere effettuati all’interno della stessa iterazione con un notevole risparmio di tempo di esecuzione:
/* LISTATO 4.1a
#include <stdio.h>
main() {
int voti[6]; int i, max, min; float media;
/* Immissione voti */
printf("VOTI STUDENTI\n\n");
for(i=0; i<=5; i++) {
printf("Voto %dº studente: ", i+1); scanf("%d", &voti[i]);
}
/* Ricerca maggiore, minore e media */
max =voti[0]; min = voti[0]; media = voti[0];
for(i= 0; i <= 5; i++) { if(voti[i] > max) max = voti[i]; if(voti[i] < min)
min = voti[i];
media = media+voti[i];
}
printf("Maggiore: %d\n", max); printf("Minore: %d\n", min); printf("Media: %f\n", media);
}
✓
NOTA
È importante ricordare che in C l’indice inferiore del vettore è zero e quello superiore è uguale al numero di
elementi meno 1: se si desidera un array di 100 si dichiara voti[100];
ma si deve tenere presente che
l’indice assume valori da 0 a 99.
4.2 Esempi di uso di array
Per determinare la destrezza di n concorrenti sono state predisposte due prove, entrambe con una valutazione che
varia da 1 a 10; il punteggio totale di ogni concorrente è dato dalla media aritmetica dei risultati delle due prove. Si
richiede la visualizzazione di una tabella che contenga su ogni linea i risultati parziali e il punteggio totale di un
concorrente.
/* LISTARTO 4.2: Carica i punteggi di n concorrenti su due prove Determina la classifica */
#include <stdio.h>
#define MAX_CONC 1000 /* massimo numero di concorrenti */
#define MIN_PUN 1 /* punteggio minimo per ogni prova */
#define MAX_PUN 10 /* punteggio massimo per ogni prova */
main()
{
float prova1[MAX_CONC], prova2[MAX_CONC], totale[MAX_CONC];
int i, n;
do {
printf("\nNumero concorrenti: ");
scanf("%d", &n);
}
while(n<1 || n>MAX_CONC);
/* Per ogni concorrente, richiesta punteggio nelle due prove */
// LISTARTO 4.2: SEGUITO
for(i=0; i<n; i++) {
printf("\nConcorrente n.%d \n", i+1);
do {
printf("Prima prova: ");
scanf("%f", &prova1[i]);
}
while(prova1[i]<MIN_PUN ||
prova1[i]>MAX_PUN);
do {
printf("Seconda prova: ");
scanf("%f", &prova2[i]);
}
while(prova2[i]<MIN_PUN ||
prova2[i]>MAX_PUN);
}
/* Calcolo media per concorrente */
for(i=0; i<n; i++)
totale[i] = (prova1[i]+prova2[i])/2;
printf("\n CLASSIFICA\n");
for(i=0; i<n; i++)
printf("%f %f %f \n", prova1[i], prova2[i],
totale[i]);
}
Non conoscendo a priori il numero di concorrenti che
parteciperanno alle gare si fa l’ipotesi che comunque non siano più
di 1000, valore che memorizziamo nella costante MAX_CONC. In
conseguenza di ciò definiamo di lunghezza MAX_CONC gli array
che conterranno i risultati: prova1, prova2 e totale.
Richiediamo all’utente a tempo di esecuzione il numero effettivo dei
concorrenti e verifichiamo che non sia minore di 1 e maggiore di
MAX_CONC: (VERIFICARE)
do {
printf("\nNumero concorrenti: ");
scanf("%d", &n);
}
while(n<MIN_PUN || n>MAX_CONC);
In seguito richiediamo l’introduzione dei risultati della prima e
della seconda prova di ogni concorrente, controllando che tale
valutazione non sia minore di 1 e maggiore di 10, nel qual caso
ripetiamo la richiesta.
Abbiamo memorizzato in MIN_PUN e
MAX_PUN i limiti inferiore e superiore del punteggio assegnabile, in
maniera che, se questi venissero modificati, basterebbe intervenire
sulle loro definizioni perché il programma continui a funzionare
correttamente. Infine calcoliamo il punteggio totale e lo
visualizziamo
4.3 Inizializzazione di variabili
L’inizializzazione di una variabile può essere esplicitata direttamente al momento della sua dichiarazione, come con
int i = 0;
L’istruzione dichiara la variabile i di tipo intero e le assegna il valore zero. Di seguito alla dichiarazione di tipo possono
essere definite e inizializzate più variabili:
int a = 50, b = 30, c, d = 333;
definisce le variabili intere a, b, c e d; inizializza a al valore 50, b a 30, d a 333, c non è inizializzata.
Analogamente si possono assegnare valori agli altri tipi di variabili semplici:
float x = 567.8927;
float y = 7e13;
char risposta = 's’;
Per gli array l’inizializzazione è possibile solamente se sono stati dichiarati come extern o come static;
Le variabili extern sono quelle che vengono definite prima di main. L’inizializzazione si ottiene inserendo I
valori tra parentesi graffe, separati da una virgola: Le variabili di tipo static sono permenenti all'interno della
funzione o del file in cui sono dichiarate.
int voti[6] = {11, 18, 7, 15, 21, 9};
Il compilatore fa la scansione dei valori presenti tra parentesi graffe da sinistra verso destra e genera
altrettanti assegnamenti consecutivi agli elementi del vettore, rispettando la loro posizione; dunque voti[0] assume il
valore 11, voti[1] 18, voti[2] 7 ecc.
Quando tutti gli elementi dell’array vengono inizializzati è possibile omettere l’indicazione del numero di elementi, e
scrivere
int voti[] = {11, 18, 7, 15, 21, 9};
È infatti il compilatore stesso che conta i valori e di conseguenza determina la dimensione del vettore.
Gli array di caratteri, comunemente detti stringhe, possono essere inizializzati anche inserendo il loro contenuto tra
doppi apici:
char frase[] = "Analisi, requisiti";
ESERCIZI
Scrivere un programma che chieda quanti
valori
verranno introdotti dalla tastiera (max 100), li chieda
tutti e successivamente li visualizzi dall’ultimo al primo.
#include<stdio.h>
#define MAXNUM 100
int main()
{
int v[MAXNUM], n, i;
printf("Quanti valori introdurrai (max %d)? ",
MAXNUM);
scanf("%d", &n);
if (n>0 && n<=MAXNUM)
{
for (i=0; i<n; i++)
{
printf("Introduci il %do valore: ", i+1);
scanf("%d", &v[i]);
}
for (i=n-1; i>=0; i--)
printf("%d\n", v[i]);
}
else
printf("Il valore inserito (%d) non e' corretto\n", n);
return 0;
}
Scrivere un programma che chieda quanti valori verranno introdotti dalla tastiera
(max 100), li chieda tutti e successivamente visualizzi prima tutti i valori pari
nell’ordine in cui sono stati inseriti e poi tutti i valori dispari nell’ordine inverso.
#include<stdio.h>
#define MAXNUM 100
int main()
{
int v[MAXNUM], n, i;
printf("Quanti valori introdurrai (max %d)? ", MAXNUM);
scanf("%d", &n);
if (n>0 && n<=MAXNUM)
{
for (i=0; i<n; i++)
{
printf("Introduci il %do valore: ", i+1);
scanf("%d", &v[i]);
}
for (i=0; i<n; i++)
if (v[i] % 2 == 0)
printf("%d ", v[i]); /* PARI */
/* NO ELSE QUI in quanto si vogliono SALTARE i dispari */
for (i=n-1; i>=0; i--)
if (v[i] % 2 == 1)
printf("%d ", v[i]); /* DISPARI */
/* NO ELSE QUI in quanto si vogliono SALTARE i pari */
}
else
printf("Il valore inserito (%d) non e' corretto\n", n);
return 0;
}
#include<stdio.h>
#define MAXNUM 100
int main()
{
int a[MAXNUM], b[MAXNUM], c[MAXNUM], n, i;
printf("Quanti valori introdurrai (max %d)? ",
MAXNUM);
scanf("%d", &n);
if (n>0 && n<=MAXNUM)
{
for (i=0; i<n; i++)
{
printf("Introduci il %do valore di a: ", i+1);
scanf("%d", &a[i]);
}
for (i=0; i<n; i++)
{
printf("Introduci il %do valore di b: ", i+1);
scanf("%d", &b[i]);
c[i] = a[i] + b[i];
}
for (i=1; i<n; i+=2)
printf("%d\n", c[i]);
for (i=0; i<n; i+=2)
printf("%d\n", c[i]);
}
else
printf("Il valore inserito (%d) non e' corretto\n", n);
return 0;
}
Scrivere un programma che definisca 2 vettori A e B di uguali
dimensioni (la dimensione sia chiesta in input, max 100), chieda
in input tutti i valori del primo e successivamente tutti i valori
del secondo (devono comparire sul video richieste come le
seguenti:
il
“Introdurre
il
“Introdurre
e successivamente
“Introdurre il
“Introdurre il
1° valore
2° valore
1°
2°
valore
valore
di A”,
di A” ecc.
di B”,
di B” ecc.
Il programma crea un terzo vettore C della stessa dimensione
di A e B contenente nel 1° elemento la somma del 1o elemento
di A e del 1o elemento di B, nel 2o elemento la somma del 2o
elemento di A e del 2o elemento di B etc.
Alla fine deve visualizzare tutti gli elementi di posizione (non
indice) pari di C (il 2o, il 4o,…) e poi tutti quelli di posizione
dispari (1o, 3o,…).
Esempio: vettori di lunghezza 4, in A sono stati messi i valori: 3
5 2 6 e in B: 3 2 6 3, verranno quindi calcolati e messi in C i
valori: 6 7 8 9 e quindi stampati i valori: 7 9 6 8.
#include<stdio.h>
#define MAXNUM 100
int main()
{
int v[MAXNUM], max, min, somma;
int n, i;
do
{
printf("Quanti valori introdurrai (max %d)? ", MAXNUM);
scanf("%d", &n);
}while(n>MAXNUM || n<=0); /* continua a chiedere un nuovo valore per n fintanto che il
valore non e' minore di MAXNUM */
for (i=0; i<n; i++)
{
printf("Introduci il %do valore: ", i+1);
scanf("%d", &v[i]);
}
max = v[0];
min = v[0];
somma = v[0];
for (i=1; i<n; i++)
{
somma += v[i];
if (v[i]>max)
max = v[i];
else if (v[i]<min)
min = v[i];
}
printf("Massimo: %d\n", max);
printf("Minimo: %d\n", min);
printf("Somma: %d\n", somma);
printf("Media: %f\n", (double)somma/n);
return 0; }
Scrivere un programma che chieda
quanti valori verranno introdotti dalla
tastiera (max 100), li chieda tutti e li
collochi in un vettore.
Successivamente, il programma deve
determinare il massimo, il minimo, la
somma e la media di questi valori.
7 Stringhe / caratteri
Caso particolare: STRINGHE
Le stringhe sono dei vettori i cui elementi sono dei caratteri. Nel codice C le stringhe si possono definire come segue:
char x[6];
stringa di 5 caratteri più il terminatore di stringa \0 (rappresentazione del carattere 0)
charx[ ] = {‘c’, ‘o’, ‘d’, ‘i’, ‘c’, ‘e’, ‘\0’};
stringa di 6 caratteri
char x[ ] = “scuola”; stringa di 6 caratteri (NB: in questo caso il compilatore aggiunge il terminatore di stringa (7°
carattere))
ESEMPIO: Programma che consente solo 3 tentativi per l’inserimento del codice segreto
Struttura iterativa:
ciclo
FOR
Al ciclo while si può sostituire il ciclo for.
for (campo1; campo2;
campo3)
{ …………………...
……………………
……………………
}
campo1: valore iniziale della variabile di
conteggio campo2:
condizione per la
ripetizione
del
codice
campo3:
aggiornamento della variabile di conteggio
ESEMPIO 12: programma che acquisisce 6 numeri interi da tastiera e in contemporanea esegue la somma, al termine calcola la media
#include <stdio.h>
#include <stdlib.h> int x, k, s = 0;
float m;
int main()
{ for(k = 1; k <= 6; k ++)
{ printf("Inserisci il %d numero intero: ", k);
scanf("%d", &x);
s = s + x;
/* aggiornamento della somma */
}
m = s / 6.0; /* calcolo della media */
printf("Il valore della somma risulta %d, e della media %f \n", s, m);
system(“pause”);
}
NB: all’inizio k vale 1, lo si confronta
con 6, se minore si esegue il codice tra
parentesi graffe, poi si incrementa k
di 1 e lo si confronta di nuovo con 6,
se ancora minore si ripete il codice.
6.1 Definizione
Una variabile di tipo char consente di memorizzare un singolo carattere.
Molto spesso, però, è comodo poter trattare come una sola unità un insieme di caratteri
alfanumerici, detto stringa; a questo scopo si possono utilizzaree gli array di char.
La linea di codice
char a[10];
Dichiara un vettore costituito da dieci caratteri.
char frase[] = "Analisi, requisiti ";dichiara invece l’array monodimensionale di
caratteri frase, il cui numero di elementi è determinato dalla quantità di caratteri
presenti tra doppi apici più uno, il carattere null (\0).
Il carattere \0 è il primo del codice ASCII, corrisponde alla notazione
binaria 00000000 e non ha niente a che vedere con il carattere 0 che
corrisponde a 00110000.
È importante osservare la differenza tra le due inizializzazioni:
char d = 'r’;
char b[] = "r";
La prima assegna alla variabile d di tipo char il valore r, la seconda assegna all’array b[] la sequenza di
caratteri r e \0; in quest’ultimo caso si tratta effettivamente di una stringa.
Naturalmente, quando si desidera far riferimento a un carattere si deve inserirlo tra apici singoli:
per esempio
b[2] = 't';
assegna al terzo elemento dell’array b il carattere t.
Il carattere terminatore \0 ci permette di trattare le stringhe senza conoscere a priori la dimensione.
Il programma del Listato 6.1 consente di verificare la corrispondenza tra ogni carattere presente in
una stringa e il suo equivalente valore all’interno del codice ASCII, espresso nei sistema decimale e
ottale.
/* listato 6.1 Visualizzazione caratteri di una stringa */
#include <stdio.h>
char frase[] = "Analisi, requisiti ";
main()
{
int i=0;
while(frase[i]!='\0') {
printf("%c = %d = %o \n", frase[i], frase[i], frase[i]); i++;
}
}
Il ciclo while permette di fare la scansione, uno a
uno, dei caratteri della stringa.
Viene controllato se il carattere in esame è \0, nel
qual caso non ci sono più caratteri da esaminare e
l’iterazione ha termine.
L’istruzione printf visualizza a ogni ciclo un elemento
dell’array, in tre formati differenti:
printf("%c
=
%d
frase[i],frase[i],frase[i]);
=
%o
\n",
Il primo formato, specificato da %c, indica il carattere ASCII stesso,
il secondo e il terzo sono i suoi corrispondenti codici espressi nel sistema decimale (%d) e ottale (%o).
Questo gioco di corrispondenze tra caratteri e numeri interi, definite dal codice ASCII, è sempre valido e
offre grande libertà al programmatore.
Comunque, se si desidera la visualizzazione dell’intera stringa, è possibile usare l’istruzione printf tramite la
specifica del formato %s:
printf("%s", frase);
Tale istruzione, se inserita nel Listato 6.1 , restituirebbe:
Analisi, requisiti
In questo caso è l’istruzione printf stessa che provvede a stampare carattere per carattere la stringa e a
bloccarsi nel momento in cui identifica il carattere \0.
6.2 Esempi di uso delle stringhe
/* LISTAYO 6.2 Copia di una stringa su un'altra */
#include <stdio.h>
char frase[] = "Analisi, requisiti ";
main()
{
int i;
char discorso[80];
for(i=0; (discorso[i]=frase[i])!='\0'; i++);
printf(" originale: %s \n copia: %s \n", frase, discorso);
}
La variabile intera i viene utilizzata come indice degli array, per fare la scansione delle due stringhe carattere per
carattere e per effettuare la copia. Nell’istruzione for viene inizializzato il valore di i a 0:
i = 0;
Successivamente il ciclo assegna a discorso[0] il valore di frase[0] e controlla che tale valore non sia uguale a \0
(marca di fine stringa), nel qual caso il ciclo ha termine. A ogni nuova iterazione il valore di i viene incrementato di
1:
i++;
Viene quindi assegnato
a discorso[i] il valore di
frase[i], (discorso[i]=frase[i])
Se si desidera copiare soltanto alcuni caratteri della prima stringa sulla seconda si deve modificare l’istruzione for
del Listato 6.2. Scrivendo
for(i=0; ((discorso[i]=frase[i])!='\0') && (i<7); i++)
si è inserita la condizione i<7 messa in AND (&&) con la verifica di fine stringa; in questo modo verranno
copiati solamente i primi sette caratteri. L’istruzione printf visualizzerà allora:
originale: Analisi, requisiti copia: Analisi
Il programma del Listato 6.3 permette invece di aggiungere a una variabile stringa i caratteri presenti in
un’altra.
/* LISTATO 6.3: Concatenazione di due stringhe */
#include <stdio.h>
char frase[160] = "Analisi, requisiti ";
main()
{
char dimmi[80]; int i, j;
printf("Inserisci una parola: ");
scanf("%s", dimmi);
for(i=0; (frase[i])!='\0'; i++) ;
for(j=0; (frase[i]=dimmi[j])!='\0'; i++,j++) ;
printf("frase: %s \n", frase);
}
In questo caso indichiamo esplicitamente il numero di elementi
(160) che compongono la variabile frase, poiché desideriamo
definire un array che possa contenere più caratteri di quelli
presenti nella stringa assegnatagli all’inizio (20):
char frase[160] = "Analisi, requisiti ";
In questo modo frase potrà contenere i caratteri che gli
verranno concatenati. La prima istruzione
printfrichiede
all’utente una stringa e scanf la inserisce nell’array di caratteri
dimmi.
In generale non si conosce il numero di caratteri che
attualmente costituiscono la stringa di partenza, per cui si deve
scorrerla fino a posizionare l’indice sul carattere terminatore:
for(i=0; (frase[i])!='\0'; i++);
Alla fine del ciclo i conterrà l’indice dell’elemento del vettore
dov’è presente il carattere \0. Nel caso
specifico, avendo
assegnato a frase la stringa "Analisi, requisiti ", iavrà valore 20.
Adesso dobbiamo assegnare agli elementi successivi di frase il contenuto di dimmi:
for(j=0; (frase[i]=dimmi[j])!='\0'; i++,j++) ;
L’indice j scorre dimmi a partire dalla prima posizione, mentre i scorre frase a partire dal suo carattere
terminatore; alla prima iterazione il carattere \0 di frase viene sostituito dal primo carattere di dimmi. A
ogni ciclo successivo viene assegnato a frase[i] il valore di dimmi[j].
All’ultima iterazione il carattere \0 di dimmi viene posto in frase, così da chiuderla correttamente.
L’istruzione printf visualizza il nuovo contenuto di frase.
printf("frase: %s \n", frase);
Osserviamo di seguito una possibile esecuzione del programma.
Inserisci una parola: funzionali
frase: Analisi, requisiti funzionali
In Figura 6.2, A e B corrispondono agli stati degli array immediatamente prima e dopo l’esecuzione del
secondo fordel programma che effettua la concatenazione.
Figura 6.2 Stato degli array prima e dopo la concatenazione
Un altro modo per memorizzare una stringa è l’uso, all’interno di un ciclo, della funzione getchar, che
cattura il carattere passatole in ingresso (Listato 6.4).
/* Listato 6.4 Immissione di caratteri con getchar()
Concatenazione di due stringhe*/
#include <stdio.h>
char frase[160] = "Analisi, requisiti ";
main()
{
char dimmi[80];
int i, j;
printf("Inserisci una parola: ");
for(i=0; (dimmi[i]=getchar())!='\n'; i++) ;
dimmi[i]='\0';
for(i=0; frase[i]!='\0'; i++);
for(j=0; (frase[i]=dimmi[j])!='\0'; i++,j++);
printf(" frase: %s \n", frase);
}
Il ciclo for che sostituisce l’istruzione scanf inizializza l’indice
i a zero, cattura il carattere passato da tastiera mediante la
funzione getchar e lo inserisce nel primo elemento dell’array
dimmi:
for(i=0; (dimmi[i]=getchar())!='\n'; i++);
A ogni iterazione il valore di i viene incrementato di 1 e il
valore immesso viene inserito nel corrispondente elemento
dell’array. Il ciclo si ripete finché il carattere immesso è
diverso da \n, cioè fino a quando l’utente non batte un Invio.
La stringa memorizzata in dimmi non contiene il carattere terminatore, che va esplicitamente
assegnatogli nella posizione appropriata:
dimmi[i] = '\0';
È chiaro che potremmo decidere d’interrompere l’inserimento al verificarsi di un altro evento; per
esempio, quando l’utente batte un punto esclamativo. In questo modo potremmo memorizzare
più linee nello stesso array: ogni Invio dato dal terminale corrisponde infatti all’assegnamento di
un \n
a un elemento dell’array; evidentemente una successiva visualizzazione dell’array
mostrerebbe la stringa con gli accapo inseriti dall’utente.
NOTA
Nel programma abbiamo definito dimmi di 80 caratteri. Se l’utente ne inserisse un numero maggiore,
come abbiamo già evidenziato, i sovrabbondanti andrebbero a sporcare zone contigue di memoria
centrale. Il C non fa infatti nessun controllo automatico del rispetto dei margini dell’array. È il
programmatore che si deve preoccupare di verificare che gli assegnamenti vengano effettuati su elementi
definiti dell’array, per cui un più corretto ciclo d’inserimento del programma sarebbe:
for(i=0; ((dimmi[i]=getchar())!='\n') && (i<80)) ;i++);
Il ciclo prosegue finché il carattere catturato è diverso da \n e contemporaneamente i è minore di 80.
Scriviamo adesso un programma che confronta due stringhe rivelando se la prima è uguale, maggiore o
minore della seconda (Listato 6.5). L’ordinamento seguito è quello definito dal codice di rappresentazione
dei caratteri, che nella maggior parte delle macchine è il codice ASCII.
/* L NO 6.5:Confronto fra ARRAY DI CHARdue stringhe */
#include <stdio.h>
char prima[160] = "mareggiata";
main()
{
char seconda[80];
int i;
printf("Inserisci una parola: ");
for(i=0; ((seconda[i]=getchar()) != '\n') && (i<80) ;i++) ;
seconda[i]='\0';
for(i=0; (prima[i] == seconda[i]) && (prima[i] != '\0') &&
(seconda[i] != '\0'); i++);
if(prima[i]==seconda[i])
printf("Sono uguali\n"); else
if(prima[i]>seconda[i])
printf("La prima è maggiore della seconda\n"); else
printf("La seconda è maggiore della prima\n");
}
L’istruzione For
for(i=0; (prima[i]==seconda[i]) &&
(prima[i]!='\0') && (seconda[i]!='\0'); i++);
scorre in parallelo gli elementi dei due array e li
confronta;
il ciclo si interrompe quando
prima[i] non risulta essere uguale a seconda[i]
oppure quando finisce una delle due stringhe.
L’if seguente serve a determinare la ragione per
cui il ciclo for si è interrotto; si noti che l’unica
possibilità
per cui prima[i] è uguale a
seconda[i] si presenta quando entrambi sono
uguali a \0, il che significa che le stringhe
hanno la stessa lunghezza e sono uguali.
6.3 Funzioni di libreria
Esistono nella libreria string.h funzioni standard che permettono di effettuare le operazioni che abbiamo
esaminatosulle stringhe e molte altre ancora. Come al solito, è sufficiente dichiarare il riferimento a tale libreria
all’inizio del programma per poter utilizzare le funzioni in essa contenute.
La funzione strcpy consente di copiare stringa2 su stringa1: strcpy(stringa1, stringa2);
La funzione strncpy permette invece di copiare i primi n caratteri di stringa2 in stringa1: strncpy(stringa1,
stringa2, n);
mentre la funzione strcat consente di concatenare stringa2 a stringa1: strcat(stringa1, stringa2);
La funzione strcmp serve a confrontare stringa2 con stringa1 (Listato 6.6): strcmp(stringa1, stringa2);
Se risultano essere uguali viene restituito zero, se stringa1 è maggiore di stringa2 viene restituito un valore
positivo, altrimenti un valore negativo .
/* LISTATO 6.6 Confronto tra due stringhe con strcmp */
#include <stdio.h>
#include <string.h>
char prima[160] = "mareggiata";
main()
{
char seconda[80];
int i, x;
printf("Inserisci una parola: ");
for(i=0; ((seconda[i]=getchar())!='\n') && (i<80); i++);
seconda[i] = '\0';
if( (x = (strcmp(prima, seconda))) == 0)
printf("Sono uguali\n");
else
if(x>0)
printf("la prima è maggiore della seconda\n");
else
printf("la seconda è maggiore della prima\n");
}
ESEMPI
Scrivere un programma che date due
stringhe in input stampi la più lunga.
La prima se sono di uguale
lunghezza.
#include<stdio.h>
#include<string.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR], b[MAXSTR];
printf("Stringa 1? ");
gets(a);
printf("Stringa 2? ");
gets(b);
if (strlen(a) >= strlen(b))
printf("%s\n", a);
else
printf("%s\n", b);
return 0;
}
Scrivere un programma che
date due stringhe in input
stampi la maggiore.
#include<stdio.h>
#include<string.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR], b[MAXSTR];
printf("Stringa 1? ");
gets(a);
printf("Stringa 2? ");
gets(b);
if (strcmp(a,b) >=0 )
printf("%s\n", a);
else
printf("%s\n", b);
Scrivere un programma che
chieda in input una stringa e
calcoli da quanti caratteri è
composta
(senza
usare
la
funzione strlen ma cercando
il carattere '\0’)
#include<stdio.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR];
int cont;
Scrivere un programma che data
una stringa
in input, la
converta tutta in maiuscolo.
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR];
int i, l;
printf("Stringa? ");
gets(a);
l=(int)strlen(a);
for (i=0; i<l; i++)
a[i] = (char)toupper(a[i]);
printf("%s\n", a);
printf("Stringa? ");
gets(a);
cont=0;
while (a[cont] != '\0')
cont++;
printf("%d\n", cont);
return 0;
}
}
return 0;
return 0;
}
Scrivere un programma che data
una stringa in input verifichi se
essa contiene almeno una ‘A’ tra i
primi 10 caratteri.
#include<stdio.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR];
int i, trovato=0;
printf("Stringa? ");
gets(a);
for (i=0; i<10 && a[i] != '\0'; i++)
/* (1) */
if (a[i] == 'A')
trovato = 1;
if (trovato == 1)
printf("Trovato\n");
else
printf("Non trovato\n");
return 0;
}
Scrivere un programma che richieda in
input una stringa e conti quante
cifre essa contiene.
Esempio
“Ciao2004! C6?” deve dare 5.
#include <stdio.h>
#include<string.h>
#include<ctype.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR];
int i, L, cifre=0;
printf("Introduci la stringa:");
gets(a);
}
L=(int)strlen(a);
for (i=0; i<L; i++)
if (isdigit(a[i]))
cifre++;
printf("Cifre: %d\n", cifre);
return 0;
Scrivere un programma che richieda in
input una stringa e conti di quante
lettere maiuscole, lettere minuscole,
cifre e altri caratteri è composta
#include <stdio.h>
#include<string.h>
#include<ctype.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR];
int i, L, maius=0, minus=0, cifre=0;
printf("Introduci la stringa:");
gets(a);
L=(int)strlen(a);
for (i=0; i<L; i++)
if (isupper(a[i]))
maius++;
else if (islower(a[i]))
minus++;
else if (isdigit(a[i]))
cifre++;
printf("Maiuscole: %d\n", maius);
printf("Minuscole: %d\n", minus);
printf("Cifre: %d\n", cifre);
printf("Altri: %d\n", L-maius-minuscifre);
return 0;
}
IL CODICE ASCII
I caratteri e le stringhe

Per memorizzare i simboli grafici corrispondenti ai caratteri
bisogna associare un numero intero a ciascuno di essi
Contiene i 95 caratteri di base (es. non le lettere accentate)
 Ha 4 sezioni importanti:
 Spazio (è il carattere visibile di codice più basso)
 Cifre (0-9 in ordine crescente)
 Maiuscole (A-Z in ordine cresc.)
 Minuscole (a-z in ordine cresc.)


Le 4 sezioni sono separate da altri caratteri generici
(punteggiatura, simboli matematici, ecc.)

Alcuni caratteri speciali (caratteri di controllo) non vengono visualizzati,
ma producono un effetto (es. inserire un ritorno a capo, beep)
Caratteri

Per memorizzare un carattere, il C memorizza il numero intero corrispondente al suo codice ASCII ('A' equivale
a 65, '0'a 48, ecc.)
Costanti carattere: indicate tra apici singoli ('A'), oppure indicandone il codice ASCII in: decimale: 65, in ottale:
'\101, in esadecimale: '\0x41'
 Le costanti di tipo carattere vengono anche chiamate letterali carattere (character literal )
 Essendo numeri interi, i caratteri possono essere usati nelle operazioni:
x = c–'0';
se c contiene il codice ASCII di una cifra, c–'0' ne è il valore corrispondente
Esempio
Se c='7', allora '7'–'0'viene valutato come 55–48, cioè il valore 7 (il risultato è di tipo int per effetto delle
promozioni integrali)

Variabili carattere: variabili di tipo intero su 8 bit, sono definite di tipo char ;y definizione
y = 'A’; assegnazione con carattere y = 65
y ='\0x41’; con cod. ASCII esadecim.


ypuò essere usata sia come numero (65) sia come carattere ('A'):
printf("%c ha valore %d\n", y, y); dove la specifica %c serve per visualizzare il simbolo corrispondente ad un
codice ASCII, mentre la specifica %d visualizza un numero intero, questo visualizza: A ha valore 65
Stringhe
 Sono vettori di char terminati da un carattere
di codice ASCII pari a 0 (il terminatore non è il carattere '0' che ha valore 48 nel codice ASCII, ma il carattere
'\0')


Le terminate da uno 0 vengono anche dette stringhe ASCIIZ, il linguaggio C ha solo questo tipo di stringhe
Stringhe costanti: Sono sequenze di caratteri racchiuse da doppi apici, la stringa "ciao ciao" è composta da 9+1
caratteri, l’ultimo è '\0’
Per includere in una stringa i caratteri \ e " è necessario precederli dal carattere di escape \
 "vero\\falso" memorizza: vero\falso
 "premi \"invio\" per terminare«
memorizza: premi "invio" per terminare
Una stringa costante viene anche chiamata letterale stringa (string literal )
 Più stringhe costanti consecutive (separate da
nulla, spazi, Tab o ritorni a capo) vengono concatenate dal
compilatore in una sola:
"ciao" "ciao"
"ciao"
"ciao"
viene memorizzata come fosse scritta così:
"ciaociaociaociao" (17 caratteri)
 Una stringa costante è un vettore di char di classe di allocazione static (quindi non modificabile) inizializzato
con i caratteri dati
 Le classi di allocazione sono descritte in altro set di slide (puntatori)

Variabili stringa
Sono vettori di char di dim. fissa, l’ultimo carattere deve essere il terminatore '\0'
 char nome[15];
definisce una variabile stringa composta di 15 char, può contenere fino a 14 caratteri utili (deve esserci
spazio per il carattere '\0')
Il 1o carattere è nome[0], il 2o nome[1], ecc.
 Il terminatore permette di occupare solo parzialmente una stringa (lo spazio relativo ai restanti caratteri
esiste ma è inutilizzato)

Si possono inizializzare le variabili stringa in 2 modi equivalenti:
char s[20]="Ciao";
char s[20]={'C','i','a','o'};
Il carattere di posizione 4 (il 5o) è '\0' in entrambi i casi: infatti, essendo vettori, se l’inizializzazione non
riempie completamente la stringa, i caratteri successivi a quelli indicati sono tutti 0 (cioè '\0')
 I singoli elementi della stringa sono caratteri:
s[2] vale 'a'
s[0] = 'M'; modifica s in "Miao"
 Per assegnare una stringa NON si può scrivere s="Ciao" ma serve una funzione
 I/O di caratteri <stdio.h>
 printf("%c", varChar);
manda in output il carattere
 scanf("%c", &varChar);

legge 1 carattere (anche spazi e ritorni a capo) e lo mette in varChar, se viene indicata un’ampiezza (es. %4c)
legge esattamente quel numero di caratteri (anche spazi) e li assegna alla STRINGA indicata come parametro,
senza aggiungere il '\0': scanf("%4c", varStringa); per saltare gli spazi iniziali si usi %1s
 I/O di caratteri <stdio.h>
 putchar(varChar);
manda in output il carattere
 varInt = getchar();
getchar restituisce il carattere letto o la costante EOF per segnalare la fine dell’input, varInt deve essere di
tipo int per potervi memorizzare anche EOF che è di tipo int.
EOF è una costante simbolica definita in <stdio.h> con una #define, in genere vale –1
 Libreria caratteri <ctype.h>
 Le seguenti funzioni danno risultato vero (valore !=0) se il carattere c è del tipo indicato
 isdigit(c)  cifra decimale
 isalpha(c)  lettera
 isalnum(c)  carattere alfanumerico
 isxdigit(c) cifra esadecimale
 islower(c)  lettera minuscola
 isupper(c)  lettera maiuscola
 iscntrl(c)  carattere di controllo
 isspace(c)  white space (' ','\t','\n',...)
 isprint(c)  char stampabile, incluso lo spazio
 isgraph(c)  char stampabile, escluso lo spazio
 ispunct(c)  stampabile, no spazio, no alfanum
Libreria caratteri <ctype.h>
 Le seguenti funzioni producono un valore int
contenente il codice ASCII del carattere c eventualmente
convertito, se possibile:
 toupper(c)  in maiuscolo
 tolower(c)  in minuscolo
Altrimenti il valore prodotto resta c (invariato)
 Se si vuole convertire in maiuscolo/minuscolo tutta una stringa è necessario applicare la funzione a ciascuno
dei caratteri:
for (i=0; i<strlen(s); i++)
s[i] = (char)toupper(s[i]);
notare il cast: toupper produce un int
 Funzioni su stringhe <stdlib.h>
 varInt = atoi(stringa) converte stringa in int
x=atoi("123");  123 in complem. a 2
 varLong = atol(stringa) converte stringa in long
y=atol("123");  123 in complem. a 2
 varDouble = atof(stringa) converte stringa in double
z=atof("1.23E5");  1.23×105 in floating point
 Confronto tra stringhe
 Avviene confrontando i caratteri di posizione corrispondente delle due stringhe secondo i loro codici ASCII ( “< ” significa
“precede”)

“cane”
“cane”
<
>
“gatto”
“Gatto”
“cane”
<
“cavallo”
“cavallo”
<
“cavallone”
“cavallo”
<
“cavallo ”
Libreria stringhe <string.h>
Lunghezza di una stringa, Copia di una stringa, Concatenazione di stringhe
Concatenazione di stringhe, Ricerca in stringhe
ESEMPI
Scrivere un programma che date due
stringhe in input stampi la più
lunga. La prima se sono di uguale
lunghezza.
#include<stdio.h>
#include<string.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR], b[MAXSTR];
printf("Stringa 1? ");
gets(a);
printf("Stringa 2? ");
gets(b);
if (strlen(a) >= strlen(b))
printf("%s\n", a);
else
printf("%s\n", b);
return 0;
}
Scrivere un programma che
date due stringhe in input
stampi la maggiore.
#include<stdio.h>
#include<string.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR], b[MAXSTR];
printf("Stringa 1? ");
gets(a);
printf("Stringa 2? ");
gets(b);
if (strcmp(a,b) >=0 )
printf("%s\n", a);
else
printf("%s\n", b);
Scrivere un programma che
chieda in input una stringa e
calcoli da quanti caratteri è
composta (senza usare la
funzione strlen ma cercando
il carattere '\0’)
#include<stdio.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR];
int cont;
Scrivere un programma che data
una stringa
in input, la
converta tutta in maiuscolo.
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define MAXSTR 80
int main()
{
char a[MAXSTR];
int i, l;
printf("Stringa? ");
gets(a);
cont=0;
while (a[cont] != '\0')
cont++;
printf("%d\n", cont);
return 0;
}
}
printf("Stringa? ");
gets(a);
l=(int)strlen(a);
for (i=0; i<l; i++)
a[i] = (char)toupper(a[i]);
printf("%s\n", a);
return 0;
return 0;
}
sottoprogramma
7.1 Il concetto di sottoprogramma
Un programma è formato da elementi connessi in modo da raggiungere un determinato scopo. Le istruzioni
possono essere considerate i componenti di un programma.
Un programma non può essere “smontato” oltre il limite delle singole istruzioni, ma è possibile aggregare gruppi
di istruzioni per formare dei “semilavorati” detti sottoprogrammi. Come un personal computer è composto da
tastiera, video, stampante e unità centrale, così un programma per il calcolo degli stipendi potrebbe essere
scomposto nei sottoprogrammi di immissione delle ore lavorate, di calcolo dello stipendio e di visualizzazione e
stampa della situazione contabile di ogni impiegato.
I sottoprogrammi si usano anche per evitare di replicare porzioni di codice sorgente: invocare un
sottoprogramma significa mandare in esecuzione la porzione di codice corrispondente. Se un sottoprogramma è
invocato più volte, la porzione di codice è eseguita più volte, tante quante sono le invocazioni. Il vantaggio dei
sottoprogrammi è appunto di consentire al programmatore di avere tante chiamate ma una sola porzione di
codice.
È possibile poi creare delle librerie, cioè delle raccolte di sottoprogrammi che possono essere utilizzati senza
essere a conoscenza dei dettagli implementativi. È quanto avviene con le funzioni printf() e scanf(), la cui
dichiarazione è contenuta nel file stdio.h.
7.2 Sottoprogrammi C
In C i sottoprogrammi sono detti funzioni: a partire da uno o più valori presi in ingresso, esse ritornano (o
restituiscono) un valore al programma chiamante. Come indicato in Figura 7.1, una funzione può essere
pensata come una scatola nera che a determinati valori in ingresso fa corrispondere un determinato valore
in uscita.
Un esempio di funzione C è abs(i), già utilizzata più volte. Considerando la funzione abs come una scatola
nera, tutto quello che dobbiamo sapere
e in effetti già sappiamo
è che inserendo come argomento i di
tale funzione un numero intero essa ne ritorna il valore assoluto (Figura 7.2).
Prima di esaminare la sintassi di dichiarazione e definizione di una funzione si consideri l’esempio riportato
nel Listato 7.1.
Per
poter
usare
un
identificatore
occorre
innanzitutto
#include <stdio.h>
double cubo(float);
main()
{
float
a; double b;
printf("Inserisci un numero: "); scanf("%f", &a);
b = cubo(a);
printf("%f elevato al cubo è uguale a %f", a, b);
}
double cubo(float c)
{
return (c*c*c);
}
dichiararlo. La dichiarazione: double cubo(float);
che precede main introduce l’identificatore cubo.
Per mezzo di questa dichiarazione si specifica che cubo è il
nome di una funzione che restituisce al programma chiamante
un valore di tipo double. Inoltre si dichiara che la funzione cubo
accetta in ingresso un solo valore come argomento, il cui tipo è
float.
In sostanza
abbiamo dichiarato un nuovo nome, cubo,
abbiamo detto a quale categoria appartiene questo nome.
La definizione della funzione cubo avviene più tardi, dopo
la fine del blocco di istruzioni di main:
double cubo(float c)
{
return (c*c*c); }
e
Oltre al nome della funzione viene definito il numero, il tipo e il nome dei suoi parametri, cioè le variabili su cui
essa agisce. Nel nostro esempio è presente un solo parametro, il cui tipo è float e il cui nome è c.
Il compito svolto da cubo è molto semplice: il valore passato nel parametro c è moltiplicato per se stesso tre
volte (c*c*c) e il risultato di questa espressione è convertito in double e restituito (con return) al programma
chiamante.
Il programma chiamante non ha da fare altro che passare alla funzione cubo un valore. Nell’esempio lo fa
passando a cubo il valore contenuto nella variabile a: cubo(a). Successivamente il valore calcolato da cubo viene
assegnato a una variabile di tipo double. Nell’esempio tale variabile è b e l’assegnazione è b = cubo(a);
Con questo semplice esempio abbiamo messo in luce diversi aspetti della sintassi delle funzioni:
• • la dichiarazione di una funzione:
double cubo(float); (double tipo di ritorno, float tipo di utilizzo)
• • la definizione di una funzione:
double cubo(float c) {...}; nome della funzione
• • il ritorno di un valore:
return(c*c*c);
• • l’invocazione di funzione:
b = cubo(a).
Passiamo ora a considerare in dettaglio ciascuno dei punti evidenziati.
Passiamo ora a considerare in dettaglio ciascuno dei punti evidenziati.
7.3 Dichiarazione di una funzione
In termini generali una funzione viene dichiarata con la sintassi detta prototyping: (prototipazione)
tipo_ritorno nome_funz (tipo_par1, ..., tipo_parN);
La dichiarazione introduce il nome della funzione, che in questo modo può essere utilizzato dal programma, ma
presuppone che da qualche altra parte ne esista la definizione, altrimenti quel nome resterebbe privo di
significato e il compilatore segnalerebbe un errore.
Nella dichiarazione di una funzione si potrebbero specificare anche i nomi dei parametri formali. Per
esempio:
double cubo(float c);
è una dichiarazione valida. Il nome del parametro formale, però, è assolutamente superfluo. Ciò che conta
in una dichiarazione è il tipo, o meglio la lista dei tipi dei parametri formali. Se in una dichiarazione di una
funzione si specificano anche i nomi dei parametri formali il compilatore semplicemente li ignora.
7.4 Definizione di una funzione
In termini generali una funzione viene definita con la sintassi prototyping nel seguente modo:
tipo_ritorno nome_funz (tipo_par1 par1, ..., tipo_parN parN)
{
...
}
La definizione stabilisce il nome della funzione, i valori in ingresso su cui agisce
detti parametri formali ,
il blocco di istruzioni che ne costituiscono il contenuto, e l’eventuale valore di ritorno. Per i nomi delle
funzioni valgono le consuete regole in uso per gli identificatori. Nelle parentesi tonde che seguono il nome
della funzione sono definiti i parametri formali specificandone il tipo e il nome.
Per ogni funzione introdotta nel programma occorre una definizione ( si ricordi che in C non è ammesso che
più funzioni abbiano lo stesso nome)
Nel blocco istruzioni delimitato da parentesi graffe può essere inserita qualunque istruzione, compresa una
chiamata di funzione.
#include <stdio.h>
#include <stdlib.h>
double coefficiente_binomiale(int n, int k);
int fattoriale(int n);
int n, k;
int main()
{
printf("n= "); scanf("%d", &n);
printf("k= "); scanf("%d", &k);
if((n < k) || (k < 0))
printf("dati non validi \n ");
else
printf("n su k =%lf\n", coefficiente_binomiale(n,
k));
return EXIT_SUCCESS;
}
double coefficiente_binomiale(int n, int k)
{
return fattoriale (n) /
(double) fattoriale(k)*fattoriale(n-k); }
int fattoriale (int n)
{
int fatt = 1;
while (n>1)
fatt*= n--;
return fatt; }
/* LISTATO 7.2: DICHIARAZIONE E
DEFINIZIONE DI FUNZIONE*/
#include <stdio.h>
double quad(float); double cubo(float);
double quar(float); double quin(float);
double pote(float, int);
La funzione main richiama la funzione potenza pote passando a essa due
parametri attuali: base ed esponente
ptnz = pote(base, esponente);
main() {
int base, esponente;
double ptnz;
printf(" Inserire base: " );
scanf("%d", &base);
printf(" Inserire esponente (0-5): ");
scanf("%d", &esponente);
ptnz = pote( base, esponente);
if (ptnz == -1)
printf("Potenza non prevista\n");
else
printf("La potenza %d di %d e' %f \n", esponente, base, ptnz); }
La funzione pote, che riceve in ingresso i valori nei
parametri b ed e corrispondenti rispettivamente a base ed
esponente, valuta il valore dell’esponente; dopo di ciò
effettua una delle seguenti azioni:
restituisce il valore 1 per esponente 0, la base stessa b
per esponente 1, invoca la funzione quad
per esponente 2, cubo
per esponente 3, quar
per esponente 4, quin
per esponente 5 oppure restituisce
1 per segnalare la
non disponibilità della potenza richiesta.
double quad(float c)
return(c*c);
}
double cubo(float c)
return(c*c*c); }
double quar(float c)
return(c*c*c*c); }
double quin(float c)
return(c*c*c*c*c);
}
{
{
{
{
double pote(float b, int e) {
switch (e) {
case 0: return (1); case 1: return (b);
case 2: return (quad( b )); case 3: return (cubo( b ));
case 4: return (quar( b )); case 5: return (quin( b ));
default : return (-1);
} }
Se l’esponente è 2, viene dunque invocata la funzione quad, cui la
funzione pote trasmette il parametro attuale b:
case2: return quad( b );
quad lo riceve in ingresso nel parametro formale c (FIGURA 7.2)
La funzione quad calcola il quadrato di c e restituisce il risultato a
pote, la quale a sua volta lo restituisce a main che l’aveva invocata
(Figura 7.3). Il main gestisce tramite if il ritorno del valore negativo
1, usato per segnalare la non disponibilità della potenza richiesta.
7.5 Visibilità
Prima di passare all’elemento sintattico “return”, dobbiamo osservare quanto segue.
Una dichiarazione introduce un nome in un determinato ambito di definizione, detto scope. In altre parole, ciò
significa che un nome può essere usato soltanto -o, come si usa dire, è visibile in una specifica parte del testo
del programma. Per un nome dichiarato all’interno del blocco istruzioni di una funzione (nome locale), la
visibilità si estende dal punto di dichiarazione alla fine del blocco in cui esso è contenuto.
Per un nome definito al di fuori di una funzione (nome globale) la visibilità si estende dal punto di
dichiarazione alla fine del file in cui è contenuta la dichiarazione.
Così, per esempio, in
int x; f()
{
int y;
y = 1;
}
la visibilità della variabile y si estende dal punto di definizione sino alla fine del blocco di appartenenza.
Anche i parametri formali di una funzione hanno un campo di visibilità che si estende dall’inizio alla fine del
blocco istruzioni della funzione; sono quindi considerati a tutti gli effetti variabili locali alla funzione
int x;
g(int y, char z)
{
int k; int l;
...
}
le variabili y e z sono locali alla funzione g e hanno una visibilità che si estende dalla parentesi graffa aperta
{ alla corrispondente parentesi graffa chiusa }. Quindi la definizione di y e z precede all’interno del blocco la
definizione delle altre variabili locali k e l aventi anch’esse una visibilità che va dal punto di definizione
alla fine del blocco . Per questo motivo la funzione:
f(int x)
{ int x; }
è errata: in essa si tenta di definire due volte la variabile locale x nello stesso blocco.
Una dichiarazione di un nome in un blocco può nascondere, o come si dice in gergo, mascherare, la
dichiarazione dello stesso nome in un blocco più esterno o la dichiarazione dello stesso nome globale.
Un nome ridefinito all’interno di un blocco nasconde il significato precedente di quel nome, significato che
verrà ripristinato all’uscita del blocco di appartenenza (Listato 7.3) .
NOTA: È inevitabile che in un programma avvenga il
// 7.3: Esempio di mascheramento dei nomi
mascheramento di nomi e non è infrequente il caso in
int x; /* nome globale */
cui il
programmatore non si accorge di aver
f()
mascherato un nome all’interno di un blocco. È allora
{
consigliato identificare le variabili globali con dei nomi
int x; /* x locale che nasconde x globale */
caratteristici e univoci: usare per variabili globali nomi
x = 1; /* assegna 1 a x locale */
del tipo i, j oppure x significa rischiare mascheramenti
indesiderati.
{
7.6 return
int x; /* nasconde il primo x locale */
x = 2; /* assegna 2 al secondo x locale */
}
x = 3; /* assegna 3 al primo x locale */
}
scanf ("%d", &x); /* inserisce un dato in x globale */
A ogni funzione C è associato un tipo, scelto tra quelli
fondamentali o derivati, che caratterizza un valore.
Questo
valore è detto valore di ritorno della
funzione ed è restituito dalla funzione al programma
chiamante per mezzo
dell’istruzione return. La
sintassi
da
usare
è:return
(espressione);
oppure:
return espressione;
All’interno del blocco istruzioni di una funzione si possono avere più istruzioni return. Nella funzione pote:
double pote( b, e)
float b;
int e; {
switch (e) { case 0: return 1; case 1: return b; case 2: return quad(b); case 3: return cubo(b); case 4:
return quar(b); case 5: return quin(b); default : return -1; } }
a ogni scelta del costrutto switch-case corrisponde un’uscita e la restituzione di un diverso valore. In questo caso
abbiamo usato la forma sintattica del return non inserendo l’espressione di ritorno tra parentesi tonde.
L’invocazione di una funzione, detta anche chiamata di funzione (Paragrafo 7.8), può stare alla destra
dell’operatore di assegnamento, salvo il caso in cui il tipo sia void. Nella funzione cubo del Listato 7.1, per esempio:
b = cubo(a); alla variabile b viene assegnato il valore restituito dalla funzione cubo. Naturalmente il valore di
ritorno può essere utilizzato all’interno di un’espressione:
y = a * cubo(x) + b * quad(x) + c * x + d;
Nel caso in cui non sia esplicitamente definito un tipo di ritorno il linguaggio C assume che esso sia il tipo
fondamentale int.
7.7 Chiamata di una funzione
Una funzione C viene invocata facendo riferimento al nome e passando a essa una lista di parametri conforme in
tipo, numero e ordine alla lista dei parametri formali elencata nella definizione della funzione stessa (Listato 7.4).
//LISTATO 7.4: chiamata di funzione
#include <stdio.h>
double area(float, float, char);
main()
{
float b, h;
double a;
char p;
printf("Inserire poligono
(Triangolo/Rettangolo): ");
scanf("%c", &p);
printf("\nInserire base: ");
scanf("%f", &b);
printf("\nInserire altezza : ");
scanf("%f", &h);
a = area( b, h, p);
printf("Il poligono (b = %f, h = %f) ha area
%f\n", b, h, a);
}
double area(float base, float altezza, char
poligono)
{
switch (poligono) {
case 'T': return (base * altezza/2.0);
case 'R': return (base * altezza);
default : return -1;
}
}
/*LISTATO 7.5: le funzioni come strumento di riutilizzo del
codice*/
#include <stdio.h>
double area(float, float, char); main()
{
float b, h; double tri, ret;
printf("Inserire base: "); scanf("%f", &b); printf("Inserire
altezza: "); scanf("%f", &h);
tri = area(b, h, 'T');
ret = area(b, h, 'R');
printf("Il triangolo (b = %f, h = %f) ha area %f\n", b, h, tri);
printf("Il rettangolo (b = %f, h = %f) ha area %f\n", b, h, ret);
}
double area(float base, float altezza, char poligono)
{
switch (poligono) {
case 'T': return (base * altezza/2.0);
case 'R': return (base * altezza);
default : return -1;
}
}
7.8 Passaggio dei parametri
In questo capitolo abbiamo operato una distinzione
tra due tipi di parametri: i parametri formali e i
parametri attuali.
I parametri formali sono quelli dichiarati per tipo,
numero e ordine nella definizione della funzione. I
parametri attuali sono invece quelli che vengono
passati alla funzione all’atto della chiamata.
In C il passaggio dei parametri avviene sempre e
soltanto per valore. Ciò significa che all’atto
dell’invocazione di una funzione ogni parametro
formale
è
inizializzato
con
il
valore
del
corrispondente parametro attuale.
Ecco perché deve esistere una coerenza di tipo e di
numero tra parametri formali e parametri attuali.
Occorre comunque chiarire che non è necessaria la
perfetta corrispondenza. Infatti, nel trasferimento
di valore da
parametro attuale a parametro
formale possono essere effettuate delle conversioni
implicite di tipo. Per esempio,
nel semplice
programma:
main()
{
double c;
c = cubo( 2 );
}
double cubo(float c);
{
return( c*c*c );
}
L’istruzione c= cubo(2) è perfettamente valida poiché la costante intera 2 viene
convertita nella costante di tipo double 2.0 (si ricordi che non esistono in C le
costanti float).
Poiché con il passaggio dei parametri i valori dei parametri attuali sono travasati
nelle locazioni di memoria corrispondenti ai parametri formali, si ha che la
semantica del passaggio dei parametri è quella delle inizializzazioni di variabile:
come per le inizializzazioni sono previste delle conversioni implicite di tipo.
Più in dettaglio, si ha che nel passaggio dei parametri possono avvenire le
conversioni seguenti.
float I parametri attuali float sono convertiti in double prima di essere passati alla funzione. Di conseguenza tutti i parametri formali float
sono automaticamente trasformati in double.
char Tutti i parametri attuali char e short int, che esamineremo nei capitoli successivi, sono convertiti in
int. Di conseguenza tutti i parametri formali char sono trasformati in int.
Occorre poi osservare che non è consentito il passaggio di parametri di tipo array, proprio perché in C il passaggio dei parametri avviene
esclusivamente per valore. Infatti, se il compilatore si trovasse nella necessità di passare un array di tipo int a[1000], occorrerebbe una
quantità di tempo proporzionale per effettuare il travaso di valori tra due array di 1000 int.
Oltre al passaggio esplicito di parametri, è possibile anche il passaggio implicito. Infatti basta definire una variabile globale sia alla funzione
chiamante sia a quella chiamata per ottenere la condivisione della variabile stessa. Si consideri l’esempio del Listato 7.6, in cui la variabile
globale
char str[] = "Lupus in fabula";
è visibile sia dalla funzione main sia dalla funzione lung_string: quest’ultima fa riferimento a str per calcolarne il numero di caratteri,
mentre la funzione main vi fa riferimento per visualizzarne il contenuto.
/*LISTATO 7.6:Passaggio di
7.8 void
parametri con variabile globale*/
Abbiamo trattato il passaggio di parametri e la restituzione di
#include <stdio.h>
un valore da parte di una funzione. Prendiamo ora in esame
char str[] = "Lupus in fabula";
funzioni che non restituiscono alcun valore, e funzioni che non
int lung_string(void);
hanno parametri. In entrambi i casi il C mette a disposizione
main()
un “tipo” speciale detto void.
{
int l;
l = lung_string();
Tipico esempio di funzioni che non restituiscono alcun
printf("La stringa %s ha %d caratteri\n", str, l);
valore è quello delle funzioni il cui scopo è la
}
visualizzazione di un messaggio o, più in generale, la
int lung_string(void)
produzione di un’uscita su uno dei dispositivi periferici. Queste
{
funzioni sono talvolta conosciute con il curioso nome di
int i;
funzioni “lavandino” ( sink, in inglese) poiché prendono dati
for (i = 0; str[i] != '\0'; i++);
che riversano in una qualche uscita, senza ritornare niente al
return i;
chiamante.
}
Un esempio di funzione “lavandino” è la funzione stampa_bin (Listato 7.7).
La funzione stampa_bin divide ripetutamente per 2 il decimale v e memorizza i resti delle divisioni intere nel
vettore a[], che poi legge a ritroso per visualizzare l’equivalente binario del decimale v. nella dichiarazione
void stampa_bin( int );
sia nella definizione
si usa lo specificatore di tipo void per indicare l’assenza di un valore di ritorno.
void stampa_bin( int v )
Viceversa, quando per una funzione non è specificato il tipo void per il valore di
{
ritorno, nel blocco istruzioni della funzione è logico che sia presente per lo meno
...
una istruzione return.
}
Il tipo void è usato anche per le funzioni che non assumono alcun parametro. Un esempio di funzione che non ha parametri e
che non restituisce alcun valore è rappresentato da mess_err (Listato 7.8).
/*_ LISTATO 7.6: esempio di funzione lavandino*/
#include <stdio.h>
#define DIM_INT 16
void stampa_bin ( int );
main() {
char resp[2];
int num;
resp[0] = 's';
while( resp[0] == 's' ) {
printf("\nInserisci un intero positivo: ");
scanf("%d", &num);
printf("La sua rappresentazione binaria è: ");
stampa_bin( num );
printf("\nVuoi continuare? (s/n): ");
scanf("%s",resp);
}
}
void stampa_bin( int v ) {
int i, j;
char a[DIM_INT];
if (v == 0)
printf("%d", v);
else {
for( i=0; v != 0; i++) {
a[i] = v % 2; v /= 2;
}
for(j = i-1 ; j >= 0; j--) printf("%d", a[j]);
} }
/*_ LISTATO 7.7: funzione senza parametri*/
#include <stdio.h>
void mess_err( void );
main()
{
int a, b, c;
printf("Inserire dividendo:");
scanf("%d", &a);
printf("Inserire divisore:");
scanf("%d", &b);
if (b != 0) {
c = a/b;
printf("%d diviso %d = %d\n", a, b, c);
}
else
mess_err();
}
void mess_err( void )
{
int i;
char c;
for (i = 0; i <= 20; i++) printf("\n");
printf(" ERRORE! DENOMINATORE NULLO");
printf("\n Premere un tasto per continuare\n");
scanf("%c%c", &c, &c);
}
La funzione mess_err non prende parametri e
non restituisce alcun valore; essa ha il solo
compito di visualizzare un messaggio di errore nel
caso di inserimento di un denominatore nullo. In C
una funzione che non prende parametri può essere
anche designata semplicemente dalle sole parentesi
tonde, senza usare la
parola chiave void. Per
esempio:
e
void mess_err();
mess_err();
sono dichiarazioni valide. Nel secondo caso, però,
mess_err viene considerata una funzione il cui
eventuale valore di ritorno è di tipo int, anche se in
realtà non ha nessun valore di ritorno. Non è forse
questo il caso anche della funzione main? Abbiamo
continuato a definirla con:
void main(void)
{
...
}
a indicare il fatto che non ritorna nessun valore
è
quindi di tipo void
e che non assume parametri.
ESEMPI
Si scriva un programma che per 10 volte chieda all’utente
un valore e ne calcoli il logaritmo in base 2.
Per il calcolo del logaritmo si scriva una funzione con
prototipo:
double log2(double a);
che calcoli il valore utilizzando la formula
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUM 10
double log2(double valore);
int main()
{
int i;
double a;
for (i=0; i<NUM; i++)
{
printf("Introdurre un numero: ");
scanf("%lf", &a);
printf("Il log2 di %f vale: %f\n", a, log2(a));
}
return EXIT_SUCCESS;
}
/*--------------------------------------------------------*/
double log2(double x)
{
return log(x)/log(2.0);
}
Si scriva una funzione con prototipo: double media(double v[], int len); che calcoli e
restituisca la media di un vettore di double passato come argomento. Si scriva un programma che
riempia due vettori di lunghezza differente (es. a[8] e b[10], li passi a media e visualizzi il
risultato per ciascuno di essi. La funzione non esegua operazioni di input/output.
#include <stdio.h>
#include <stdlib.h>
#define DIM1 8
#define DIM2 10
double media(double vettore[], int lunghezza);
int main()
{ int i;
double a[DIM1], b[DIM2];
printf("Inserire %d valori per a:\n", DIM1);
for (i=0; i<DIM1; i++)
scanf("%lf", &a[i]);
printf("Inserire %d valori per b:\n", DIM2);
for (i=0; i<DIM2; i++)
scanf("%lf", &b[i]);
printf("La media di a vale: %f\n", media(a,DIM1));
printf("La media di b vale: %f\n", media(b,DIM2));
return EXIT_SUCCESS;
}
/*--------------------------------------------------------*/
double media(double v[], int len)
{ double somma=0;
int i;
for (i=0; i<len; i++)
somma += v[i];
return somma/len;
}
Si scriva la funzione sommaVett che calcoli la somma di due
vettori. Si scriva un main che chieda la dimensione dei
vettori (max 100), ne chieda i valori, li passi alla funzione
e visualizzi il vettore dei risultati. Non si alteri il contenuto
dei due vettori da sommare. La
funzione non faccia
input/output.
Per non usare variabili esterne o variabili locali static, alla
funzione bisogna passare anche il vettore dei risultati (il
contenuto iniziale non è rilevante).
/*--------------------------------------------------------*/
void sommaVett(const int a[], const int b[], int r[], int n)
{
int i;
for (i=0; i<n; i++)
r[i] = a[i] + b[i];
}
/* Note
Il vettore da riempire con il risultato della somma viene
allocato nel chiamante (main) e passato alla funzione, il
contenuto iniziale di questo vettore e' irrilevante.
Per garantire la non modifica dei vettori si puo' usare la
clausola const come indicato.
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXNUM 100
void sommaVett(const int a[], const int b[], int r[], int n);
int main()
{
int x[MAXNUM];
int y[MAXNUM];
int risultato[MAXNUM];
int n;
int i;
do {
printf("Lunghezza dei vettori? ");
scanf("%d", &n);
}while (n<1 || n>MAXNUM);
for (i=0; i<n; i++)
{
printf("x(%d): ", i+1);
scanf("%d", &x[i]);
}
for (i=0; i<n; i++)
{
printf("y(%d): ", i+1);
scanf("%d", &y[i]);
}
sommaVett(x, y, risultato, n);
for (i=0; i<n; i++)
printf("risultato(%d): %d\n", i+1, risultato[i]);
return EXIT_SUCCESS; }
esercizi
SOLUZIONE: Esercizio 1 Dati tre numeri interi, individuare il più grande.
47
SOLUZIONE
Esercizio 2
(Programma che acquisisce 9 numeri interi da tastiera e al termine ne
fa la media aritmetica)
Nel programma occorre organizzare un ciclo che acquisisca i numeri, all’interno del ciclo
organizzare l’esame del numero, se pari incrementare una variabile per il conteggio.
SOLUZIONE
Esercizio 3 (Programma che interrompe un ciclo se la somma dei numeri acquisiti
supera una soglia predefiniti pari a 28)
Rappresentato con il diagramma di flusso, il programma appare con struttura molto semplice e la sua
traduzione in C può realizzarsi in più modi.
SOLUZIONE Esercizio 4 (programma che carica in memoria 8 numeri interi; in seguito ne fa la somma)
#include <stdio.h>
#include <stdlib.h>
int z[5];
/* creazione di un vettore di nome z, di tipo intero e costituito
da 4 numeri interi.
NB: in fase di dichiarazione l'indice in parentesi
quadra indica il numero di elementi che
costituiscono il vettore.
int k = 0, s = 0;
/* variabile di conteggio, deve essere impostata a 0
poichè rappresenterà l'indice degli elementi del
vettore z (e il primo elemento ha indice 0); */
int main()
{ while(k <= 7)
{printf("Inserisci un numero intero per z[%d] = ", k);
scanf("%d", &z[k]);
k++;
}
k = 0;
while(k <= 7)
{ s = s + z[k];
k++;
/* il numero digitato da tastiera viene caricato nel
k-esimo elemento del vettore z */
/* aggiornamento della variabile di conteggio */
/* azzeramento della variabile di conteggio */
// ciclo per la somma
}
printf("\nLa somma degli elementi del vettore risulta %d”, s);
system(“pause”);
}
SOLUZIONE
Esercizio 5 (programma che carica in memoria 6 numeri reali, ma interrompe l’acquisizione
nel caso un numero risulti maggiore di 31.5)
#include <stdio.h>
#include <stdlib.h>
int v[6], k = 0;
int main()
{ while (k < 6)
{ printf("Inserisci un numero intero: ");
scanf("%d", &v[k]);
if (v[k] > 31.5)
{ printf(“\nCiclo interrotto”);
break; }
k++;
}
printf(“\nAcquisizione terminata \n");
system(“pause”);
}
SOLUZIONE Esercizio 7
(Programma che ricerca il numero intero più piccolo tra gli elementi di un
vettore di 5 elementi, da acquisire)
1/2
SOLUZIONE Esercizio 8 (Programma che carica in memoria 5 numeri interi; in seguito verifica se
è presente almeno un valore, tra gli elementi del vettore, che si ripete)
1/2
SOLUZIONE Esercizio 9
(Programma che carica in memoria 9 numeri interi e, in seguito, li ordina in senso crescente)
1/2
SOLUZIONE Esercizio 9 Programma che carica in memoria 9 numeri interi e, in seguito, li ordina in senso crescente)
#include <stdio.h>
#include <stdlib.h>
void main(){
int k = 0, x[7], y, h;
while(k < 7)
2/2
// acquisizione del vettore
{printf("\nInserire un valore per x[%d] = ", k);
scanf("%d", &x[k]);
k++;
}
k = 0;
while(k < 6)
{ h = k + 1;
while(h < 7)
{ if(x[h] < x[k])
{ y = x[k];
x[k] = x[h];
x[h] = y;
}
h++;
}
k++;
// ordinamento in senso crescente
}
printf("\nVettore ordinato:");
k = 0;
while(k < 7)
{printf("\n x[%d] = %d ", k, x[k]);
k++;
}
system(“pause”);
}
// visualizzazione del vettore ordinato
SOLUZIONE:Esercizio 6 (programma che carica in memoria 7 numeri interi e informa su
quanti sono dispari e quanti pari)
#include <stdio.h>
#include <stdlib.h>
int x[7], p = 0, d = 0, k = 0;
float dec ;
int main()
{ while (k <= 6)
{ printf("Inserisci un numero intero: ");
scanf("%d", &x[k]);
dec = x[k] / 2.0 – x[k] / 2;
if (dec == 0)
p++;
else
d++;
k++;
}
printf("\nI numeri pari sono %d", p);
printf("\nI numeri dispari sono %d \n", d);
system(“pause”);
}
SOLUZIONE
Esercizio 7
(Programma che ricerca il numero intero più piccolo tra gli elementi di un vettore di 5
elementi, da acquisire)
#include <stdio.h>
#include <stdlib.h> int k = 0,
x[5], y;
int main()
{ while(n < 5)
{printf("\nInserire un valore per x[%d] = ", k);
scanf("%d", &x[k]);
k++;
}
y = x[0]; k = 1;
while(k < 5)
{ if(x[k] < y)
y = x[k];
k++;
}
printf("\nIl numero più piccolo risulta %d \n", y);
system(“pause”);
}
2/2
SOLUZIONE Esercizio
8 (Programma che carica in memoria 5 numeri interi; in seguito verifica se è
almeno un valore, tra gli elementi del vettore, che si ripete)
#include <stdio.h>
#include <stdlib.h>
void main(){
int n = 0, x[5], y, i = 0; while(n < 5)
{printf("\nInserire un valore per x[%d] = ", n); scanf("%d", &x[n]);
n++;
}
while(i < 4)
{ y = x[i]; n = i + 1;
while(n < 5)
{ if(x[n] == y)
{printf("\nIl valore %d si ripete \n", y); break;
}
n++;
}
i++;
}
printf(‘’Non ci sono numeri che si ripetono’’); system(“pause”);
}
2/2
QUARTA
•
•
•
•
•
•
•
•
AUTOMI
classificazione dei sistemi
automi a stati finiti
caratteristiche di un sistema
sistemi a stati finiti ( automi )
modelli di rappresentazione dei sistemi a stati finiti
diagramma di transizione degli stati
ESEMPI
•
•
•
•
•
•
Il plc
segnali a tempo continuo
schemi a blocchi
comportamento in regime permanente
stabilità dei sistemi
plc
AUTOMI
CLASSIFICAZIONE DEI SISTEMI
SISTEMI CONTINUI
Si tratta di sistemi caratterizzati da variabili continue.
Esempio: Circuito elettrico ohmico - capacitivo
Le variabili evolvono con continuità (Sistemi continui) e sono continuamente osservate, cioè il
tempo è rappresentato da una semiretta continua (a tempo continuo).
esempio: Circuito elettrico ohmico - capacitivo
Le variabili sono continue (Sistemi continui), ma i loro valori non sono rilevati con continuità, bensì
a intervalli di tempo (a tempo discreto).
NB: Rientrano in questa classe tutti i sistemi continui controllati mediante controllori digitali.
SISTEMI DISCRETI
Sono sistemi caratterizzati da variabili discrete.
Esempio: Circuito elettrico ‘Interrotta’
Le variabili interruttore e lampada possono
assumere solo due configurazioni (alto/basso,
on/off, aperto/chiuso,
acceso/spento) (Sistema
discreto).
Le loro configurazioni sono rilevate con continuità
nel tempo (a tempo continuo).
esempio: Circuito elettrico ‘Interrotta’
Le variabili interruttore e lampada sono discrete
(Sistema discreto).
Le loro configurazioni sono rilevate a intervalli di
tempo (a tempo discreto).
NB: La classificazione del sistema come sistema discreto e quindi dei componenti Interruttore e
Lampada come componenti discreti risponde alle necessità di chi realizza o utilizza il sistema.
Ma per l’industria che costruisce gli interruttori e le lampade, questi non sono affatto componenti
discreti. La transizione da
uno stato all’altro non è istantanea, ma è caratterizzata da una
progressione continua di cui tener conto in sede di costruzione del componente.
I sistemi discreti a tempo discreto si dividono in due classi:
COMBINATORI
Sistemi in cui le uscite dipendono dal valore
attuale degli ingressi.
SEQUENZIALI
Sistemi in cui le uscite dipendono dal valore attuale
degli ingressi e dello stato.
Esempio: Comando con pulsanti di Marcia/Arresto di
un motore
Sono rappresentati mediante tavole di verità
I1
I2
L
A
A
OFF
A
C
OFF
C
A
OFF
C
C
ON
NB: sono sistemi in cui non vi è memoria della
configurazione degli ingressi negli istanti precedenti
quello attuale.
I sistemi discreti a tempo discreto sequenziali
vengono chiamati anche SISTEMI A STATI FINITI.
AUTOMA A STATI FINITI
L’automa a stati finiti è un sistema digitale, con un numero finito di ingressi ed uscite digitali e con
un numero finito di stati che, essendo numerabili, possono essere rappresentati con una variabile
ancora digitale.
Ricordiamo che:
a) L’informazione associata ad una grandezza elettrica digitale non è legata al valore della
tensione ma a codici numerici binari costruiti con segnali elettrici del tipo ON/OFF
a) L’ingresso
costituisce una sollecitazione che il sistema subisce dall’ambiente esterno
c) L’uscita
costituisce la risposta che il sistema dà all’ambiente esterno quando è stato sollecitato
da uno o più ingressi
d) Lo
stato è la condizione in cui si trova il sistema in un determinato istante e alla quale è
pervenuto in seguito alla sequenza di sollecitazioni subite negli istanti precedenti: questo
implica un effetto “memoria” dal quale non si può prescindere.
Per un sistema, essere in uno stato piuttosto che in un altro vuol dire dare risposte diverse per
lo stesso ingresso.
Caratteristiche di un automa
Ingressi, uscite e stati
l’attività di un automa si esplica come successione di azioni, secondo una gamma fissa
preregistrata (automa stupido ma utile) oppure in risposta a sollecitazioni esterne (automa
intelligente).
Le azioni si susseguono in sequenza, il sistema evolve da una fase operativa alla successiva;
pertanto l’automa è prima di tutto un sistema dinamico o sequenziale, ovvero un sistema
che modifica il proprio stato con l’avanzare del tempo.
Le azioni non hanno luogo con continuità bensì a scatti; dopo una breve fase di transito da
uno stato al successivo, segue una fase di mantenimento di durata maggiore.
Le azioni sono cioè separate da intervalli di tempo finiti, perciò l’automa è anche un sistema
discreto.
Nel compiere il suo ciclo di lavoro l’automa transita attraverso diverse situazioni interne,
dette stati.
Nel corso di un ciclo si verifica una successione di stati e il passaggio da uno stato all’altro è
imposto sia dalla logica operativa intrinseca della macchina, sia da eventuali sollecitazioni
esterne che condizionano il flusso operativo.
Per poter descrivere il funzionamento di un automa in modo preciso e rigoroso, non è sufficiente
ricorrere all’approccio descrittivo con il quale abbiamo esordito, è necessario rappresentare
simbolicamente gli elementi che ne identificano il comportamento e descrivere le relazioni che li
correlano.
Gli elementi fondamentali sono l’insieme degli ingressi, che influenzano l’evoluzione del sistema,
l’insieme degli stati, che originano le sequenze operative e l’insieme delle uscite, che sono gli
elementi utili.
Un insieme di elementi prende il nome di alfabeto. Gli elementi di questi insiemi vengono de
finiti variabili.
Per economia di scrittura, spesso ci si riferisce a un insieme di variabili con un solo simbolo, anzi
ché enumerarle a una a una.
I simboli compatti sono:
insieme variabili di ingresso: I(t)
insieme variabili di uscita: U(t)
insieme variabili di stato: X(t)
L’evidenziazione di ingressi e uscite non è sufficiente per rappresentare l’automa in quanto
mancano gli stati e le relative transizioni
A tale scopo un automa si puo cosi rappresentare:
sezione di memoria: memorizza lo stato attuale;
•sezione logica: prepara lo stato futuro.
•sezione di temporizzazione (clock): sincronizza
l’evoluzione.
Per poter avanzare attraverso la sequenza dei propri stati, una macchina automatica sequenziale
deve ricordare lo stato nel quale si trova (per esempio un orologio ricorda l’ora indicata) e avere
una logica, una intelligenza, che le permetta di costruire, a partire dalla conoscenza dello stato
attuale, lo stato futuro, cioè quello successivo.
La macchina genera allora le uscite (output) in base alle sollecitazioni di ingresso (input) e allo
stato interno, registrato nella propria memoria.
Affinché il meccanismo sia cadenzato, è necessario poi un segnale che disciplini l’emissione delle
sequenze, cioè blocchi il sistema nel proprio stato per un dato intervallo di tempo, dopodiché dia
via libera alla transizione allo stato successivo.
Il segnale di clock svolge il ruolo di temporizzazione, chiudendo e aprendo il circuito, quindi
bloccando o rilasciando il processo di avanzamento degli stati.
esempio: Orologio digitale
L’orologio può essere senz’altro classificato come automa. È un sistema dinamico, dato che
evolve nel tempo; è discreto perché compie il passaggio da una condizione a quella
successiva a intervalli regolari distanziati da intervalli di tempo finiti. Consideriamo per
semplicità un orologio costituito solo dalle cifre dei minuti, rappresentate simbolicamente
DM = Decine dei Minuti
UM = Unità dei Minuti
DM e UM sono in questo caso le variabili di uscita.
L’orologio potrebbe poi disporre di due pulsanti, con stampigliate le sigle:
AVM: avanzamento veloce minuti
ALM: avanzamento lento minuti
Queste sono le variabili di ingresso.
A queste indicazioni corrisponde allora il blocco
mostrato a fianco come:
Esempio: Apertura a combinazione
Si consideri una cassaforte con apertura a combinazione a 4 cifre. La sequenza numerica vie ne
immessa facendo ruotare alternativamente a destra e a sinistra, in corrispondenza delle tacche
numeriche, la manopola che comanda il congegno di apertura, introducendo una sequenza
numerica prefissata.
Supponendo che la combinazione prefissata sia 1357 per essere sicuri di non scordarsi la
combinazione, ci si può limitare a memorizzare solo il primo numero della sequenza e affidarsi,
per la ricostruzione della sequenza, allo schema logico consistente nel sommare ogni volta 2 alla
cifra precedente.
La funzione di memoria è strettamente correlata con lo stato. È la memoria del sistema a
conservare lo stato, la condizione attuale.
La successione passata degli stati rappresenta la “storia” del sistema; in base a questa storia si
costruiscono gli stati futuri.
Gli stati si indicano simbolicamente con la lettera maiuscola S seguita da un indice numerico
progressivo, ovvero S0, S1, S2 ...
Lo stato presente viene chiamato stato attuale e indicato come S(t), lo stato al passo successivo
viene chiamato stato futuro e indicato come S(t + 1). Si noti che si è parlato di passo e non di
istante di tempo in qaunto Il funzionamento di un automa è indipendente dall’entità del passo
«clock»
stati S1, S2, S3, S4 ----- : 1 ➞ 3 ➞ 5 ➞ 7.
Esempio: Automa che genera la sequenza dei numeri naturali
Questo esempio dovrebbe fare luce su quanto detto ora. Un sistema, per generare
automaticamente la sequenza 0, 1, 2, 3 …, deve possedere una memoria (per conoscere il numero
appena generato) e una logica (per costruire il numero successivo in base al numero appena
generato).
In questo caso la logica è molto semplice e consiste nel sommare 1 al numero appena generato.
La tabella descrive sinteticamente
questo processo.
Conteggio pezzi
Un sistema per imballaggio conta tramite fotocellula delle lattine, prima di confezionarle. Ogni tre
lattine deve terminare il ciclo di conteggio e iniziare quello di imballaggio. Il conteggio avviene alla
rovescia partendo da 3.Rappresentare la sequenza degli stati del ciclo di conteggio.
la numerazione S3, S2, S1, S0 della sequenza
degli stati è convenzionale, ma viene fatta
coincidere con il conteggio per linearità di
ragionamento
Esempio: Serbatoio
Il sistema è costituito da:
a) un serbatoio d’acqua
b) un sensore SH per segnalare il raggiungimento del livello
massimo
c) un sensore SL per segnalare il raggiungimento del livello minimo
d) una elettrovalvola di carico VC
e) una valvola di scarico VS
f) un automa per la gestione delle operazioni secondo le modalità di
seguito indicate
Funzionamento:
Fase di scarico: partendo dalla condizione di serbatoio pieno, la valvola di carico VC è chiusa,
bloccando l’afflusso di acqua nel serbatoio, fino a quando il livello non scende al di sotto del valore
minimo per effetto del deflusso ottenuto manovrando la valvola di scarico VS.
Fase di carico: quando il livello minimo è stato raggiunto, la valvola VC viene aperta e resta aperta
fino a quando il serbatoio non si riempie raggiungendo il livello massimo, dopodiché si riparte con
la fase di scarico.
Nota: è abbastanza intuitivo che, per un buon funzionamento, la portata associata alla valvola di
carico VC sia maggiore di quella associata alla valvola di scarico VS.
Osservazione
Quando il livello dell’acqua è compreso tra quello massimo e quello minimo, i sensori generano per
l’automa lo stesso ingresso, sia durante la fase di carico che durante quella di scarico. E’
importante quindi che il sistema di controllo (automa) abbia una memoria che gli ricordi in quale
fase si trova, consentendogli di reagire con la giusta uscita (apertura o chiusura della valvola VC).
SERBATOIO
Un modo semplice per illustrare il comportamento del sistema di controllo è quello di utilizzare un diagramma
di stato come quello rappresentato nella Fig. 9.
SISTEMI A STATI FINITI
( AUTOMI )
• Gli automi a stati finiti sono sistemi dinamici, stazionari, con ingressi, stato, uscite e tempo
• discreti
• Sono dinamici i sistemi dotati di memoria (Es: flip-flop JK).
• La memoria è costituita dallo stato del sistema.
• Definizione: lo stato rappresenta una situazione in cui il sistema si trova per
effetto delle configurazioni degli ingressi negli istanti precedente
• Sono stazionari i sistemi i cui parametri restano costanti nel tempo.
•
NB: i sistemi a stati finiti sono una classe di sistemi molto importante in cui rientrano la
logica di controllo delle macchine utensili,
• il funzionamento di un sistema operativo per PC
• Il funzionamento di una lavatrice
• ……………………………………..
AUTOMA DI MEALY
Nel modello di Mealy l’uscita dipende dalla elaborazione,
da parte di una rete combinatoria, degli ingressi e dello
stato attuale.
Le uscite commutano durante la transizione dallo stato
attuale allo stato futuro (sia per i sistemi sincroni che
asincroni).
AUTOMA DI MOORE
Nel modello di Moore l’uscita dipende
dalla
elaborazione,da parte di una rete combinatoria,
del solo stato attuale.
MODELLO DI HUFFMAN
E un modello generale per rappresentare un
automa: un unico sottosistema combinatorio
retroazionato con elementi di memoria.
Gli elementi di memoria sono dei flip flop
(sincroni o asincroni): uno per ogni variabile
di stato.
CONFRONTO TRA L’AUTOMA DI MEALY E L’AUTOMA DI MOORE
La sintesi di un sistema a stati finiti può essere realizzata sia con il modello di Mealy che con
quello di Moore.
Tuttavia cambiano la complessità e le prestazioni del sistema costruito.
Automi di Mealy
•Sono più veloci, gli ingressi giungono
direttamente sul circuito delle uscite.
• Hanno un minor numero di stati, potendo
associare le uscite alle transizioni
Sono possibili uscite spurie transitorie
dovute a percorsi diversi, con differenti
ritardi di propagazione, cui gli ingressi sono
soggetti.
Automi di Moore
•Sono meno veloci, gli ingressi causano
direttamente solo il cambiamento dello
stato; le uscite si aggiornano dopo che il
nuovo stato si è stabilizzato.
•Hanno un maggior numero di stati, dovendo
associare le uscite agli stati
•Si
ottiene
un
maggior
controllo
sull’evoluzione
della macchina, grazie
all’aggiornamento delle uscite subordinato
al raggiungimento del nuovo stato
.
•Sono più facilmente testabili
MODELLI DI RAPPRESENTAZIONE DEI SISTEMI A STATI FINITI
Il funzionamento di un automa può essere illustrato (descritto) mediante:
• TABELLA di transizione degli stati e TABELLA delle uscite
• DIAGRAMMI di transizione degli stati
ESEMPIO: riconoscitore di sequenza per sblocco meccanismo
Descrizione: il sistema deve riportarsi allo stato iniziale ogni volta che riceve in ingresso un
carattere non valido.
Configurazioni valide per l’ingresso: {A, B, C, D, E, F}
Configurazioni previste per l’uscita: {blocco, sblocco}
Sequenza valida: BDA
La corrispondenza della logica di controllo (sistema) al modello di Mealy oppure di Moore è spesso
una scelta del progettista.
AUTOMA DI MEALY
La tabella di transizione degli stati descrive l’evoluzione dello stato del sistema in funzione dello
stato attuale e dell’ingresso:
Poiché le uscite dipendono oltre che dallo stato, anche dagli ingressi, per la loro indicazione si deve
costruire la tabella delle uscite:
AUTOMA DI MOORE
Poiché le uscite sono definite in corrispondenza degli stati, esse sono indicate nelle stesse
celle degli stati futuri.
DIAGRAMMA DI TRANSIZIONE DEGLI STATI
Il funzionamento di un automa può essere descritto anche con i diagrammi di transizione degli
stati (o grafi).
•A ogni nodo è associato uno stato ( x )
• A ogni arco è associato un ingresso, la freccia
indica la direzione della transizione di stato
causata dall’ingresso specificato
•Autoanello: transizione che parte e giunge sullo
stesso stato
• Lo stato iniziale
doppio cerchio.
viene
rappresentato
con
un
Esercizio precedente:
PASSI (Algoritmo) PER LO STUDIO DEGLI AUTOMI
Descrizione del sistema:
• Definizione degli ingressi, degli stati e delle uscite (attribuzione dei
configurazioni possibili)
simboli e esame delle
• Individuazione di uno stato iniziale da cui cominciare la costruzione
diagramma
della tabella o del
• Costruzione della tabella o del diagramma.
NB: si può cominciare da uno stato iniziale qualsiasi, normalmente si sceglie quello più comodo.
Il sistema di controllo, descritto mediante diagramma di transizione degli stati o mediante tabelle
di transizione, può essere implementato (realizzato) con
• hardware cablato per la specifica applicazione
• hardware programmabile, scrivendo uno specifico software di controllo.
• Il linguaggio di programmazione è il C ANSI, con compilatore Dev-C++.
ESEMPIO Comando di marcia / arresto di un motore
Descrizione del sistema
Il sistema di controllo è molto semplice: mediante due pulsanti si comanda la marcia e
l’arresto di un motore.
NB: occorrerebbe prevedere un terzo pulsante che ponga termine al controllo.
Definizione degli ingressi
Gli ingressi sono due pulsanti normalmente aperti (Marcia, Arresto), che possono assumere
solo due configurazioni (P: premuto, R: a riposo).
Definizione degli stati
Lo stato del sistema può essere rappresentato dal contatto di potenza oppure dalla
condizione del motore: F = fermo, M = in marcia.
Definizione delle uscite
L’uscita è rappresentata dal comando (COM) che si vuole esercitare sul motore. E’ un segnale
a due livelli (avvio motore, arresto motore).
Può essere associato allo stato: uscite = stato. Di conseguenza: modello di Moore.
Individuazione stato iniziale
Si deve decidere se cominciare con il motore fermo o in marcia. Ipotesi: motore fermo.
Scrivere il software di controllo.
Schema generale
Descrizione della logica di controllo mediante: diagramma di transizioni degli stati.
Automa di Moore.
Il software di controllo presenta fondamentalmente due sezioni:
• sezione di inizializzazione: in cui scrivere il codice da eseguire una sola volta, all’inizio
• sezione sotto scansione ciclica: in cui si scrive il codice di controllo, la cui esecuzione è
ripetuta ciclicamente.
Esempio di software di controllo:
ESEMPIO: COMANDO PUNTO LUCE: MEDIANTE RELE’ INTERRUTTORE
Descrizione del sistema
Il sistema è costituito da due pulsanti, un relè interruttore (con due posizioni di lavoro),
una lampada.
Premendo indifferentemente uno dei due pulsanti lo stato dei contatti del relè
interruttore commuta, e di conseguenza commuta anche lo stato della lampada.
Definizione degli ingressi
Gli ingressi sono due pulsanti normalmente aperti (S1, S2), che possono assumere solo
due configurazioni (P: premuto, R: a riposo).
(su scheda Velleman: Rilasciato = lettura 0)
Definizione degli stati
Lo stato del sistema può essere rappresentato dal contatto del relè oppure dallo stato della
lampada: contatto aperto = Lampada spenta, contatto chiuso = Lampada accesa. Simbolo L
= (ON, OFF).
Definizione delle uscite
L’uscita della logica di controllo è rappresentata da un comando impulsivo COM, che fa
commutare il relè.
Individuazione stato iniziale
Si deve decidere se cominciare con il contatto aperto o chiuso. Ipotesi: contatto aperto.
Schema generale
Soluzione
Costruzione del diagramma di transizione degli stati
Occorre scegliere quale rappresentazione utilizzare: Mealy o Moore?
Il sistema è molto semplice; l’uscita (il contatto di potenza) può essere fatta
corrispondere allo stato. In questo caso la rappresentazione è quello di Moore.
ESEMPIO: CONTROLLO TRAPANO AUTOMATICO
Descrizione del sistema
Premendo il pulsante S0 si alimenta il motore M1.
Il carrello porta utensile scende alla velocità v1.
L’attivazione del finecorsa S2 modifica la velocità di discesa del carrello
v2 < v1 e attiva il motore M2.
L’attivazione del finecorsa S3 disattiva il motore M2 a fa salire alla
velocità v1 il carrello.
L’attivazione del finecorsa S1 arresta il motore M1.
Schema generale
Definizione degli ingressi
Gli ingressi sono costituiti dal pulsante S0 e dai finecorsa S1, S2, S3.
Si tratta di segnali che possono assumere solo due configurazioni:
Pulsante: S0 = Rilasciato, Premuto
(su scheda Velleman: Rilasciato = lettura 0)
Finecorsa: S1, S2, S3= Rilasciato, Premuto
soluzione: Diagramma di transizione degli stati
NB: si dovrebbero assumere opportune precauzioni per evitare l’invio di comandi contraddittori
(interblocco)
ESEMPIO: MISCELATORE
Descrizione del sistema
Il sistema miscela due liquidi. Componenti:
•pulsanti S1, S2 normalmente aperti
•elettrovalvole M1, M2, M3 normalmente chiuse
•sensori di livello B0, B1, B2 normalmente aperti (asciutti), si chiudono in
presenza del liquido
• motore M0
Premendo S1 si avvia il ciclo, previa verifica di serbatoio vuoto (altrimenti
provvedere allo svuotamento).
Fasi del ciclo:
•con serbatoio vuoto (B0, B1, B2 asciutti) , elettrovalvole M2 e M3 chiuse,
motore fermo: si fa entrare il 1° liquido aprendo l’elettrovalvola M1;
• durante il riempimento si attiva B0: nessun intervento del controllo
•attivazione di B1: chiusura di M1, apertura di M2 (entrata del 2° liquido) e
avvio del motore
• attivazione di B2: chiusura di M2 e apertura di M3 (inizio scarico)
• disattivazione di B2: nessun intervento di controllo
• disattivazione di B1: arresto motore M0
• disattivazione di B0: chiusura M3 e ripetizione del ciclo.
NB: con serbatoio vuoto, premendo S2 il sistema si porta allo stato iniziale di riposo.
Definizione degli ingressi
Gli ingressi sono rappresentati dal pulsante S1 normalmente aperto e i tre sensori di livello
normalmente aperti.
Definizione degli stati
L’identificazione degli stati dipende dal modello:
• Moore: ad ogni uscita diversa occorre associare uno stato
• Mealy: possibile accorpare più stati
Definizione delle uscite
Le uscite rappresentano i comandi che il sistema di controllo deve emettere: il motore e le
tre elettrovalvole.
Individuazione stato iniziale
Si deve prevedere uno stato di attesa, da cui uscire con l’attivazione del pulsante S1.
Soluzione: modello di Moore
Soluzione: modello di Mealy
Esempio di software di controllo:
MISCELATORE: MOORE
Soluzione : modello di Mealy
Esempio di software di controllo:
MISCELATORE: MEALY
ESEMPI0:
Distributore di bibite
Costo della bibita: 40 €cent
Monete utilizzabili: 10 €cent , 20 €cent
Il sistema, oltre alla parte che gestisce l’automa, prevede:
a) una gettoniera che generi un codice numerico binario per ognuna delle due monete e per
la condizione di riposo (nessuna moneta)
b) un dispositivo che, su comando dell’automa, sganci la bibita
c) un dispositivo che, su comando dell’automa, sganci il resto
Si noti che per l’ingresso occorrono due bit, perché sono da codificare 3 condizioni diverse, e
quindi due linee (X1 e X0). I comandi per lo sgancio, invece, richiedono un bit ciascuno
perché ognuno di loro prevede solo due condizioni (sganciare o non sganciare): necessita
quindi una sola linea per ogni comando (B e R).
In situazioni diverse, dove ci siano più tipi di monete oppure più tipi di bibite oppure più
possibilità di resto, cresce il numero di condizioni da considerare e quindi cresce anche il
numero di bit e con esso il numero di linee.
Formalizziamo le variabili utilizzate.
Ingressi X1 X0 (binari):
Nessuna moneta (00); Moneta da 10 €cent (01); Moneta da 20 €cent (10).
Totale: 2 linee di ingresso (2 bit).
Uscite (binarie):
Comando per lo sgancio della bibita B (0/1); Comando per lo sgancio del resto R (0/1).
Totale: 2 linee di uscita (2 bit), una per il sottosistema di sgancio della bibita ed una per il
sottosistema di sgancio del resto.
Come per gli ingressi, è possibile fondere insieme le due uscite utilizzando una sola variabile a 2
bit. ( Es.: BR = 00 né bibita né resto; 01 non ammesso; 10 solo bibita, 11 bibita + resto ).
Stati:
Gli stati corrispondono alla somma di volta in volta accumulata con l’introduzione delle monete.
Risultano 5 stati: 0 €cent, 10 €cent, 20 €cent, 30 €cent.
In questo caso non servono variabili ma una locazione di memoria
Diagramma degli stati
Per descrivere le evoluzioni nel tempo del sistema, ovvero come esso passi da uno stato all’altro
quando viene sottoposto alle sollecitazioni degli ingressi esterni, vengono utilizzati i diagrammi di
stato.
La rappresentazione viene fatta utilizzando per ogni stato un cerchio (nodo) che porta indicato al
proprio interno il nome dello stato (S0 , S1 , …. oppure A, B, ….), e collegando i vari nodi con degli
archi orientati che indicano l’evoluzione da uno stato all’altro. Per completare i diagrammi,
vengono aggiunte le indicazioni sugli ingressi che generano l’evoluzione da uno stato all’altro e
sulle uscite corrispondenti a tale evoluzione.
Modello di Mealy:
in tale modello, nello stato terminale di una evoluzione non è possibile conoscere l’uscita se non
si conosce contemporaneamente anche l’ingresso che ha portato l’automa in quello stato (uno
stesso stato
possibilità di più uscite).
Per tale motivo, accanto agli archi orientati corrispondenti alle evoluzioni generate dagli
ingressi, vengono indicati sia gli ingressi stessi che le uscite (separati da una barra).
Modello di Moore:
in tale modello, noto lo stato raggiunto, è nota l’uscita corrispondente (uno stato una uscita). Per
tale motivo gli ingressi vengono indicati accanto agli archi orientati corrispondenti alle evoluzioni
che essi generano, mentre l’uscita viene indicata accanto al nome dello stato, all’interno del cerchio
rappresentativo dello stato stesso.
Per meglio comprendere la differenza tra modello di Mealy e modello di Moore, scegliamo di
utilizzare inizialmente il primo tipo; successivamente, con qualche piccola modifica al diagramma
ottenuto, passeremo all’altro tipo. Scopriremo che il modello di Moore, pur avendo di norma più
stati, consente una semplificazione del software.
La Fig. 6 illustra una prima stesura del diagramma di stato (automa di Mealy); una seconda stesura
si otterrà per passare al modello di Moore (Fig. 7); una terza ed ultima stesura (Fig. 8) si renderà
necessaria per risolvere alcuni problemi legati all’implementazione fisica dell’automa.
1) automa di Mealy)
Prima di procedere con la descrizione del diagramma di figura, occorre chiarire che lo schema
rappresentato indica tutte le possibili situazioni che possono presentarsi nella realtà.
Ad esempio, con una sequenza costituita da una moneta da 20c seguita da un’altra moneta da
20c, la macchina, partendo dallo stato di riposo “0c” passa prima allo stato “20c” e poi da questo
salta allo stato di riposo “0c”, dopo aver dato la bibita senza resto (Uscita “1/0c”).
Ancora, con una sequenza costituita da una moneta da 20c seguita da un’altra da 10c e ancora da
un’altra da 20c la macchina, partendo dallo stato di riposo “0c” passa prima allo stato “20c”, poi
allo stato “30c” e infine allo stato di riposo “0c”, dando la bibita con un resto di 10c (Uscita
“1/10c”).
E così via.
Ovviamente, se non viene raggiunto o superato il valore della bibita, l’automa resta in uno stato
intermedio con le uscite bloccate a “0/0c”.
a) Lo stato “0c” è lo stato di riposo; quello cioè in cui si trova la macchina quando è in attesa
di un nuovo ciclo per l’acquisto della bibita.
L’uscita è “0/0c” perché non devono essere dati né la bibita né il resto.
Con 10c si passa allo stato “10c”, mentre se la moneta introdotta è da 20c si passa allo stato
“20c”.
Quando l’ingresso è “0c” (nessuna moneta introdotta), la macchina rimane sullo stesso stato.
Da notare che i nomi degli stati rappresentano anche l’ammontare di moneta introdotta. Per
tutti gli ingressi fin qui citati non devono essere dati né la bibita né il resto, non avendo
raggiunto una somma pari al valore della bibita (Uscita 0/0c).
b)Quando
la macchina è nello stato “10c” l’introduzione di una moneta da 10c la porta nello stato
“20c”, già visto; se la moneta , invece, è da 20c la macchina va nello stato “30c”.
Ancora una volta, non essendo stato raggiunto il valore della bibita, la macchina non deve dare
niente in uscita (Uscita 0/0). Quando l’ingresso è “0c” (nessuna moneta introdotta), la macchina
rimane sullo stesso stato.
C) Nello stato “20c” l’introduzione di una moneta da 10c fa passare la macchina nello stato “30c”,
senza alcuna conseguenza sull’uscita, mentre l’introduzione di una moneta da 20c la fa tornare
nello stato “0c”.
In quest’ultimo caso, avendo raggiunto il valore della bibita, la stessa viene sganciata senza alcun
resto (Uscita “1/0c”). Quando l’ingresso è “0c” (nessuna moneta introdotta), la macchina rimane
sullo stesso stato.
d) Nello stato “30c” l’introduzione di una moneta o da 10c o da 20c fa tornare la macchina nello stato
di riposo “0c”: nel primo caso viene raggiunto esattamente il valore della bibita, per cui viene
sganciata la stessa senza resto (Uscita 1/0c); nel secondo caso, invece, viene superato il valore della
bibita, per cui vengono sganciati bibita e resto da 10c (Uscita 1/10c). Quando l’ingresso è “0c”
(nessuna moneta introdotta), la macchina rimane sullo stesso stato.
Tabelle di transizione di stato e di trasformazione di uscita
Tali tabelle hanno entrambe come indicatori di riga lo stato attuale e come
l’ingresso. Al loro interno riportano, rispettivamente, lo stato futuro e l’uscita.
indicatore di colonna
Nella Tab. a) è possibile conoscere lo stato futuro
incrociando stato attuale ed ingresso.
Analoga cosa vale per la Tab. b), con riferimento
all’uscita.
Come si può controllare anche dal diagramma degli stati, quando, ad esempio, se lo stato attuale è
“30c” e viene introdotta una moneta da 10c, la macchina si porta nello stato di riposo “0c” (stato
futuro) e dà come uscita “1/0c” (bibita senza resto).
Queste tabelle sono fondamentali per il progetto dell’automa in logica cablata, mentre in logica
programmata possono essere utilizzate o meno, a seconda della soluzione scelta.
all’automa di Moore,
Rispetto all’automa di Mealy, l’uscita è legata solo
allo stato cui fa riferimento, per cui
essa viene
direttamente indicata nel cerchietto rappresentativo
dello stato stesso.
Per garantire questa condizione per tutti gli stati, è
stato necessario aggiungere qualche stato in più.
La situazione cambia nel modo seguente:
a) Lo stato “0c” è lo stato di riposo; quello cioè in cui si trova la macchina quando è in attesa di
un nuovo ciclo per l’acquisto della bibita.
L’uscita è “0/0c” perché non devono essere dati né la bibita né il resto.
Con 10c si passa allo stato “10c”, mentre se la moneta introdotta è da 20c si passa allo stato
“20c”.
Quando l’ingresso è “0c” (nessuna moneta introdotta), la macchina rimane sullo stesso stato.
Per tutti gli stati fin qui citati non devono essere dati né la bibita né il resto, non avendo
raggiunto una somma pari al valore della bibita (Uscita 0/0c).
Quando la macchina è nello stato “10c” l’introduzione di una moneta da 10c la porta nello stato
“20c”, già visto; se la moneta , invece, è da 20c la macchina va nello stato “30c”. Ancora una
volta, non essendo stato raggiunto il valore della bibita, la macchina non deve dare niente in
uscita (Uscita 0/0c). Quando l’ingresso è “0c” (nessuna moneta introdotta), la macchina rimane
sullo stesso stato.
b)Nello stato “20c” l’introduzione di una moneta da 10c fa passare la macchina nello stato “30c”,
mentre l’introduzione di una moneta da 20c la fa passare nello stato “40c”.
In quest’ultimo caso, avendo raggiunto il valore della bibita, la stessa viene sganciata senza alcun
resto (Uscita “1/0c”).
Quando l’ingresso è “0c” (nessuna moneta introdotta), la macchina rimane sullo stesso stato.
c) Nello stato “30c” l’introduzione di una moneta da 10c fa passare la macchina nello stato “40c”,
mentre l’introduzione di una moneta da 20c la fa passare nello stato “50c”.In entrambi i casi viene
quindi raggiunto o superato il valore della bibita: nel primo caso viene sganciata la sola bibita
(Uscita 1/0c); nel secondo vengono sganciati bibita e resto da 10c (Uscita 1/10c). Quando
l’ingresso è “0c” (nessuna moneta introdotta), la macchina rimane sullo stesso stato.
d)Gli stati “40c” e “50c” sono di chiusura per il ciclo di acquisizione della bibita. Nel primo viene
rilasciata solo la bibita, nel secondo la bibita e il resto di 10c.
In entrambi i casi, essendosi chiuso il ciclo per l’acquisizione del prodotto, il sistema si riporta
nello stato di riposo. Si noti che gli ingressi 10c e 20c non avranno mai la possibilità di
presentarsi in questi due stati finali, perché il ritorno a zero dei segnali provenienti dalla
gettoniera, dopo il passaggio dell’ultima moneta (Ingresso “0c”), avrà già resettato la macchina
portandola nello Stato “0c”.
In ultima analisi, nei due stati finali, gli ingressi 10c e 20c rappresentano condizioni di indifferenza
(don’t care) e questo giustifica la X sulle evoluzioni finali che portano allo stato di riposo.
Tabelle di transizione di stato e di trasformazione di uscita
In questo caso, trattandosi di un automa di Moore per il quale l’uscita è legata solo allo stato, la
tabella di trasformazione di uscita non ha l’ingresso come indicatore di colonna (tabella ad una
sola dimensione).
STATO
FUTURO
STATO
ATTUALE
INGRESSO
USCITA
0c
10c
20c
0c
0c
10c
20c
0c
0/0c
10c
10c
20c
30c
10c
0/0c
20c
20c
30c
40c
20c
0/0c
30c
30c
40c
50c
30c
0/0c
40c
0c
0c
0c
40c
1/0c
50c
0c
0c
0c
50c
1/10c
Tab. c) Transizione di stato
Tab. d) Trasformazione di uscita
Come si può controllare anche dal diagramma degli stati, quando, ad esempio, lo stato attuale
è “30c” e viene introdotta una moneta da 10c, la macchina si porta nello stato “40c” (stato
futuro) e dà come uscita “1/0c” (bibita senza resto).
Per concludere, occorre ribadire che se si vuole rendere esecutivo il progetto bisogna
curare attentamente l’interfaccia con l’hardware, per cui può essere necessario in certi casi
apportare qualche correttivo al diagramma degli stati, che non ne cambia la struttura logica
ma semplicemente corregge certe situazioni
prodotte dalla suddetta necessità di
interfacciare l’hardware.
E’ questo il caso degli “Stati trappola”.
L’aggiunta di questi stati al diagramma si rende necessaria quando accade che un ingresso
che porta in uno stato fa anche uscire da quello stato. Il più delle volte succede che il ciclo
di acquisizione del microprocessore legga l’ingresso migliaia di volte per lo stesso stato,
innescando una deriva che porta il sistema ad evolvere velocemente da uno stato all’altro,
come impazzito.
Il problema si risolve inserendo tra due stati un terzo stato che blocchi l’evoluzione tra i
primi due finché l’ingresso non si è di nuovo azzerato: questo è il motivo per cui tale stato
aggiunto è stato qui definito “trappola”. La Fig. 8 riporta il diagramma di stato del
distributore di bibite modificato a questo scopo
Con riferimento alla Fig. 8, si veda ad
esempio quello che succede nello stato
“20c” con un ingresso 10c: il sistema si
porta nello stato “30 bis” e lì rimane
bloccato finché l’ingresso non si azzera;
azzeratosi l’ingresso, l’automa evolve
verso lo stato “30c”.
Si noti che i due stati di chiusura “40c” e
“50c” non sono preceduti da stati
trappola perché essi stessi fungono da
trappola; bisogna solo stare attenti a
sganciare bibita e/o resto una sola volta.
Le nuove tabelle di transizione di stato e di trasformazione
di uscita diventano:
STATO ATTUALE
INGRESSO
0c 10c 20c
0
0
10b 20b
10b
10
20b
20
30b
30
40
50
10
10
20
20
30
30
0
0
10b
20b
20b
30b
30b
40
40
50
10b
30b
20b
40
30b
50
40
50
STATO
FUTURO
USCITA
0
10b
10
20b
20
30b
30
40
50
0/0c
0/0c
0/0c
0/0c
0/0c
0/0c
0/0c
1/0c
1/10c
PLC
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
logica di controllo
Architettura dei istemi di controllo
IL PLC
campo di utilizzo del PLC
controllo del processo
componentistica
funzionamento base dei PLC
Linguaggio di programmazione "ladder"
organizzazione della produzione
installazione- manutenzione - ricerca guasti
considerazioni sulla scelta del PLC
linee di produzione con il PLC
LOGICA DI CONTROLLO
Una automazione può, oggi, essere realizzata secondo due diverse tecnologie.
In passato la logica di controllo era implementata (realizzata) attraverso la tecnologia cablata: i
circuiti di controllo erano realizzati collegando i componenti mediante cavi (cablaggio).
Con questa tecnologia elettromeccanica (relè, temporizzatori) cablata si realizza, ancora oggi, un
controllo:
•rigido (poco flessibile)
•molto ingombrante
•con notevole consumo energetico.
Nel corso del ‘900 lo sviluppo dell’automazione ha reso sempre più complicato il cablaggio dei
quadri di controllo.
Il numero di componenti (relè, temporizzatori) impiegati nella logica cablata è cresciuto
esponenzialmente e la gestione dei quadri di controllo è divenuta molto complessa.
Alla luce dello sviluppo dell’elettronica integrata, nel 1968 la General Motors, allo scopo di ridurre
i costi e le difficoltà derivanti dalla tecnologia cablata, emanò delle specifiche che i nuovi
controllori, fondati sulla tecnologia programmabile e destinati a sostituire i quadri di controllo
(cablati), avrebbero dovuto rispettare.
Dall’applicazione di quelle specifiche nacque il PLC (Programmable Logic Controller). Oggi il più
diffuso controllore programmabile nell’automazione industriale.
Una automazione realizzata con tecnologia programmabile comporta la scrittura di un software
per il controllo.
Ciò consente di modificare il controllo semplicemente riscrivendo il software. Si realizza quindi
un sistema molto flessibile.
Realizzato con tecnologia programmabile elettronica, il controllo consente:
•minori consumi energetici
•minore ingombro.
NB: A parità di tecnologia, un circuito di controllo cablato risulta comunque più veloce di uno
programmabile. Ciò è dovuto all’assenza nel circuito cablato delle fasi di decodifica delle
istruzioni.
Nel 1973 si costruirono i primi PLC in grado di comunicare tra loro. Tuttavia la mancanza di
standard comuni rese incompatibili le reti di costruttori diversi.
Negli anni ’80, ancora la General Motors rese i PLC programmabili tramite Personal Computer
(invece che con tastiera dedicata).
Negli anni ’90 sono stati costruiti PLC con ingombri ridotti e si è proceduto a una parziale
convergenza dei protocolli.
ARCHITETTURA DEI SISTEMI DI CONTROLLO
ARCHITETTURA TRADIZIONALE
Il
PLC è collegato ai sensori e agli
attuatori
attraverso
un
collegamento punto a punto.
Vantaggi
• Affidabilità Svantaggi
•Elevato costo dei cablaggi
• Bassa
flessibilità
(Espandibilità)
3
Flessibilità: capacità di un sistema
di
controllo di configurarsi e
ampliarsi
semplicemente
aggiungendo componenti.
ARCHITETTURA A BUS
Il PLC è collegato ai sensori e agli attuatori
attraverso un bus.
Bus: insieme di linee di collegamento, cui
accedono sia il PLC che i sensori e gli attuatori.
NB: sensori e attuatori devono essere del
tipo intelligente.
Vantaggi:
• Flessibilità (Espandibilità) (possibilità di
aggiungere altri componenti)
• Intelligenza distribuita (decentramento di
funzioni)
Svantaggi:
• Maggior costo dei componenti
• Assenza di standard comuni tra costruttori
(con conseguenti problemi di affidabilità di
funzionamento).
ARCHITETTURA SCADA
(Supervisor Control And Data Acquisition)
Un sistema SCADA è un sistema in cui il software permette una alta possibilità per l’operatore di
interfacciarsi col processo.
Un grande vantaggio è rappresentato dalla Scalabilità: capacità di un sistema di controllo di
adattarsi alle necessità aggiungendo utenti o risorse (proprietà tipiche dei sistemi in rete).
IL PLC
Il
PLC è un dispositivo o sistema digitale elettronico che utilizza una memoria programmabile per
memorizzare informazioni o istruzioni, atte a realizzare specifiche funzioni, finalizzate al controllo di sistemi
combinatori e sequenziali per la gestione di macchine e processi, quali: operazioni logico-aritmetiche,
temporizzazioni, conteggi, comparazioni, codifiche, decodifiche".
i PLC , oltre alle funzioni strettamente logiche (AND,OR,NOT etc.) sono in grado di eseguire conteggi,
temporizzazioni,comparazioni, calcoli numerici, ed altre operazioni di manipolazioni di dati in formato bit, byte, word
(come ad esempio operazioni di SHIFT, TEST su BIT, ed altre).
I più evoluti tra essi oramai possono essere paragonati a dei veri e propri Personal Computer, per cui si potrebbe anche
chiamarli IPC (Personal Computer Industriali).
In altre parole, un PLC può essere definito come uno speciale elaboratore, di tipo industriale, (Avente cioè
caratteristiche ben precise che gli consentono di lavorare con assoluta affidabilità in un ambiente difficile e gravoso, come
può esserlo un ambiente industriale, per la presenza notevole di disturbi elettrici, vibrazioni, ampie variazioni di
temperatura ed umidità, polveri etc.) concepito per risolvere problemi di controllo ed automazione e che si
differenzia dal PC soprattutto per quanto riguarda il linguaggio di programmazione (che non deve essere particolarmente
complesso, per far si che possa essere utilizzato da tecnici che non hanno conoscenze orientate all'elettronica ed
all'informatica) e l'interfacciamento con i dispositivi esterni.
In sintesi: si definisce PLC
•un sistema elettronico a funzionamento digitale
•destinato ad un uso in ambito industriale
•dotato di memoria, in cui archivia il programma da eseguire
•per controllare vari tipi di macchine e processi.
PROGETTAZIONE DEL SOFTWARE DI CONTROLLO
Ogni problema di automazione richiede una corretta progettazione:
• della struttura meccanica
• dei cablaggi elettrici
• del software del sistema di controllo.
NB: Prima di cominciare a scrivere il software sarebbe opportuno stendere una dettagliata
descrizione dell’automazione da realizzare. Il tempo trascorso in questa attività preliminare
non è sprecato, in quanto consentirà di scrivere un software più funzionale e facile da
modificare e adattare ai futuri cambiamenti che le inevitabili riorganizzazioni dei processi
industriali richiederanno.
La descrizione dell’automazione è facilitata dal ricorso alle rappresentazioni grafiche (Ladder,
FBD, SFC).
STRUTTURA
FUNZIONAMENTO
Un programma per PLC è costituito da tre elementi:
•programma utente
•blocco dati (opzionale)
•configurazione CPU (opzionale).
Il programma, scritto con la Unità di Programmazione (anche PC), deve essere caricato nella CPU
del PLC.
La CPU immagazzina il programma nella RAM e questa, a sua volta, lo copia immediatamente
nella EEPROM per la memorizzazione permanente.
NB: Il trasferimento del programma nella
EEPROM fornisce maggiori garanzie di
affidabilità durante l’esecuzione.
Il programma in esecuzione è quello caricato
nella EEPROM.
RAM
- EEPROM
NB: Il PLC non è una macchina di
Von Neumann: la memoria è
divisa in diverse aree.
Condensatore ad alta capacità.
E’ in grado di mantenere la RAM attiva per
diversi giorni dopo che è stata tolta
l’alimentazione.
CAMPO DI UTILIZZO DEI PLC
La necessità dell'industria di produrre a "qualità costante" e sempre più elevata, di rendere
flessibile la capacità produttiva e migliorare la produttività per poter essere competitiva nelle
attuali condizioni di mercato, spinge verso un'automazione che interessa tutti i livelli del
processo produttivo. Si va cioè verso la "fabbrica automatica" ed il PLC sta assumendo in
quest'ultima il ruolo di componente fondamentale.
Non esiste ormai settore di produzione, trasformazione o controllo in cui non si trovano o non
siano possibili applicazioni del controllore a logica programmabile.
I PLC delle ultime generazioni non hanno più soltanto le caratteristiche originali di semplici
"sequenziatori" , ma stanno assumendo quelle di "calcolatori di processo" con compiti di controllo
e supervisione del processo produttivo visto che è possibile dotarli della possibilità di comunicare
con altri PLC e PC ed inoltre presentano delle interfacce utente sempre più sofisticate.
Il PLC presenta una serie di vantaggi, rispetto alla logica cablata realizzata con componenti
elettromeccanici e pneumatici, che lo rendono sicuramente e fortemente competitivo;i più im
portanti di questi vantaggi sono:

maggiore economicità sia nella fase di realizzazione
del sistema di comando sia nella fase di gestione
dello stesso, in particolare riguardo ad eventuali
ampliamenti e/o modifiche.

ampliamenti al sistema di comando possono essere
fatti semplicemente " aggiungendo " i componenti e
limitandosi al loro collegamento fisico senza dover
modificare quello delle altre apparecchiature.
modifiche al ciclo di automazione possono
essere apportate semplicemente intervenendo
sul "programma" e
lasciando inalterati i
collegamenti fisici.

Il tempo per realizzare le modifiche può essere ragionevolmente ridotto al minimo in quanto è
possibile "testare" e mettere a punto il programma eseguendo delle prove "al banco" su uno
stesso PLC dotato di opportuni simulatori.
Il PLC si può intendere come una apparecchiatura "General Purpose" (è l'utente che decide
per quale applicazione specifica verrà utilizzato) con:
- possibilità di Ampliamento
 recupero e reimpiego dello stesso PLC qualora non fosse più necessaria l'applicazione a cui era
stato inizialmente destinato.
 assenza di parti in movimento e quindi ridotta usura e manutenzione e lunga vita dei
componenti:

possibilità di produrre facilmente la stampa dei programmi
possibilità di autodiagnosi dei guasti

possibilità di inserimento in reti di controllo centralizzate

ingombro ridotto

minimo consumo
maggior sicurezza poichè nella maggior parte dei casi si hanno tensioni di max 30 V e di
conseguenza impossibilità di incidenti folgoranti.


CONTROLLO DI UN PROCESSO CON PLC
Per poter controllare una macchina od un processo il PLC deve acquisirne lo stato istante per istante ed in
base alle istruzioni scritte nella propria memoria, determinare se devono o meno essere apportate delle
modifiche allo stato attuale delle uscite.
Per acquisire lo stato attuale del processo vengono collegati agli "ingressi" del PLC tutte quelle
apparecchiature che possono fungere da "sensori" del sistema ("datori" di segnali) quali ad es. : pulsanti,
finecorsa, fotocellule, interruttori, contatti ausiliari di relè, telerruttori, relè termici, ecc.
Per "attuare" quanto è stato determinato dall'elaborazione del programma, alle uscite del PLC sono collegate
tutte quelle apparecchiature atte a realizzare quanto necessario per l’esecuzione del processo
(attuatori), che possono essere, a seconda di come viene realizzato l'automatismo, di tipo pneumatico,
oleodinamico od elettromeccanico od anche misto, come ad es. :relè, telerruttori, elettrovalvole, lampade di
segnalazione, suonerie, cilindri pneumatici od oleodinamici, valvole elettropneumatiche etc.
Il compito principale di un PLC è quello di acquisire informazioni e dati provenienti dal sistema controllato,
elaborarli in base ad un programma [che quindi non è altro che una serie di istruzioni tramite cui viene definito
come si dovrà comportare la macchina (processo) al verificarsi di eventi o situazioni ben definite] ed emettere,
verso il sistema controllato, il risultato di tale elaborazione che costituisce ciò che va fatto in quel momento da
parte degli organi preposti all'esecuzione del processo.
Per far ciò il PLC è dotato, oltre che di moduli d'ingresso e di uscita (I/O) , di un'unità centrale di elaborazione
(CPU), che costituisce il cuore del sistema e sovrintende a tutte le operazioni necessarie al funzionamento del
sistema, di MEMORIA per memorizzare il cosidetto sistema operativo del PLC, il programma utente ed i risultati
intermedi dell'elaborazione, di un ALIMENTATORE per alimentare tutte le varie parti costituenti il PLC ed infine
di un SISTEMA BUS per permettere i collegamenti fra le varie parti che compongono il sistema.
Oltre a ciò, il PLC deve poter comunicare con il mondo esterno ed è quindi dotato della possibilità di collegarsi
con delle periferiche per permettere il dialogo uomo-macchina, per comunicare con altri PLC, per permettere
l'utilizzo di memorie di massa e per fornire documentazione cartacea.
IL PLC NEL DETTAGLIO
L'ALIMENTATORE
La CPU necessita di alimentazione ad una tensione continua e stabilizzata di pochi volt
(solitamente 5). Altri
circuiti richiedono una tensione di 12 0 24 V sempre in corrente continua.
L'unità centrale di un PLC è equipaggiata pertanto con un alimentatore in cui sono raggruppati tutti i dispositivi
necessari per fornire tale alimentazione quali :



TRASFORMATORI ;
RADDRIZZATORI (Convertitori C.A./C.C.)
STABILIZZATORI.
Si può considerare parte dell'alimentatore anche il dispositivo che commuta sulla batteria
tampone, in assenza di alimentazione dalla rete, per salvare il contenuto della RAM.
Interfaccia uomo-macchina (in inglese Human-Machine Interface, HMI) si riferisce allo strato
che separa un essere umano che sta utilizzando una macchina dalla macchina stessa.
Profibus è l'acronimo di Process Field Bus. Si tratta di un bus di campo (field bus). Le sue applicazioni sono nel
campo dell'automazione industriale di processo.
-LA CPU
La CPU (Central Processing Unit o Unità Centrale) è la parte più importante del PLC di cui costituisce
"l'intelligenza". Essa è l'unità di governo del sistema ed il suo elemento centrale è un componente
integrato denominato Microprocessore.
Il microprocessore racchiude in sè tutte le funzioni di calcolo e controllo del processore centrale di un
normale calcolatore. La sua caratteristica più importante è la programmabilità che ha consentito il grande
passo in avanti dalla logica cablata alla logica programmabile.
Attualmente i microprocessori utilizzati come CPU dei controllori programmabili sono molto vari in quanto
non esiste una qualsiasi forma di standardizzazione.
Ogni costruttore impiega il microprocessore che ritiene più adatto alle prestazioni che vuole fornire al suo
sistema con livellio di potenza diversificati ( da 16 a 64 bit)
IL SISTEMA BUS
Il sistema bus è un insieme di collegamenti interni per la trasmissione e lo scambio di segnali, tensione
d'alimentazione e potenziali di massa.
Lo scambio di segnali tra il microprocessore e le schede d'ingresso e d'uscita avviene quindi tramite il sistema
bus.
Il bus è suddiviso in più gruppi di segnali:
-bus degli indirizzi, tramite il quale si può accedere agli indirizzi delle singole schede;
- bus dati, tramite il quale i dati possono essere letti dalle schede d'ingresso o trasferiti alle schede d'uscita;
-bus di comando, tramite il quale vengono gestiti i segnali di comando e controllo dello svolgimento delle
funzioni all'interno del controllore.
-LA
MEMORIA
Il PLC ha bisogno di memoria sia per il proprio sistema operativo sia per la memorizzazione del
programma utente sia per l'elaborazione dei dati intermedi durante l'esecuzione del programma.
Di solito il costruttore utilizza, per la memorizzazione del sistema operativo, una memoria di tipo ROM (Read
Only Memory), che ha appunto le caratteristiche di essere non volatile e di non poter essere modificata visto
che è una memoria di sola lettura.
Il programma utente , al contrario, deve poter essere modificato in quanto la sua stesura è demandata
all'utente che lo adatterà alle sue esigenze iniziali e, qualora fosse necessario, lo modificherà in seguito a
nuove esigenze.
Lo stesso si può dire riguardo la memoria necessaria per la memorizzazione dei risultati intermedi in quanto
sulla stessa il PLC effettuerà continuamente operazioni di lettura e scrittura.
Quindi, sia per il programma utente che per la memorizzazione dei risultati intermedi, il costruttore fornisce il
PLC di una memoria di tipo RAM (Random Access Memory) che può essere letta e riscritta.
La dimensione della RAM utente è uno dei parametri che caratterizza maggiormente un PLC in quanto da essa
dipende la lunghezza del programma che può essere gestito dal PLC.
Per PLC di piccola taglia, attualmente, si hanno memorie utente che hanno dimensione da tre a quattro
Kbyte, a cui corrisponde la capacità di memorizzare programmi di circa mille istruzioni.
Ovviamente in PLC di taglia superiore la dimensione della RAM varia proporzionalmente con la complessità
del set di istruzioni del linguaggio di programmazione proprio del PLC e con le dimensioni, prevedibilmente
superiori, dei programmi necessari per gestire automatismi complessi.
ASPETTO FUNZIONALE DELLE MEMORIE DEL PLC
In base al loro impiego, le memorie in un PLC si possono distinguere in :
 memoria di sistema,
 memoria di programma,
 memoria dati.
LA MEMORIA DI SISTEMA :
La memoria di sistema serve a conservare tutte quelle particolari istruzioni che servono per la gestione ed
il controllo del funzionamento della CPU e che pertanto costituiscono un vero e proprio SISTEMA
OPERATIVO del PLC.
Dato che il suo contenuto è di primaria importanza per il controllore, vengono utilizzate delle memorie di
tipo ROM, per evitare la sua involontaria cancellazione. Nulla vieta comunque che sia PROM o EPROM,
purchè non accessibile all'utente.
LA MEMORIA DI PROGRAMMA :
È la memoria destinata a contenere le istruzioni che costituiscono il programma eseguibile dal PLC. Per
svolgere tale funzione essa deve essere accessibile all'utente (a cui è demandata la stesura del
programma stesso) e viene quindi realizzata con memorie di tipo RAM.
LA MEMORIA DATI :
È anche detta MEMORIA DI LAVORO e prevede due sezioni distinte: i FLAG ed i REGISTRI
I FLAG (o MERKER)
Si tratta di una certa quantità di memoria in formato WORD o DOUBLE WORD
che
può essere
indirizzataanche in formato BYTE od a singoli BIT e che può
essere
utilizzata dall'utente
per
memorizzare risultati intermedi durante l'elaborazione del programma.

Tali risultati possono essere successivamente utilizzati in altre parti del programma.
I singoli BIT di queste memorie possono essere "SETTATI" (cioè posti
"RESETTATI" (cioè posti al valore logico 0).
al
I REGISTRI
Si tratta di memoria di tipo RAM che viene utilizzata per svolgere determinate
l'esecuzione del programma.
valore
logico 1)

funzioni durante
Solitamente si ha almeno un registro di LAVORO in cui vengono memorizzati i risultati delle singole
operazioni di tipo logico-aritmetico che vengono svolte dalla CPU istruzione dopo istruzione, un registro
AUSILIARIO che interviene solo in particolari situazioni, un registro di STACK che serve per la
memorizzazione di risultati intermedi quando il registro di lavoro deve essere utilizzato per altre
elaborazioni ed infine un registro di STATO.
o
LA SEZIONE DI INPUT/OUTPUT DI UN PLC
La sezione di I/O di un PLC riveste particolare importanza per quanto concerne la valutazione delle
prestazioni dello stesso, è usuale accennare innanzitutto alla quantità di punti di ingresso e di uscita
quando si parla delle caratteristiche di un PLC.
Questo comunque non è l'unico parametro di riferimento per la scelta di un PLC, infatti bisognerà tenere
conto di altre caratteristiche come ad es. la velocità di esecuzione di un ciclo di programma, la possibilità di
eseguire calcoli, la dimensione della RAM utente, ecc.
Non esistono quindi dei parametri di riferimento asfsoluti per valutare la scelta di un PLC rispetto ad un altro,
ma ciò dovrà essere fatto di volta in volta in funzione ovviamente del rapporto PRESTAZIONI/PREZZO in
riferimento alle specifiche dell'impianto da gestire.
UNITÀ D'INGRESSO
Le informazioni provenienti dal processo controllato possono essere semplicemente definite
come
"segnali in ingresso".
Questi segnali sono ovviamente di tipo elettrico e dovranno essere trattati in modo che siano riconoscibili
dalla CPU.
Il compito delle schede d'ingresso (come poi, in senso inverso, faranno anche le schede d'uscita) è quello di
consentire il dialogo tra il PLC ed il gruppo di potenza, o , per essere più precisi, per permettere al PLC di
acquisire i comandi e lo stato degli attuatori del suddetto gruppo.
Tali segnali possono essere sia segnali di tipo binario, caratterizzati dalla possibilità di assumere due soli valori
(" 1 logico" e " 0 logico"), a prescindere dalla natura iniziale del segnale, che potrebbe essere anche di tipo
analogico o comunque un segnale instabile nel tempo, ma lo si vuole trattare come segnale "digitale
binario", caratterizzato quindi da due soli stati possibili : assenza di tensione o presenza di tensione.
I segnali possono essere anche di tipo analogico, quindi variabili nel tempo dentro un prefissato intervallo
di valori, in questo caso devono preventivamente essere trattati da appositi convertitori A/D prima di essere
elaborati dalla CPU o digitali
SCHEDE D'INGRESSO DIGITALI.
Nel caso di segnali da trattare come segnali di tipo ON/OFF le schede d'ingresso devono essere in grado di
"capire" quando il segnale in ingresso è da considerare ON e quando è da considerare OFF, quando si tratta
di un disturbo ed inoltre di isolare galvanicamente la CPU dall'esterno in modo che eventuali sbalzi di
tensione o sovraccarichi od addirittura corto circuiti non danneggino la stessa.
Uno dei compiti svolti dalle schede d'ingresso è quello di adattare il livello e le caratteristiche del segnale.
Infatti, mentre la tensione di funzionamento interna del PLC è una tensione bassa (di solito 5 V), i segnali
possono presentarsi con livelli di tensione diversi ( 24, 48, 110, 220 V ).
La prima operazione svolta dalle schede di ingresso consiste nella messa in forma o squadratura del segnale.
Per determinare con certezza se il segnale è ON oppure OFF, di solito le schede d'ingresso sono costruite in modo che il
segnale esterno viene riconosciuto tale entro un intervallo di valori prefissato.
Ad es. si consideri un segnale a 24 V
Per evitare di acquisire false informazioni dovute a disturbi indotti dal mondo esterno si effettua un filtraggio
delle informazioni parassite, viene cioè valutato non solo il livello logico del segnale, ma anche la sua durata. Tanto
maggiore è questo ritardo tanto più grande risulta l'immunità ai disturbi.
TECNICA DEL MULTIPLEXAGGIO DEGLI INGRESSI IN UN CONTROLLORE PROGRAMMABILE
Spesso si presenta la necessità di collegare agli ingressi di un PLC dei segnali numerici opportunamente
codificati. Uno dei codici più usati per questo scopo è il codice BCD.
Usando questo codice, se si vuole inserire dei valori numerici con un certo numero di cifre, occorreranno un numero
di ingressi digitali pari a quattro per ogni cifra che costituisce il valore numerico da inserire.
Per cui, se si vuole inserire un valore numerico compreso tra 0 e 9999, si devono utilizzare quattro
codificatori ognuno dei quali occupa quattro ingressi (migliaia, centinaia, decine, unità).
In totale servono quindi 16 ingressi da destinare
esclusivamente all'acquisizione del valore da
inserire.
È possibile ridurre questo numero utilizzando una
tecnica di multiplexaggio degli ingressi come
quella indicata in figura, in cui si collegano i 16
segnali
provenienti
dai
codificatori,
disaccoppiandoli con dei diodi, a 4 ingressi del
PLC.
.
Questa soluzione richiede una gestione software un pò più sofisticata, permette però di risparmiare complessivamente
il 50 % di punti di I/O necessari.
Sono infatti necessari 4 ingressi e 4 uscite invece di 16 ingressi
SCHEDE D'INGRESSO ANALOGICHE
Esistono in commercio dei sensori analogici (termocoppie, resolver, ecc.) che forniscono, in relazione al livello di un
liquido in un serbatoio, alla temperatura di un forno, alla pressione in una tubazione etc., un segnale variabile con
continuità entro due limiti.
I valori di questi segnali sono standardizzati; valori tipici sono :
± 50 mV, ± 1 V, ± 5 V, ± 10 V, 0..10 V, 0..20 mA, ± 20 mA, +4..20 mA.
Per rendere possibile l'elaborazione da parte del PLC del valore del segnale in ingresso, qualunque esso sia, bisogna
convertire il segnale analogico variabile in un segnale digitale comprensibile alla CPU.
La precisione del convertitore dipende dal numero di bit che è in grado di
elaborare, cioè dalla sua "risoluzione" ed anche dalla sua "accuratezza".
Il numero di bit solitamente va da un minimo di 8 a 10, 12 bit
Con 8 bit è. possibile elaborare 28 = 256 combinazioni, con 10 bit 210 = 1024
combinazioni e con 12 bit 212 = 4096 combinazioni.
Il PLC ha un'immagine a gradini della grandezza come quella di figura
Se ad es. si ha una temperatura variabile da Tmin a Tmax e si utilizza un sensore che fornisce un valore in tensione da 0 a
10 V ( 0 V = Tmin e 10 V = Tmax ) ed il convertitore è ad 8 bit, si ha una risoluzione di 10/256 = 0.039 V a cui
corrisponderà un valore di temperatura dato da:
(Tmax-Tmin)/256.
Se ad es. l'intervallo di variazione della temperatura è di 100 °C la risoluzione del convertitore analogico/digitale sarà di
100/256=0.39 °C.
Con un ADC a 10 bit la risoluzione sarebbe di 100/1024=0.0976 °C.
Se si avesse un ADC a 12 bit la risoluzione diventerebbe di 100/4096=0.0244 °C.
Maggiore quindi è il numero di bit, maggiore sarà la fedeltà con la quale il convertitore trasformerà il segnale analogico in
segnale digitale.
Le schede analogiche possono avere diversi ingressi, per ridurre i costi si ricorre alla tecnica del multiplexer, che consente di
commutare i diversi ingressi su di un unico convertitore, questo determina però un leggero aumento del tempo di
Acquisizione dati
Anche nelle schede analogiche la CPU riceve i segnali digitali mediante
l'interposizione di optoisolatori.
SCHEDE D'USCITA DIGITALI
I moduli o schede d'uscita rappresentano sostanzialmente la interfaccia tra
l'elaborazione del programma attuata dalla CPU del PLC e gli attuatori che
costituiscono il sistema di comando verso l'impianto controllato.
Per quanto concerne il numero di uscite presenti su ogni scheda di uscita
valgono le stesse considerazioni fatte per le schede di ingresso.
Si definisce "tempo di emissione dell'uscita" l'intervallo di tempo che intercorre tra l'istante cui appare
un'immagine d'uscita nella memoria del PLC e quello in cui viene raggiunta la soglia di tensione a cui corrisponde
l'effettiva attivazione dell'uscita.
Per le uscite a relè questo tempo dipende principalmente dal tempo di salita dei relè, che varia da due a più decine di
millisecondi, mentre per le uscite statiche (a transistor) tale tempo è decisamente più breve.
Le tensioni più frequentemente utilizzate sono 24 o 48 V, si possono comunque avere tensioni diverse. La corrente che ogni
singola uscita è in grado di erogare va da 100 mA a 2 A.
SCHEDE D'USCITA ANALOGICHE
Le schede di uscita analogiche svolgono, in senso inverso, le stesse funzioni delle schede di ingresso analogiche. Operano
cioè una conversione digitale-analogica (D/A) dei valori, elaborati dal PLC così come definito da programma, che devono
essere trasmessi all'attuatore collegato alla scheda, il quale è costruito per ricevere un segnale analogico in tensione od in
corrente.
Vale tutto quanto già detto a proposito delle schede d'ingresso analogiche.
PERIFERICHE
Il controllore programmabile per poter dialogare con il mondo esterno (per essere programmato, per i controlli diagnostici,
per la stampa dei programmi su carta, per l'emissione di segnali d'allarme, per la messa a punto del programma ed altre
funzioni) necessita di particolari apparecchiature denominate unità periferiche, quali ad es. :







consolle di programmazione ;
memorie di massa ;
simulatori ;
programmatori di EPROM ;
interfaccia per stampanti e plotter ;
moduli di collegamento per personal computer ;
unità di servizio (chiavi elettroniche).
:
Sistema di gestione di un impianto per la produzione alimentare
Il sistema permette la gestione di un impianto per
la produzione di prodotti alimentari con controllo
dei tempi, delle temperature e del dosaggio degli
alimentari.
E possibile la gestione in manuale o in automatico
con la registrazione delle ricette per le varie
tipologie di lavorazione richieste
L’operatività e gli stati di funzionamento sono gestiti
da un terminale touch screen
I DISPOSITIVI DI PROGRAMMAZIONE
Il PLC trasmette segnali alle schede d'uscita in funzione dei valori acquisiti dalle schede d'ingresso ed elaborati secondo
le istruzioni contenute nel programma utente che è allocato in memoria.
È quindi indispensabile un'interfaccia che permetta il dialogo tra l'operatore e la macchina in modo da rendere possibile
la immissione del programma elaborato dal programmatore ed una serie di altre funzioni più o meno sofisticate.
Le funzioni fondamentali che un dispositivo di programmazione deve garantire sono
 scrittura del programma nella memoria del PLC; lettura del programma già residente in memoria;
modifica del
programma; ricerca di istruzioni del programma; compilazione del programma.
Tra le funzioni superiori dei dispositivi di programmazione rientra ad es. il : Funzionamento ON-LINE ed OFF-LINE
I piccoli modelli possono operare solo ON-LINE, cioè collegati al PLC.
La capacità di operare OFF-LINE, propria delle unità più evolute, consente al programmatore di scrivere e testare i
programmi " al banco ", in condizioni sicuramente migliori di quelle che si avrebbero sull'impianto ed inoltre in tempi
che non dipendono dallo stato di realizzazione dell'impianto, nel caso di un impianto nuovo o comunque, in caso di
modifiche da apportare ad un impianto già in funzione, l'attività di messa a punto del programma non comporta la
fermata dell'impianto
Per mezzo di opportune interfacce è possibile collegare il PLC a calcolatori con i quali potrà scambiare informazioni.
Con un collegamento in rete si possono svolgere per mezzo di un calcolatore funzioni come :
 controllo della produzione; raccolta e gestione di dati relativi al processo ;rilevamento degli eventuali guasti;
supervisione e controllo dei processi produttivi mediante sinottici dell'impianto visualizzati su monitor ; forzatura degli
ingressi e delle uscite; controllo e modifica a distanza e del programma e di alcuni parametri come valori di conteggi e
temporizzazioni.
FUNZIONAMENTO BASE DEI PLC
I PLC , così come i computer, è in grado di elaborare solamente informazioni espresse dai due livelli logici 1 e 0. Di
conseguenza tutte le informazioni fornite ad un PLC, siano dati od istruzioni, devono essere espresse tramite
combinazioni di questi due stati o livelli logici.
Spesso il livello logico 1 viene indicato con la lettera H (dall'inglese HIGH cioè livello ALTO) ed il livello logico 0 con la
lettera L (dall'inglese LOW, cioè livello BASSO).
La rappresentazione di dati ed istruzioni in termini di 0 ed 1 logici prende il nome di rappresentazione binaria,
un'informazione, nella forma comprensibile al PLC, si può presentare nella seguente forma :
0011 1010 1100 1110
Come si vede, la precedente espressione binaria è costituita da più bit.
Una sequenza del genere prende il nome di " PAROLA ".
In particolare si tratta di una parola a 16 bit, che si riferirà ad un PLC che opera in parallelismo 16, in grado cioè di
elaborare dati espressi, al massimo, con 16 bit.
-FUNZIONAMENTO SEQUENZIALE
Caratteristica base di tutti i sistemi di elaborazione dati è il funzionamento sequenziale, che è da intendersi come "fare
una cosa alla volta , una dopo l'altra".
Il funzionamento sequenziale dei sistemi a PLC porta a due considerazioni importanti :
1)l'elaborazione
di un programma richiede un certo tempo che può essere più o meno lungo, a seconda del numero e
del tipo di istruzioni che lo compongono.
2)l'elaborazione
sequenziale delle istruzioni comporta anche il fatto che, qualora si abbiano nel programma delle
istruzioni che portano alla elaborazione di risultati in contraddizione fra loro, si possono creare delle situazioni di
incertezza già in fase di programmazione.
-TEMPO DI ESECUZIONE DELLE ISTRUZIONI
Per tempo di esecuzione di un'istruzione si intende il tempo che intercorre tra l'istante in cui l'istruzione stessa viene letta
dalla memoria, sfruttando l'indirizzo che in quel momento è contenuto nel contatore di programma (Program Counter), e
l’istante in cui, dopo che la stessa è stata decodificata ed eseguita, la CPU inizia la fase di lettura dell'istruzione successiva.
Tali durate sono molto varie fra di loro, ad es. la lettura di un ingresso può essere eseguita anche in un solo microsecondo,
mentre caricare un contatore può richiedere anche 600 microsec.
A seconda dei modelli, per una stessa marca di PLC, ed ancora di più per PLC di marca diversa, la stessa istruzione può
richiedere tempi molto diversi per essere eseguita. A volte addirittura in un dato PLC viene eseguita in un tempo fino a
mille volte superiore a quello necessario in altro PLC.
-TEMPO DI CICLO (O DI SCANSIONE)
Per TEMPO DI CICLO si intende il tempo necessario per eseguire tutte le istruzioni che costituiscono il programma.
-TEMPO DI REAZIONE
Supponendo che un ingresso venga esaminato una sola volta per ciclo, per TEMPO DI REAZIONE del PLC si intende la
somma del tempo di ritardo nell'acquisizione della variazione e la durata del ciclo.
Il tempo di reazione è variabile in quanto dipende dal momento in cui si verifica la variazione dell'ingresso.
IL CONCETTO DI CICLO NEI PLC
Una caratteristica fondamentale dei PLC è il funzionamento sequenziale della CPU.
Le istruzioni che costituiscono il programma vengono eseguite una alla volta, una dopo l'altra tranne ovviamente i casi in
cui si incontrano delle istruzioni di salto che impongono una variazione a questa sequenza.
Alla fine del programma, svolte alcune operazioni di sistema, si ricomincia dalla prima istruzione.
TIPI DI CICLI
In relazione ai cicli ed alla gestione dell'input-output i PLC si differenziano sostanzialmente nel fatto che i
valori degli ingressi e delle uscite vengono letti e scritti (aggiornati) direttamente od indirettamente tramite
una memoria.
Nel caso in cui l'accesso è diretto, si ha un modo di funzionamento che si avvicina molto al concetto di
risposta del sistema agli eventi in tempo reale (prendere in considerazione i fenomeni nel momento stesso
in cui avvengono ed agire subito di conseguenza
Nel caso di utilizzo di una memoria intermedia, l'acquisizione dello stato degli ingressi viene fatta
contemporaneamente in un certo istante (ad es. prima di eseguire il ciclo) e questo valore viene mantenuto
invariato in memoria per tutta la durata del ciclo anche se nel frattempo alcuni o tutti gli ingressi hanno
modificato il loro stato.
I costruttori di PLC hanno impostato modalità diverse di attuazione dei cicli in riferimento ai due momenti
fondamentali di "acquisizione degli ingressi" ed "aggiornamento delle uscite".
I tipi di ciclo che si trovano più comunemente sono i seguenti :
-CICLO SINCRONO IN INGRESSO ED IN USCITA
È il ciclo tipico in cui si fa uso dei registri di "immagine degli ingressi" e di "immagine delle uscite".
Il PLC legge tutti gli ingressi contemporaneamente all'inizio del ciclo e crea in memoria (ovvero nel registro a
ciò dedicato) una immagine del processo relativa all'istante in cui è stato acquisito il valore di ogni singolo
ingresso.
Tale immagine rimane invariata per tutta la durata del ciclo anche se, durante l'esecuzione
dello stesso, alcuni ingressi dovessero modificare il loro stato.
Le varie fasi eseguite da un PLC, funzionante con questo tipo di ciclo, sono descritte in figura
- CICLO SINCRONO IN INGRESSO ED ASINCRONO IN USCITA
Come nel ciclo precedente, gli ingressi sono acquisiti contemporaneamente
all'inizio del ciclo, si ha quindi anche in questo caso un registro di immagine degli
ingressi.
Le uscite invece vengono aggiornate non appena viene elaborato un risultato
(ovvero non appena un risultato da assegnare ad un'uscita è disponibile, questo
viene subito emesso all'esterno e l'uscita interessata viene aggiornata)
-CICLO ASINCRONO IN INGRESSO ED IN USCITA
L'organizzazione di questo ciclo è basata sulla elaborazione delle sequenze di istruzioni una per una. Viene letto un
ingresso (o più ingressi se nella sequenza ne compaiono più di uno), lo si usa in una data funzione, si elabora il
valore dell'uscita, viene aggiornata l'uscita ed infine si passa alla sequenza successiva
Il primo tipo di ciclo che abbiamo visto è tipico dei PLC di basso livello. Il secondo è scarsamente
diffuso. Il terzo è adottato da un PLC di buon livello
Comunque sia questa è soltanto una schematizzazione dei tipi di ciclo dei PLC, in commercio si possono trovare
soluzioni le più diverse.
Modulo base S7 - 224
Il
modulo base dispone di I/O integrati:
14 Ingressi (Byte 0 e Byte 1)
10 Uscite (Byte 0 e Byte 1)
LINGUAGGI
DI
PROGRAMMAZIONE
NOTE STORICHE
I linguaggi di programmazione del PLC hanno avuto uno sviluppo diverso da quello dei calcolatori.
Il PLC è stato introdotto inizialmente per sostituire i quadri di comando a relè, per cui dovevano
essere gestiti non da informatici, bensì da elettricisti con scarse conoscenze di informatica.
Gli elettricisti progettavano i quadri di comando con degli schemi a contatto per cui si organizzò un
linguaggio di programmazione del PLC molto simile (LADDER) e oggi molto diffuso. Le industrie
costruttrici di PLC scelsero linguaggi proprietari, con conseguenti problemi di portabilità.
La programmazione a contatti non consente tuttavia di sfruttare al meglio la potenza hardware del
PLC. Per questo e anche per consentire la programmazione a tecnici informatici e elettronici furono
sviluppati in seguito altri due tipi di linguaggi: IL (Instruction List) e FBD (Functional Diagram
Block).
Restava comunque la difficoltà di realizzare una facile ed efficace automazione dei grandi impianti.
Inoltre, a causa della incompatibilità tra i modelli dei diversi costruttori e dell’aumento della
complessità dell’automazione, si è rivelata sempre più critica la manutenzione del software di
controllo.
Nel
tentativo
di
risolvere
questa
problematica
fu
implementato
un
nuovo
linguaggio
di
programmazione, simile a uno di quelli di alto livello per la programmazione del PC e standardizzato,
con sintassi vicina a quella del Pascal: ST (Structured Text).
Un processo di automazione, e quindi la scrittura di un software di controllo, può essere visto come
un automa a stati finiti (DES, Discrete Event System).
La rappresentazione grafica di un DES mediante i tradizionali diagrammi di transizione degli stati
presentava dei limiti che li rendevano incapaci di una descrizione completa dell’automazione.
I diagrammi erano stati di valido aiuto nella:
•descrizione del funzionamento di un automa a stati finiti
•progettazione dell’hardware.
Ma nella progettazione del software di controllo i limiti dei diagrammi emersero a mano a mano che
l’automazione si rendeva sempre più complessa; i diagrammi con consentivano la rappresentabilità
di
•più stati attivi contemporaneamente
•processi paralleli
•funzioni di controllo logiche.
Nel solco di questa problematica, nel 1975 in Francia si cominciò a sviluppare il GRAFCET (Graphe
de
Coordination Etapes Transitions), una rappresentazione del processo di automazione
mediante un diagramma funzionale standardizzato, capace di rappresentare processi sequenziali
(processi il cui
svolgimento avviene a passi e la transizione da un passo al successivo è
Il
subordinato a certe condizioni)
Grafcet:
•era un formalismo che consentiva una buona progettazione del controllo degli impianti
•era indipendente dalla tecnologia con cui il controllo sarebbe stato implementato
•forniva una rappresentazione immediata del processo di automazione.
•Nel corso degli anni ’80 il Grafcet fu ulteriormente sviluppato e il successo fu tale che nel
1987 fu assunto come standard internazionale dall’IEC (Comitato Elettrotecnico
Internazionale).
.
Infine la norma IEC 1131 – 3 del 1993 (recepita in Italia nel 1996), cercando di mettere ordine nei
vari linguaggi di programmazione dei PLC, ha incluso anche il Grafcet tra i linguaggi di
programmazione con la nuova denominazione di Sequential Functional Chart (SFC).
Per la programmazione dei PLC i costruttori possono quindi implementare i seguenti linguaggi:
•IL (Istruction List)
•ST (Structured Text)
•LD (Ladder Diagram)
•FBD (Function Block Diagram)
•SFC (Sequential Functional Chart)
Programmare un PLC significa trasferire in esso una sequenza di istruzioni (programma) in un
linguaggio di programmazione opportunamente codificate tramite delle periferiche dedicate a
questo scopo (unità di programmazione).
Il compito del PLC sarà quello di determinare lo stato delle uscite, ad esso collegate, in funzione
dello stato degli ingressi, secondo le relazioni stabilite dal programma che il PLC esegue.
IL PLC può essere programmato a svolgere una certa sequenza di operazioni, più o meno
complessa, sulla base dell'insieme delle funzioni elementari da esso eseguibili sulla base del SET
di istruzioni di cui è dotato (operazioni logiche, conteggi, comparazioni, temporizzazioni, etc),
Visto che il PLC deve operare in un contesto di automazione industriale, la sua capacità di espressione
funzionale deve essere omogenea con le esigenze di automazione industriale.
Basti pensare che i più elementari problemi da risolvere nell'ambito dell'automazione industriale sono del tipo : "
se il tal contatto è chiuso e contemporaneamente quell'altro contatto è aperto, allora attiva la tal
uscita".
I linguaggi attualmente in uso si possono considerare appartenenti a due categorie ben precise, cioè quella dei
linguaggi grafici e quella dei linguaggi letterali.
La differenza fra questi due tipi consiste essenzialmente nella modalità di rappresentazione visiva delle
combinazioni logiche che costituiscono le varie sequenze in cui è suddiviso un programma : in quelli grafici si fa
uso di simboli grafici mentre in quelli letterali si fa uso di codici letterali mnemonici cui è attribuita una
determinata funzione .
alcuni dettagli del linguaggio LADDER (o KOP




Appartiene alla categoria dei linguaggi grafici perchè si presenta in maniera
simile ad uno schema elettrico funzionale, con delle semplici modifiche
rispetto a quest'ultimo :
flusso di potenza va da sinistra verso destra ;
il flusso logico va dall'alto verso il basso ;
ogni circuito è disegnato in posizione orizzontale invece che verticale.
- le linee che rappresentano l'alimentazione vengono disegnate verticalmente invece che orizzontalmente;
 i simboli dei contatti NA, dei contatti NC e delle bobine vengono semplificati come si vede in figura In questo
tipo di linguaggio, per rappresentare lo stato dell’operando, viene valutato il livello logico della funzione e non
il livello fisico del sensore collegato all’operando che è interessato
Cenni sul fup e awl e Ladder
AWL
I linguaggi letterali (o liste d'istruzioni o linguaggi simbolici o AWL) utilizzano una serie di parole (codici letterali
mnemonici) che identificano ognuna una determinata funzione logica (AND, OR, NOT, ecc.), allo stesso modo si possono
rappresentare temporizzatori, contatori, comparatori, ecc.
I due programmi visti precedentemente in FUP ed in KOP, si presentano sotto la seguente forma
- FUP
E’ un linguaggio di tipo grafico, la differenza rispetto al KOP sta nel fatto che i simboli utilizzati per rappresentare le
funzioni logiche, non sono più dei contatti bensì dei blocchi logici.
LINGUAGGIO DI PROGRAMMAZIONE LADDER

E'
il
più

Si basa su simboli di provenienza "elettrica":
 Binari di
vecchio linguaggio di programmazione per
potenza (power
PLC
rail), contatti elettrici e avvolgimenti magnetici (coil)

Si articola in linee verticali dette “rung”

Ciascun “rung” può contenere contatti, coil, Function Block e Funzioni

Ciascun "rung" deve essere connesso necessariamente al binario di potenza sinistro (left power rail), mentre il
collegamento con quello destro è opzionale
Elementi di Base del Linguaggio Ladder

Power Rail

Linee Elettriche Orizzontali

Connessioni ai Power Rail

Contatto Normalmente Aperto

Contatto Normalmente Chiuso

Coil (bobine)

Negated Coil
ORGANIZZAZIONE DELLA PRODUZIONE DEL SOFTWARE PER
LA
PROGRAMAZIONE
La prima fase per la programmazione di un PLC che deve gestire un qualunque impianto di automazione industriale od
applicazioni diverse, è quella dell'ANALISI FUNZIONALE del problema da risolvere.
In questa prima fase non interessa quello che sarà il contenuto del programma, il quale deve essere visto come una
scatola nera di cui interessa sapere ciò che vi entra, le elaborazioni che deve effettuare e ciò che ne dovrà uscire.
In pratica bisogna definire :
 Qual'è il punto di partenza, cioè quanti, quali e di che tipo sono i segnali in ingresso, con quali caratteristiche, con
quale durata e con quale significato ;
 L'esatta definizione e descrizione del funzionamento dell'impianto anche nei minimi particolari, perchè in base a
ciò si dovrà definire le elaborazioni che il PLC (ovvero il programma che deve essere scritto) dovrà svolgere.
 Qual'e' il punto di arrivo vale a dire i segnali che dovranno essere forniti al processo : come , quando, in che forma,
con quale durata.
A queste fasi segue quella della definizione della " Lista di Occupazione degli I/O " ; questa lista è importante per il
programmatore perchè gli permette di sapere in quale determinato ingresso è collegato il tal sensore ed in quale uscita
è collegato il talaltro attuatore.
Subito dopo la lista di occupazione degli I/O si può eventualmente fare anche una lista di assegnazione delle variabili
interne (memorie a disposizione dell'utente) che si intende utilizzare per scopi particolari o comunque definibili già prima
di iniziare la stesura del programma, come per es. quali memorie si utilizzeranno per memorizzare dei valori di conteggio,
quali per memorizzare situazioni particolari del processo ecc.
E' importante inserire dei commenti e delle osservazioni che rendano il programma più chiaro e leggibile
Il modo di come si descrive il funzionamento dell'impianto può essere diverso a seconda di come ognuno è abituato
a lavorare, cioè si può ricorrere ad es. ad uno o più diagrammi di flusso, se il processo è costituito da più fasi di
lavorazione,
Dopo avere scritto il programma si può analizzare le possibilità di ottimizzarlo e minimizzarlo per renderlo il più
efficiente possibile.
TEST E SIMULAZIONE
Dopo che il programma è stato sviluppato, bisogna passare alla fase di correzione e messa a punto dello stesso.
Ciò può essere fatto trasferendo il programma nella memoria del PLC ed eseguendolo simulando l'azionamento dei
sensori tramite un opportuno simulatore.
La simulazione permette di analizzare il comportamento del PLC di fronte alle varie situazioni che si possono
presentare nella realtà e verificare quindi se il programma è rispondente con quanto si vuole fare.
Dopo di chè si può passare alla fase successiva che è quella della documentazione dei programmi comprendente
1. Descrizione di massima dell'impianto
E' necessario quantomeno redigere uno schema completo dei collegamenti completandolo con una descrizione del
funzionamento dell'impianto
.
2. Lista di occupazione I/O
Da questa lista deve essere possibile ricavare tutte le informazioni che riguardano i sensori e gli attuatori collegati al PLC
ed anche informazioni riguardo le unità di funzione (memorie, contatori, registri, ecc.) utilizzati all'interno del programma.
Per compilare questa lista e documentarla, è sufficiente l'uso di una tabella organizzata su più colonne come quella
dell'esempio in fig. 18
3.Listato del programma :
Il listato del programma deve essere completo di commenti esplicativi che ne facilitano la comprensione, altrimenti
risulterebbe del tutto insufficiente qualunque sia il linguaggio di programmazione utilizzato.
Le unità di programmazione più diffuse permettono ormai con facilità sia la programmazione che la stampa dei programmi
nei diversi linguaggi disponibili per quel tipo di PLC.
4. Cross reference :
Per cross reference s'intende una lista di riferimento che consente di indicare, per ogni operando (ingresso, uscita,
memoria) tutti i punti del programma in cui viene utilizzato, consentendo quindi una ricerca a colpo d'occhio del punto di
programma in cui bisogna eventualmente intervenire.
INSTALLAZIONE - MANUTENZIONE - RICERCA GUASTI
Per l'installazione di un PLC bisogna distinguere tra l'installazione dell'HARDWARE e l'installazione del SOFTWARE.
INSTALLAZIONE DELL'HARDWARE :
Si ricorda che per l'installazione di un PLC, bisogna attenersi alle norme CEI 44-5 (1985) fasc. 729: "Equipaggiamenti
elettrici di macchine industriali. Parte 1: norme generali".
E' necessario considerare diversi aspetti, come la corretta installazione, la protezione contro i disturbi di natura elettrica,
ed infine le caratteristiche ambientali, allo scopo di garantire un corretto funzionamento, la sicurezza del personale e
dell'impianto stesso.
E' sempre importante leggere il manuale d'installazione fornito con il PLC, in quanto vi possono essere delle prescrizioni
particolari che tengono conto delle caratteristiche tipiche del controllore che si sta installando.
I controllori programmabili devono essere protetti dalle sovratensioni che possono generarsi sia negli ingressi che nelle
uscite.
Le unità d'ingresso sono munite al loro interno di accoppiatori ottici (optoisolatori) , i quali evitano che una sovratensione
possa danneggiare i circuiti interni del PLC.
Per quanto riguarda le uscite, se queste non sono già protette dai cortocircuiti, bisogna prevedere l'installazione di fusibili
extrarapidi sulle stesse.
Inoltre è da considerare sempre qual'è la potenza elettrica massima che una unità di uscita è in grado di comandare,
sommando le potenze dei singoli carichi (relè, contattori, ecc.) ed individuando nel ciclo della macchina qual'è il numero
massimo di uscite che si trovano ad essere attivate contemporaneamente.
Se il valore di potenza così ottenuto supera quello massimo ammissibile dal PLC occorrerà prevedere l'utilizzo di contattori
o relè di potenza per amplificare la potenza massima erogabile dal PLC. Bisogna sempre predisporre un dispositivo
d'emergenza per togliere tensione ai carichi d'uscita in caso di necessità ed un dispositivo per togliere tensione alle
macchine non in funzione, per interventi sulle stesse, tramite dei sezionatori a relè.
MANUTENZIONE E RICERCA GUASTI
Oltre ad una corretta installazione, è necessario che venga fatta periodicamente una adeguata manutenzione.
Tutti i PLC , pur con certe differenze, hanno delle funzioni di test ed autodiagnosi dei guasti o mal funzionamenti (test
sul funzionamento del microprocessore, sulla memoria, sul livello della batteria, ecc.) che permettono una ricerca dei
guasti guidata e quindi di individuare l'anomalia più velocemente.
La funzionalità degli I/O si può controllare tramite i led indicatori per ogni punto di I/O.
Nelle apparecchiature più sofisticate è possibile visualizzare sulle unità di programmazione un insieme di informazioni
sulla natura dello specifico guasto.
La manutenzione ordinaria, che di norma dovrebbe essere fatta con frequenza almeno semestrale o maggiore se
le condizioni ambientali lo impongono, serve a prevenire una serie di guasti soprattutto per quanto riguarda la parte
relativa alle circuiterie di collegamento dei sensori e degli attuatori, ponendo cura ad es. ai seguenti punti :
- controllo delle viti di fissaggio ;
-verifica del corretto inserimento dei cavi di collegamento nei rispettivi morsetti e che le viti degli stessi siano
correttamente serrate ;
-controllare la carica della batteria che a seconda del tipo che viene usato ha una durata che varia da due anni a
cinque anni (batterie al litio).
E' utile riportare su di una apposita targhetta la data in cui la stessa dovrà essere sostituita.
E' consigliabile tenere a magazzino delle unità di I/O di ricambio, che sono le parti del PLC più soggette a guasti
semprechè il PLC sia costruito in modo da permetterne la rapida sostituzione.
Per le eventuali misure di controllo che si dovessero rendere necessarie, è opportuno l'uso di un multimetro, digitale od
analogico che sia, dotato di una elevata impedenza d'ingresso.
A volte le cause di guasto o di anomalie di funzionamento, possono essere la temperatura o l'umidità, per cui è
opportuno disporre di un igrometro ed un termometro
-
MISURE PER LA PROTEZIONE DAI DISTURBI ELETTRICI
Per garantire la protezione dai disturbi elettrici, che non agiscono sull'hardware ma sul software e possono determinare
mal funzionamenti del controllore, è opportuno fissare il PLC su di una piastra metallica collegata a terra.
Per quanto riguarda il cablaggio dei conduttori, deve essere realizzato separando i conduttori di alimentazione
del controllore e del circuito di potenza dai conduttori dei segnali di I/O, prevedendo la loro sistemazione in canaline
separate oppure, se ciò non è possibile, schermando singolarmente i cavi in corrente alternata.
La stessa cosa va fatta per i conduttori di collegamento dei segnali analogici rispetto ai segnali digitali: se sono
alloggiati nella stessa canalina, si dovranno schermare i cavi di collegamento dei segnali analogici.
Bisogna procurarsi un unico punto di riferimento di massa per il collegamento al morsetto di massa sul PLC.
Occorre anche separare il cablaggio per corrente alternata da quello per corrente continua ed evitare di collocare i
conduttori vicino a disturbi elettrici particolarmente forti.
Vanno rispettate la sezione e la lunghezza massima dei conduttori che è indicata nei manuali del controllore.
Se nell'armadio in cui è alloggiato il PLC vi sono dei contattori o dei relè con bobine comandate da contatti
elettromeccanici, si può rendere necessaria l'installazione di gruppi RC spegniarco in parallelo alle bobine.
E' da evitare l'installazione di lampade fluorescenti all'interno dell'armadio.
L'installazione del software richiede procedure diverse a seconda dell'unità di programmazione che è stata usata per la
programmazione e che si usa per l'immissione del programma sul PLC.
Si tratta di operazioni semplici da effettuare, sia che si eseguano da unità di programmazione, sia da PC; in entrambi
i casi si dispone di un menù di comandi di facile comprensione ed utilizzo.
LA SCELTA ED IL DIMENSIONAMENTO DEL CONTROLLORE PROGRAMMABILE
Bisogna considerare diversi fattori per arrivare a definire qual'è, tra i PLC presenti in commercio, quello che soddisfa
maggiormente le proprie esigenze.
E' opportuno considerare i seguenti punti :
numero e tipo di segnali che si devono elaborare (cioè numero di I/O)
 tipo e volume dell'elaborazione che deve svolgere il PLC (Kbyte memoria RAM utente e dati)
 tempo di ciclo del PLC
 tipo di sensori ed attuatori
 tipo di morsettiere e cablaggi
 tipo di memorie installabili
 caratteristiche ambientali
 possibilità di dialogo con altri PLC o con PC
 assistenza tecnica, vita operativa
 linguaggi di programmazione
 costo delle apparecchiature, costo delle interruzioni del funzionamento dell'impianto.
Vi sono alcuni criteri di massima che è possibile seguire per individuare il prodotto che meglio si adatta alle proprie
esigenze, tra questi possiamo distinguere criteri funzionali,(quantità delle funzioni che il PLC può svolgere) tecnologici
(le caratteristiche dei sensori, elettronici od elettromeccanici) , operativi (possibilità di ampliamento)ed infine criteri
economici

CONSIDERAZIONI SULLA SICUREZZA NEL CAMPO DEI PLC
Una prima distinzione da fare è quella tra guasti attivi e guasti passivi.
Un guasto è passivo se non si manifesta subito, attivo invece quando si manifesta subito. Entrambi possono essere pericolosi
o non pericolosi.
Un guasto attivo e pericoloso è ad esempio il cortocircuito tra i conduttori di un pulsante di marcia (o in genere di un
sensore che ha il compito di abilitare l'attivazione di un'uscita) che provoca l'azionamento non voluto dell'uscita.
Un guasto passivo non pericoloso è l’interruzione di un conduttore di collegamento di un pulsante di marcia che impedirà di
.
avviare il motore ma nella stragrande maggioranza dei
casi non crea situazioni di pericolo.
Sia il cortocircuito tra due conduttori di collegamento di un sensore, sia l’interruzione di un conduttore possono provocare dei
guasti attivi e/o passivi entrambi pericolosi o non pericolosi a seconda che si verifichino sui conduttori di collegamento di un
contatto NA o NC. Altro fattore importante ai fini della sicurezza è l'isolamento dei conduttori.
Si pensi ad un cortocircuito sullo stesso conduttore, che pur essendo di solito scarsamente considerato, è un guasto che può
provocare situazioni di pericolo : nel caso in cui un difetto d'isolamento su di un conduttore provochi il cortocircuito di un
contatto NA, se in conseguenza di ciò si ha l'attivazione di una lampada o di un segnale acustico per quanto sia sgradito non
è sicuramente pericoloso, ma se viene cortocircuitato un pulsante di marcia, ciò determinerà l'azionamento indesiderato del
motore corrispondente con ovvio pregiudizio della sicurezza.
Nel primo caso si avrebbe un guasto attivo ma non pericoloso nel secondo un guasto attivo pericoloso. Si ritiene che
l’interruzione di un conduttore (ad es. per un morsetto allentato) si possa verificare con maggiori probabilità rispetto al
cortocircuito tra due conduttori, ragion per cui nella scelta dei contatti da utilizzare (NA o NC) si dovranno adottare gli
accorgimenti che danno maggior garanzie di sicurezza.
Un'importante regola che è assolutamente da rispettare ai fini della sicurezza contro le interruzioni dei
conduttori di collegamento delle apparecchiature di comando è quella di usare sempre dei contatti NA per la
apparecchiature che hanno il compito di attivare delle uscite (abilitare dei movimenti) e dei contatti NC per le
apparecchiature che hanno il compito di disattivare le uscite (arresto di movimenti).
Per quanto il PLC possa essere considerato un'apparecchiatura che elabora delle informazioni, agisce comunque in ambiente
industriale ed i guasti che possono creare situazioni di pericolo è indifferente che avvengano all'interno od all'esterno dello
stesso.
 Un errore di trasmissione dati all'interno del PLC potrebbe provocare l'attivazione di un'uscita invece di un'altra, bisogna
adottare particolari accorgimenti perchè il sistema di controllo soddisfi le prescrizioni normative in termini di sicurezza.
− I comandi che riguardano i circuiti di sicurezza devono agire su componenti elettromeccanici indipendenti dal PLC.
In generale, per effettuare un'installazione che garantisca un elevato grado di sicurezza, occorre
considerare i seguenti punti.
• Le apparecchiature collegate ad un PLC dovrebbero comprendere dispositivi di comando interbloccanti ed interruttori
di sicurezza che impediscano il funzionamento durante un guasto dell'impianto.
• L'alimentazione dell'equipaggiamento elettronico deve essere sempre derivata da un trasformatore d'isolamento,
collegato a valle dell'interruttore generale, ed utilizzato anche per gli altri circuiti ausiliari della macchina o dedicato
esclusivamente alla componente elettronica.
• Occorre provvedere all'interruzione delle uscite ritenute critiche, ai fini della sicurezza, quando la macchina non è in
funzione o quando si deve intervenire all'interno della macchina stessa (messa a punto, manutenzione, ecc.). Il circuito
di tali uscite deve essere interrotto da un contatto pulito di un interruttore o di un relè e non da un dispositivo a
semiconduttore (transistor, Triac).
• Ogni modulo o circuito di uscita va collegato ad un solo carico ed in conformità alle specifiche del costruttore (per ciò
che attiene, per esempio, alla potenza massima assorbita e alla sopportabilità in termini di potenza reattiva).
• Bisogna escludere il controllo dal PLC con una predisposizione esterna e realizzare un comando ad impulsi esterno per
la messa a punto della macchina o per il caricamento del programma; in caso di guasto del PLC, devono rimanere
efficaci i dispositivi di emergenza e gli interruttori di sicurezza. Questi dispositivi di sicurezza devono agire direttamente
sugli organi attuatori nella parte di potenza del comando.
• In presenza di comandi a distanza, la cui attivazione potrebbe produrre sulla macchina situazioni di pericolo, è
necessario prevedere un dispositivo di esclusione a chiave, che consenta ai manutentori ed agli operatori di porsi,
all'occorrenza, in situazioni di sicurezza contro avvii o consensi intempestivi provenienti da zone remote.
Linee di produzione
Uno degli impieghi più importanti per i controllori programmabili è nelle linee di assemblaggio (le cosi dette “catene di
produzione”).
Nelle linee ci sono più PLC, ciascuno governa un macchinario, un robot o parte della linea. Questi comunicano fra loro
tramite una rete. Di solito c'è un PLC “Master” e uno o più “Slave”.
Il “Master” invia pacchetti di dati agli “Slave” che eseguono la lavorazione di conseguenza; La comunicazione è del tipo
a bus (detto “Bus di campo:unica connessione tra i diversi PLC).
Il “Master” individua lo “Slave” con cui deve comunicare tramite un indirizzo (detto “Stazione”). Il “Bus di campo” è
fisicamente realizzato con due o quattro fili, oppure con una vera e propria rete ethernet.
In alcuni reti è necessario disporre di più PLC “Master”, perchè non c'è una vera è propria linea di
produzione, ma piuttosto diverse stazioni di lavorazioni indipendenti.
In questo caso una tecnica molto usata è di fare comunicare i PLC tra loro in modo sequenziale. Cioè una sorta di catena,
in cui ciascun PLC trasmette in rete un pacchetto di dati seguito da un “Token” (come il testimone nella staffetta).
Questo “Token” contiene il numero della stazione destinataria del pacchetto. Ciascun PLC riceve e verifica se il “Token”
punta la propria stazione, in caso contrario lo ritrasmette al PLC successivo. Cosi via, di solito a catena chiusa, cioè con
l'ultimo PLC collegato al primo della catena.
SEGNALI A TEMPO CONTINUO
SEGNALI CANONICI
TRASFORMATA DI LAPLACE
ANTITRASFORMATA DI LAPLACE
TEOREMA DEL VALORE INIZIALE E FINALE
ESERCIZI
LAPLACE: POLI COMPLESSI CONIUGATI
LAPLACE: SOLUZIONE DI EQUAZIONI DIFFERENZIALI
SEGNALI CANONICI
Tipicamente nei controlli automatici per testare un sistema dinamico si utilizzano dei segnali detti
canonici o di saggio, utilizzati come funzioni elementari in combinazione delle quali è scomposto il
generico ingresso. Infatti, assumendo che il sistema sia lineare, il principio di sovrapposizione
degli effetti permette di studiare separatamente l’effetto di tali segnali.
Inoltre l’ipotesi di linearità assicura che l’uscita del sistema si componga unicamente dei modi
elementari «andamenti temporali “elementari” associati ai poli della fdt, rappresentano per cui
dinamiche proprie del sistema indipendenti dal particolare ingresso. e dei modi dell’ingresso.
come si vedrà nell’analisi di stabilità dei sistemi lineari.
Pertanto le caratteristiche dinamiche dell’uscita di un sistema sono analoghe in corrispondenza di
diversi ingressi, a meno dei modi introdotti da questi ultimi
segnale a gradino
• Ingresso a impulso
NB:
non
sempre
è
possibile
ricavare
sperimentalmente
la
risposta
del
sistema
all’impulso, in quanto l’impulso deve fornire
l’energia sufficiente al sistema per provocarne la
risposta. La trasformata di laplace del segnale
impulsivo è pari a 1
Nel dominio del tempo viene rappresentato
da u (t). La trasformazione di Laplace del
gradino unitario è 1 / s
SEGNALI CANONICI
Segnale a rampa :
Nel dominio del tempo viene rappresentato
da r (t). La trasformazione di Laplace del
segnale a rampa è 1 / s 2
segnale parabolico :
Nel dominio del tempo viene rappresentato da t 2 / 2.
La trasformazione di
Laplace
del segnale
3
parabolico è 1 / s
segnale sinusoidale:
Nel dominio del tempo viene rappresentato da sin
(ωt) . la Laplacetrasformazione della sinusoide è
ω / (s 2 + ω 2)
segnale cosinusoidale:
Nel dominio del tempo viene rappresentato da
cos (ωt). Latrasformazione di Laplace del coseno
è ω / (s 2 + ω 2 )
SEGNALI CANONICI
La risposta del sistema è la somma di due contributi.
Il primo è indipendente dalle condizioni iniziali e dipende solo dall’ingresso (risposta forzata): si
ottiene quando al sistema è applicato un ingresso e le condizioni iniziali sono nulle.
Il secondo è indipendente dal segnale forzante e dipende solo dalle condizioni iniziali (risposta
libera): è l’evoluzione dinamica del sistema privo di ingresso con condizioni iniziali non nulle.
Le radici del polinomio a numeratore della funzione di trasferimento G(s) ( RAPPORTO FRA USCITA
E INGRESSO) sono dette zeri del sistema (in numero pari a m), mentre le radici del polinomio a
denominatore della funzione di trasferimento G(s) sono dette poli del sistema ( in numero pari a
n).
Gli zeri e i poli di un sistema possono essere o reali o complessi e coniugati a coppie.
TRASFORMATA DI LAPLACE
Per descrivere l’evoluzione di un sistema in regime transitorio, ossia durante il passaggio delle
uscite da un regime stazionario ad un altro, è necessario ricorrere ad un modello più generale
rispetto al modello statico, detto modello matematico dinamico.
Tale modello è costituito da una o più equazioni differenziali che legano non solo le variabili
incognite di uscita (effetti) con quelle note di ingresso (cause), ma anche le loro derivate
rispetto al tempo.
Oltre ai metodi classici derivati dall'analisi matematica, per risolvere una equazione
differenziale lineare a coefficienti costanti, quale quella descritta precedentemente, si può
utilizzare l’operatore di trasformazione secondo Laplace.
Si tratta di un procedimento che presenta numerosi vantaggi rispetto alle tecniche classiche
dell’analisi. In particolare, esso trasforma equazioni integro-differenziali in equazioni
algebriche, di più semplice risoluzione.
La trasformata di Laplace è una trasformazione funzionale. Tale trasformazione stabilisce una
corrispondenza biunivoca tra funzioni oggetto (funzioni del tempo) e funzioni immagine della
variabile complessa s.
Lo studio dei transitori dei sistemi viene effettuato attraverso l’applicazione della trasformata di
Laplace che consente di trasformare equazioni
differenziali complesse di cui sono note le
costanti in semplici
polinomi. le trasformate di Laplace possono essere utilizzate solo per
risolvere le equazioni differenziali complesse con costanti note .
TRASFORMATA DI LAPLACE
L'operazione di trasformazione a partire dalla sua definizione matematica può risultare abbastanza
complicata, ma nella pratica viene in genere eseguita facilmente consultando delle tabelle, che
mettono in relazione le principali funzioni nel dominio del tempo con le corrispondenti funzioni nel
dominio della frequenza, e/o applicando delle semplici regole di trasformazione.
La frequenza complessa S è definita come S = σ + j ω.
La trasformata di Laplace è un operatore
che associa ad una funzione del tempo f(t)
definita per t≥0 una funzione F(s) a valori
complessi definita per valori della variabile
complessa s.
L’utilizzo delle trasformate di Laplace consente di
semplificare notevolmente i calcoli nella risoluzione
di equazioni differenziali: operazioni di derivazione
ed integrazione nel dominio del tempo corrispondono
ad operazioni di tipo algebrico nel dominio delle
trasformate.
ANTITRASFORMATA DI LAPLACE
Data una funzione di Laplace F(s), si definiscono:
- zeri di F(s) i valori di s che annullano il numeratore
- poli di F(s) i valori di s che annullano il denominatore.
Antitrasformazioni immediate:
F(s) = 6/ s
f (t) = 6
F(s) = 5 s^3
f (t) = 5 ⋅t2^2
F(s) = 6/S+2
f (t) = 6⋅e−2⋅t
Una funzione razionale (rapporto tra polinomi) può essere scomposta in somma di fratti semplici:
da cui è immediata la antitrasformazione:
Da cui è immediata la antitrasformazione:
f (t) = R1 ⋅e^(s1⋅t) +R2 ⋅e^(s2⋅t)
ANTITRASFORMATA DI LAPLACE
La risposta impulsiva di
un sistema può essere
ricavata
applicando
in
ingresso un segnale che
approssimi l’impulso di
Dirac e misurando l’uscita
corrispondente.
L’impulso
di
Dirac
è
un’astrazione
matematica
che
può
solo
essere
approssimata.
In molti casi non è
possibile né conveniente
applicare al sistema una
sollecitazione
impulsiva
per non danneggiare il
sistema
a
causa
dell’elevata
ampiezza
dell’impulso.
TRASFORMAZIONI
Le trasformazioni in matematica sono spesso utilizzate per aggirare le rilevanti difficoltà che si
presentano nello svolgere direttamente i calcoli richiesti. Per esempio:
 nella esecuzione di calcoli come prodotti e divisioni
 nella risoluzione di equazioni come quelle biquadratiche e differenziali.
Un prodotto è convertito in somma mediante la trasformazione Logaritmo. Il percorso della
trasformazione è più lungo, ma meno difficoltoso.
Una equazione biquadratica è risolvibile con una semplice sostituzione:
Una equazione differenziale lineare si può risolvere più facilmente con delle opportune trasformazioni.
 Se le variabili di ingresso sono sinusoidali e interessa la soluzione a regime si può ricorrere alla
trasformazione di Steinmetz: (proposta per risolvere i circuiti elettrici in corrente alternata)
Osservazioni: questa trasformazione
 non fornisce informazioni sul funzionamento durante il transitorio in quanto
presuppone che l’ingresso sinusoidale sia applicato da talmente tanto tempo da essersi
esauriti tutti i transitori
 ha permesso, se non la comparsa, certamente una migliore gestione del concetto di
impedenza (che non esiste nel dominio del tempo).
 Per le variabili di ingresso che hanno andamenti generici e sono nulle per t <= 0 è stato
elaborato un procedimento noto col nome di Trasformata di Laplace
Osservazione:
La soluzione descrive il funzionamento del
circuito a partire da t = 0, comprendendo quindi
oltre al regime, anche il transitorio (in quanto si
segue
l’ingresso
sin
dalla
sua
prima
applicazione al sistema: cioè per t >= 0).
TEOREMA DEL VALORE INIZIALE/FINALE
teorema del Valore iniziale
Ci permette di trovare il valore iniziale al tempo t = (0 + ) per una data funzione (Laplace)
senza ricorrere alla f (t), che richiede un processo molto noioso .
poi teorema Valore iniziale è dato da
Applicazioni
Trovare il valore iniziale per la funzione
dal teorema del valore iniziale
il valore iniziale è 5.
TEOREMA DEL VALORE INIZIALE/FINALE
Esempio 2: trovare il valore iniziale della funzione trasformata
dal teorema valore iniziale
Esempio 3:
Trovare il valore iniziale di
Valore iniziale teorema non è applicabile in quanto il polinomio del numeratore deve essere
inferiore del polinomio denominatore.
TEOREMA DEL VALORE INIZIALE/FINALE
esempio 4
Risolvere l'equazione utilizzando trasformata di Laplace
questo può essere risolto utilizzando frazioni parziali, che è più facile che risolvere nella
sua forma precedente. In primo luogo, il denominatore deve essere fattorizzato.
i coefficienti A e B devono essere trovati
Sostituendo nell'equazione:
Quindi, utilizzando la tabella l'equazione può essere riconvertito in forma normale.
TEOREMA DEL VALORE INIZIALE/FINALE
teorema del valore Finale
E 'molto interessante scoprire che possiamo trovare il primo valore o l'ultimo valore di f (t) ,
senza dover studiare la funzione intera f (t).
Ci permette di trovare il valore finale al tempo t = (0 - ) per una data funzione
esempi
trovare i valori finali di F(s) senza calcolare esplicitamente f (t)
Risposta
TRASFORMATA DI LAPLACE: esercizi
TRASFORMATA DI LAPLACE CON POLI COMPLESSI CONIUGATI
Antitrasformazione in presenza di poli complessi coniugati:
Se i poli sono complessi coniugati, tali risultano anche i residui:
TRASFORMATA DI LAPLACE:SOLUZIONE EQUAZIONI DIFFERENZIALI
TRASFORMATA DI LAPLACE:SOLUZIONE EQUAZIONI DIFFERENZIALI
TRASFORMATA DI LAPLACE:SOLUZIONE EQUAZIONI DIFFERENZIALI
ALGEBRA DEGLI SCHEMI A BLOCCHI
ALGEBRA DEGLI SCHEMI A BLOCCHI
ESERCIZI
ALGEBRA DEGLI SCHEMI A BLOCCHI
Nei controlli automatici spesso il legame fra due variabili viene indicato con un blocco, ad
esempio con il simbolo
si vuole intendere che la variabile y(t) è dipendente dalla variabile x(t). Ù
Se il legame tra tali grandezze è lineare, tempo invariante e statico, ossia espresso da un
guadagno G, il blocco è puramente algebrico, e istante per istante vale la relazione y=Gx e il
blocco viene indicato come in figura.
Esaminiamo ora una serie di regole che consentono di trasformare uno schema a blocchi in un
nuovo diagramma equivalente al primo ma più semplice e compatto.
per risolvere schemi a blocchi comunque complicati si devono rispettare le seguenti condizioni:
- sistemi lineari
- semplificazione a partire dal blocco interno
- blocchi concentrici , non si devono intersecare
ALGEBRA DEGLI SCHEMI A BLOCCHI
punto di diramazione (collegamento parallelo)
Blocchi in parallelo
Le relazioni espresse nello schema sono:
y1=G1x
y2=G2x
y=y1+y2
Considerando simultaneamente le equazioni si ha:
y=y1+y2=(G1+G2)x=Gx, con G=G1+G2
Perciò lo schema di partenza si può trasformare in uno più
semplice
ALGEBRA DEGLI SCHEMI A BLOCCHI
2) Blocchi in cascata o serie
Consideriamo lo schema
Si ha:
y=G2z=G1G2x
quindi il diagramma equivalente è:
Si conclude che la serie o cascata di due o più blocchi è equivalente ad un unico blocco il
cui guadagno è pari al prodotto dei guadagni dei blocchi componenti.
3) Scambio di giunzioni sommanti
Lo schema:
indica l’operazione:
z=(x+y)+w
ALGEBRA DEGLI SCHEMI A BLOCCHI
ALGEBRA DEGLI SCHEMI A BLOCCHI
Reazione negativa/positiva
esprime le relazioni:
y=Ge,
e=x-z=x-Hy
quindi
y=Gx-GHy,
ossia
Y = x* G/(G+H)
ESERCIZI
ESERCIZI
ESERCIZI
COMPORTAMENTO IN REGIME TRANSITORIO
RISPOSTA NEL DOMINIO DEL TEMPO
RISPOSTA LIBERA E FORZATA
TRANSITORIO E REGIME
SISTEMI DEL 1 ORDINE
SISTEMI DEL 2 ORDINE
ESEMPI APPLICATIVI
Poli dominanti
Risposta nel dominio del tempo
In un sistema possono essere presenti più accumulatori di energia, quindi più variabili di stato, ossia più poli nelle
funzioni di trasferimento.
Ad ogni polo corrisponde una costante di tempo.
Le costanti di tempo più grandi determinano la durata complessiva del transitorio. Quando sono molto più grandi,
il transitorio è di fatto determinato da esse.
Alle costanti di tempo più grandi corrispondono i poli più piccoli (in valore assoluto). Questi poli sono chiamati
dominanti.
Se nel sistema sono presenti poli dominanti, gli altri poli si possono trascurare.
Consideriamo un generico sistema
Se il segnale d’ingresso e(t) subisce brusche variazioni, il segnale d’uscita (risposta del sistema) è
costituito dalla somma di una risposta transitoria ed una risposta permanente (o risposta a regime).
Per determinare il segnale d’uscita u(t), si procede nel seguente modo:
1.Si determina la G(s)G(s) = U(s)/E(s)
2.Si determina la E(s), facendo uso delle tabelle delle Td.L
3.Si calcola l’uscita U(s) =G(s)*E(s)
4.Si antitrasforma la U(s) per risalire alla u(t)
16
RISPOSTA FORZATA E RISPOSTA LIBERA
Classificazioni dei sistemi per ordine
La classificazione per ordine di un sistemi viene fatto in relazione al numero di poli della sua
f.d.t.
Un sistema quindi dicesi di:
- ordine zero quando la sua f.d.t. non presenta poli
- ordine uno quando la sua f.d.t. presenta un polo (denominatore della f.d.t. è un polinomio di primo
grado)
- ordine due quando la sua f.d.t. presenta 2 poli (denominatore della f.d.t. è un polinomio di secondo
grado)
La risposta di un si può scomporre in: y(t) = yFORZATA (t) + yLIBERA (t)
Componente FORZATA: csistemaomponente della risposta che dipende direttamente dall’azione
forzante, cioè dall’ingresso (corrisponde alla risposta del sistema quando quest’ultimo è, nell’istante
iniziale, allo stato zero)
Componente LIBERA: componente della risposta che non dipende direttamente dall’ingresso (è la
risposta che il sistema produce nonostante l’ingresso sia nullo; è diversa da zero solo se il sistema ha
accumulato energia in precedenza)
Esempio: circuito RC, ingresso e(t) = k
Esempio: circuito RL, ingresso x(t) = e(t) = k
Transitorio e Regime
La risposta di un sistema può essere scomposta in componente transitoria yT(t) e componente di
regime yR(t) :
y(t) = y (t) + y r(t)
La componente transitoria è formata da tutti quei termini che si annullano per il tempo che tende a
infinito.
La componente di regime è formata da tutti quei termini che invece non si annullano, cioè:
y R (t) = lim y(t)
tinf
NB: nei sistemi lineari la componente di regime assume la stessa forma
d’onda dell’ingresso.
• Nel dominio del tempo le variabili sono esaminate secondo la loro evoluzione temporale
• Normalmente si esamina la risposta del sistema a un segnale di prova canonico, cioè si sollecita il
sistema con un:
.
ingresso a gradino
ingresso a impulso
NB: non sempre è possibile ricavare sperimentalmente la risposta del sistema
all’impulso, in
quanto l’impulso deve fornire l’energia sufficiente al sistema per provocarne la risposta.
SISTEMI DEL 1° ORDINE
Un sistema del 1° ordine è un sistema con un solo accumulatore di energia. Ossia un
sistema il cui comportamento è descrivibile con una sola variabile di stato.
NB: si assume come uscita del sistema la variabile di stato y(t)
y(t)
y(t)
Risposta all’impulso:
Risposta al gradino:
t
t
Le prestazioni di un sistema (non solo del 1° ordine) nel dominio del tempo sono spesso
fornite
con l’indicazione di alcuni tempi caratteristici definiti nella risposta al gradino.
tD : tempo di ritardo (delay time)
Fornisce l’indicazione della prontezza di risposta del sistema
tR : tempo di salita (rise time)
Fornisce l’indicazione della accelerazione di y(t)
tS : tempo di assestamento (setting time. Fornisce l’indicazione della
durata del transitorio. Corrisponde al
tempo impiegato dalla
risposta y(t) per portarsi entro la fascia +/- Δ%
SISTEMI DEL 2° ORDINE
Un sistema del 2° è un sistema il cui comportamento è descritto da due variabili di stato, sono
cioè sistemi con due accumulatori di energia:
La risposta nel tempo dipende dai poli della funzione di trasferimento. Per meglio descriverle si
introducono due parametri:
• δ = coefficiente di smorzamento
• ωn = pulsazione naturale [rad/s]
E si
eseguono le seguenti sostituzioni:
a1 = 2·δ·ωn,
a0 = ω2n
SISTEMI DEL 2° ORDINE
La risposta al gradino presenta un transitorio che dipende solo dai poli della funzione di trasferimento.
I tre poli di Y(s) risultano
NB: s1 e s2 sono i poli della funzione di trasferimento; possono
essere reali o complessi in funzione di .
Sistema sovrasmorzato
Ipotesi:
I poli
y(t)
 1
Im
 s t
y(t)  K 0  K 1 e s1t  K 2 e 2
della fdt sono reali distinti
>1
•
•
s2
s1
•
Re
s0
t
Sistema a smorzamento critico
y(t)
Ipotesi:
Im
 1
I poli
=1
sono reali coincidenti
y(t)  K 0  K t e
st
•
s1 = s2
•
s0
Re
t
SISTEMI DEL 2° ORDINE
Sistema sottosmorzato
Ipotesi:
 1
s
I poli sono complessi coniugati
0
y(t)  K  2 K e cos(t  )
t
1,2
   j
n
n
12
NB: ωn rappresenta la pulsazione alla quale
oscillerebbe la risposta del sistema nel caso
assenza di smorzamento ( = 0).
di
SISTEMI DEL 2° ORDINE
Relazioni tra i poli della funzione di trasferimento e i parametri  e ωn
Dall’espressione dei poli della funzione di trasferimento:
s 1,2  n  jn
1  2
risultano le seguenti corrispondenze:
  n
   n 1 2
s   2  2   n
Da cui: (prescindendo dal segno di )


 cos 
n
n 

1  2
,
sotituendo  
dopo alcuni calcoli risulta
:

,
n
n 
 2  2
SISTEMI DEL 2° ORDINE
Relazione tra massima sovraelongazione e 
Nei sistemi del 2° ordine senza zeri, con poli complessi coniugati (delta < 1), la massima
sovraelongazione SMAX dipende solo dal coefficiente di smorzamento :
SMAX%
y(t)
yMAX
SMAX
yR
t

SISTEMI DEL 2° ORDINE
Esercizio: Circuito RLC serie, calcolo  e ωn in funzione dei parametri del circuito
La tensione e(t) rappresenta l’ingresso. Come uscita è assunta la tensione sul condensatore.
Si deve manipolare la funzione di trasferimento
in modo da porre uguale a 1 il coefficiente del termine con s2
:
Osservando la funzione di traferimento, risulta:
Da cui:
 
1
2
R
C
L
n 
1
LC
NB: un aumento di R comporta un aumento di ,,
mentre non influisce su ωn.
Sistema del 2° ordine, la cui funzione di trasferimento possiede uno zero
SISTEMI DEL 2° ORDINE
La presenza di uno zero:
• altera la pendenza con cui la risposta si avvia: non più con tangente orizzontale.
• altera SMAX, che non dipende più solo da 
• non altera la pulsazione di oscillazione ω
X(s)
k bs 1
s 2  a 1s a
Y(s)
0
Nel sistema è presente uno zero:
s
1
b
NB: con zero positivo il sistema presenta una risposta che
si avvia in direzione opposta.
SISTEMI DEL 2° ORDINE
Esaminando la risposta nel tempo, è possibile stimare i parametri della funzione di trasferimento.
Esempio: sistema del 2° senza zeri (ricavare k, , ωn)
X0
X(s)
t
k
2
s  2  s  2
n
Y(s)
n
Per il calcolo del valore di regime yR è conveniente ricorrere
al teorema del valore finale:
Calcolo :
Dal grafico della risposta si legge yMAX e yR, con essi si calcola SMAX e
per via grafica si ricava .
Calcolo ωn:
Dal grafico della risposta si legge il periodo T, con esso si calcola la

pulsazione di oscillazione ω = 2  / T, e quindi: n 
2
1 
Calcolo k:Applicando il teorema del valore finale si ottiene:
SISTEMI DEL 2° ORDINE: ESEMPI APLICATIVI
5RISPOSTA
AL GRADINO DI AMPIEZZA E DI UN SISTEMA DEL 2°
ORDINE CON  >1, (POLI REALI ISTINTI E NEGATIVI)
La risposta al gradino è aperiodica
RISPOSTAAL GRADINO DI AMPIEZZA E DI UN SISTEMA DEL 2° ORDINE CON =1, (POLI REALI CCOINCIDENTI E NEGATIVI)
La risposta al gradino è aperiodica
SISTEMI DEL 2° ORDINE: ESEMPI APPLICATIVI
RISPOSTA AL GRADINO DI AMPIEZZA E DI UN SISTEMA DEL 2° ORDINE CON  <1, (POLI COMPLESSI E CONIUGATI CON
PARTE REALE NEGATIVA )
La risposta al gradino è oscillatoria smorzata
Studio della riposta del sistema retroazionato
Calcolo della f.d.t. del sistema retroazionato W(s)
Il circuito retroazionato è equivalente al circuito in figura
con H(s)=1
SISTEMI DEL 2° ORDINE: ESEMPI APPLICATIVI
SISTEMI DEL 2° ORDINE: APPLICATIVI
La risposta si ricava antitrasformando la U(s), facendo uso delle tabelle
delle T.d.L.
SISTEMI DEL 2° ORDINE: ESEMPI APPLICATIVI
Il sistema descritto dallo schema a blocchi è sottoposto ad un
gradino di ampiezza 5
Determinare:
a) il valore a regime
b) il tempo di salita
c) il tempo a cui avviene l’overshoot
d) il valore dell’overshoot
e) il valore max del segnale d’uscita
f) il tempo di assestamento al 2%
Soluzione
 Calcolo della risposta U(s)
Il circuito retroazionato è equivalente al circuito in figura con H(s)=1
Confrontiamo la nostra fdt con quella standard
SISTEMI DEL 2° ORDINE: ESEMPI APPLICATIVI
Il comportamento dei sistemi di controllo in regime permanente
CLASSIFICAZIONE DEI SISTEMI DI CONTROLLO
ERRORE STATICO
CALCOLO DELL'ERRORE A REGIME
CONSIDERAZIONI SUL SEGNALE D'INGRESSO
COMPORTAMENTO DEI SISTEMI DI CONTROLLO TIPO 0
COMPORTAMENTO DEI SISTEMI DI CONTROLLO TIPO 1
COMPORTAMENTO DEI SISTEMI DI CONTROLLO TIPO 2
TABELLA RIASSUNTIVA
ESERCIZI
DISTURBI ADDITIVI
ESERCIZI
CLASSIFICAZIONE DEI SISTEMI DI CONTROLLO AD ANELLO CHIUSO
La classificazione dei sistemi ad anello chiuso per tipo, viene fatto in relazione al numero di poli nell’origine della f.d.t. ad anello
aperto. Il tipo del sistema indica il numero dei poli che la G(s)H(s) presenta nell’origine
N. dei poli nulli della G(s)H(s)
classificazione
0
1 (s al denominatore )
2 (s2 al denominatore )
sistema di tipo zero
sistema di tipo uno
sistema di tipo due
Nel progetto di un sistema di controllo ad anello chiuso occorre tener conto, della precisione e della sensibilità ai disturbi additivi e
parametrici .
ERRORE A REGIME
La precisione rappresenta la capacità di un sistema di produrre una risposta la più simile possibile a quella desiderata, ma in un
sistema di controllo reale l’uscita non è mai esattamente quella desiderata ma è affetto da errore
La precisione di un sistema è evidenziata dall’errore statico, cioè
l’errore permanente o a regime. Esso è definito come differenza tra
il valore d’uscita desiderata u0 (t )e il valore realmente ottenuto u(t )
a transitorio esaurito, quando vengono applicati in ingresso i segnali
tipici: gradino; rampa; parabola
ERRORE STATICO
Alimentazione di potenza
X(s)
E(s)
YRET(s)
Y(s)
G(s)
H(s)
Per errore statico si intende lo scostamento, a regime, della variabile controllata Y(s) dal valore
desiderato.
Tale scostamento è in relazione con il segnale errore E(s) uscente dal nodo di confronto: essi hanno
lo stesso valore percentuale.
E’ allora possibile svolgere i calcoli sul segnale errore E(s).
E(s)  X (s)  X RET (s)  X (s)  H (s) Y (s)  X (s)  H (s)  X (s) 
G(s)
X (s)

1 G(s)  H (s) 1 G(s)  H (s)
CALCOLO DELL’ERRORE A REGIME
Il calcolo dell’errore a regime richiede il calcolo del limite
dove è richiesta la conoscenza della funzione e(t), cioè della antitrasformata di E(s).
E’ possibile evitare la antitrasformazione ricorrendo al teorema del valore finale:
er  lim e(t)  lim s  E(s)
t  s0
e sostituendo l’espressione di E(s):
er  lim s 
s0
X(s)
X(s)
 lim s 
1 G(s) H(s) s0 1 L(s)
Osservazioni: la precisione statica dipende quindi dal
 Valore del segnale di ingresso X(s)
 Guadagno d’anello G(s)•H(s)
Il comportamento dei sistemi di controllo in regime permanente
Considerazioni sul GUADAGNO D’ANELLO
L(s) = G(s)•H(s)
In assenza di ritardi finiti, le funzioni di trasferimento sono razionali, cioè si presentano come rapporto tra polinomi:
L(s)  G(s) H(s) 
1 N(s)
s n D(s)
I sistemi con retroazione sono classificati in tipi, in funzione del numero di poli nulli presenti nel guadagno d’anello:
n =0
n =1
n =2
………
sistema tipo 0
sistema tipo 1
sistema tipo 2
Ai fini del calcolo dell’errore statico conviene porre:
L' (s) 
N(s)
D(s)
LST = valore statico del guadagno d’anello
Considerazioni sul SEGNALE DI INGRESSO
Le prestazioni a regime dipendono anche dalla forma del segnale d’ingresso. In alcuni sistemi il segnale di ingresso non ha
una forma prestabilita, per cui si caratterizza la precisione statica considerando segnali con forma standard (canonica).
Ingresso a gradino
Ingresso a rampa
X0
X(s) 
s
x(t)  X 0
X(s) 
x(t)  X0  t
X0
s2
X0
t
X0 t
t
Ingresso a parabola
x(t)  X 0  t
2
2X0
X(s) 
s3
X0 t 2
t
Il comportamento dei sistemi di controllo in regime permanente TIPO 0
e r  lim s 
SISTEMA TIPO 0
s0
n =0
X(s)
1 L(s)
Guadagno d’anello: L(s)  N(s)
D(s)
Calcolo dell’ERRORE a regime:
Ingresso a gradino
Errore di posizione
X0
X0
X0
e r  lim s  s


s0
1 L(s) 1 lim N(s) 1 L ST
s0 D(s)
Ingresso a rampa
Errore di velocità
X0
2
X0
s
e r  lim s 
 lim

s0
s0
1 L(s)
s  s L(s)
Ingresso a parabola
Errore di accelerazione
2  X0
3
2  X0
s
e r  lim s 
 lim 2

2
s0
s0
s

s
L(s)
1 L(s)
Il comportamento dei sistemi di controllo in regime permanente TIPO 0
Ingresso a rampa
SISTEMA TIPO 0
Errore di velocità
Errore assoluto sull’uscita del sistema si ricava dividendo quello
sul nodo di confronto er per il guadagno statico della fdt di
retroazione H0:
e
yr 
r
H0

Il comportamento dei sistemi di controllo in regime permanente TIPO 1
e r  lim s 
SISTEMA TIPO 1
n=1
Guadagno d’anello:
Calcolo dell’ERRORE
Ingresso a gradino
Errore di posizione
Ingresso a rampa
Errore di velocità
Ingresso a parabola
Errore di accelerazione
s0
L(s) 
X(s)
1 L(s)
1 N(s)
s D(s)
X0
X0
s
e r  lim s 

0
s 0
1  L(s) 1  lim 1N(s)
s0 s D(s)
X0
X0
X
s 2  lim
er  lim s 
 0
s0
1 L(s) s0 s  s  N(s)
LST
s  D(s)
2X 0
3
X0
s
e r  lim s 
 lim

s0
s0
1N(s)
1 L(s)
s2  s2
s D(s)
Il comportamento dei sistemi di controllo in regime permanente TIP0 1
Ingresso a rampa
SISTEMA TIPO 1
Errore assoluto sull’uscita del sistema si ricava
dividendo quello sul nodo di confronto er per il
:
guadagno statico
della fdt di retroazione H0
yr 
Ingresso a gradino
Errore di posizione
Errore di velocità
Errore assoluto
sull’uscita del sistema
y r 
X0
LST  H 0
er
H0
0
Ingresso a parabola
Errore di accelerazione

Il comportamento dei sistemi di controllo in regime permanente tipo 2
SISTEMA TIPO 2
n =2
Guadagno d’anello:
L(s) 
1 N(s)
s 2 D(s)
Calcolo dell’ERRORE
Ingresso a gradino
Errore di posizione
Ingresso a rampa
Errore di velocità
Ingresso a parabola
Errore di accelerazione
X0
X0
s
e r  lim s 

0
s0
1 L(s) 1  lim 1 N(s)
s0 s2 D(s)
X0
s2
e r lim s 
 lim
s0
1 L(s) s0
X0
0
1 N(s)
s s 2
s D(s)
2X 0
2X 0
X0
s3  lim
e r lim s 

s0
1 L(s) s0 s 2 s 2 1 N(s)
LST
2
s D(s)
Il comportamento dei sistemi di controllo in regime permanente: tipo 2
Ingresso a rampa
SISTEMA TIPO 2
Errore assoluto sull’uscita del sistema si ricava dividendo quello
sul nodo di confronto er per il guadagno statico della fdt di
retroazione H0:
yr 
Ingresso a gradino
Errore di posizione
Errore di velocità
0
er
H0
0
Ingresso a parabola
Errore di accelerazione
Errore assoluto
sull’uscita del sistema
y r 
2 X 0
LST  H 0
RIEPILOGO
TABELLA RIASSUNTIVA
NB: le espressioni che appaiono in tabella si riferiscono ai valori assoluti calcolati
rispetto al segnale errore er :
RIEPILOGO
ESERCIZIO
1) Dimensionare il ramo di retroazione
2) Calcolare il guadagno A0 del convertitore di potenza in modo da avere un errore a regime al 5%
3) Verificare la stabilità del sistema ricorrendo al metodo di Routh, nell’ipotesi che il convertitore sia caratterizzato
da una risposta istantanea.
Soluzione
1) Dimensionare il ramo di retroazione
Si calcola il valore statico di H(s):
H0 
XRIF  4  0.0465
YID
86
2) Calcolare il guadagno statico A0 del convertitore di potenza in modo da avere un errore a regime  al 5%
L’incognita A0 è nascosta all’interno dell’espressione dell’errore a regime e precisamente nella costante LST.
Il sistema è di tipo 0, l’ingresso è un gradino, dalla specifica risulta
er 
La costante LST risulta:
X0
 er MAX
1  L ST
LST  lim L'(s)  A 0 10 H 0  A 0  0.465
s0
mentre l’errore massimo ammissibile è :
e r MAX  0.05  4  0.2
Per il calcolo di A occorre dunque
0 risolvere ladisequazione:
La cui soluzione conduce a A0  40.9
4
 0.2
1 A0 0.465
Soluzione
3) Verificare la stabilità del sistema ricorrendo al metodo di Routh
Occorre valutare il comportamento dinamico del ramo di retroazione e del convertitore di potenza.
Si ipotizza che siano entrambi privi di fenomeni dinamici, cioè che presentino una risposta immediata.
• H(s) = H0
• A(s) = A0
Si deve calcolare l’equazione caratteristica dell’intero sistema, ma prima occorre assegnare un valore
al guadagno A0 del convertitore:
Ipotesi A0 = 41.
L’equazione risulta:
Tabella di Routh:
1
6
5
20.1
1.98
20.1
s3  5s 2  6 s  20.1  0
Non essendoci variazioni di segno nella prima colonna, il sistema risulta stabile.
Infatti le soluzioni risultano: S1 = - 4.639
S2 = - 0.181 + j 2.072 S3 = - 0.181 – j 2.072
Esercizio
Il comportamento dei sistemi di controllo in regime permanente
Sapendo che l’errore a transitorio esaurito vale 1,5 per un segnale d’ingresso a parabola unitaria, determinare il valore di k
Soluzione
Il
sistema è di tipo 2, poiché nella della f.d.t. ad anello aperto compaiono due poli nulli.
L’errore a regime è uguale a
e()  lim s 
s0
 Per un segnale a parabola unitaria
R(s)
H0 1G(s)H0 
r(t) = t2
2
e R(s) =
s3
questo errore è:
Il comportamento dei sistemi di controllo in regime permanente
Esercizio
Ricavare il valore di k affinché l’errore a regime sia minore del 2% per un segnale d’ingresso a gradino unitario.
Soluzione
Il sistema è di tipo 0, poiché la f.d.t. ad anello aperto non ha poli nell’origine .
G(s)H(s) =
L’errore a regime è uguale a
e()  lim s 
s0
0,4k
s2  0,4s  0,04
R(s)
H0 1G(s)H0 
 Per un segnale a gradino unitario r(t) = 1 e R(s) = 1/s questo errore è:
p= e()  lim s 
s0
1

s 1
1
0,4k
s2  0,4s  0,04
1
0,4k
= lim
s0 1 
s2  0,4s  0,04
=
1
0,4k
1
0,04

Posto p < 2/100 si ricava k
2  1  0,4k  50  0,4k  49
1
<
0,04
0,04
1  0,4k 100
0,04
k
49  0,04
0,4
 k  4,9
DISTURBI ADDITIVI: GENERALITÀ
I disturbi additivi sono segnali indesiderati che entrano nel sistema e si sommano al segnale utile
Ad esempio in un sistema di riscaldamento la variazione della temperatura esterna è un disturbo additivo che provoca una
variazione non desiderata del valore della grandezza fisica. Per valutare l’effetto prodotto da uno o più disturbi sulla risposta si
applica il principio di sovrapposizione degli effetti.
ESERCIZI - EFFETTI DEI DISTURBI ADDITIVI
Esercizio 1 – Disturbo sul blocco di andata - Risposta a regime
Determinare la risposta a regime del sistema in figura sollecitato da un segnale a gradino unitario. Il disturbo ha ampiezza 0,1.
Soluzione
Per determinare l’uscita applichiamo e il principio di sovrapposizione degli effetti: considerando l’uscita
come somma dell’uscita U1(S) dovuta al segnale R(s), e U2(s), dovuta al disturbo.
Consideriamo agente solo il segnale R(s) poniamo 1(s) =0
Riducendo i due blocchi in cascata ad un solo blocco con fdt G1G2 si ha
W1 
G1  G 2
1  G1  G 2  H
U1  W  R
Soluzione
Avendo in ingresso un gradino di ampiezza unitaria
R(s)=1/s :
8
1
(uscita complessa in assenza del disturbo)
U1(s)  
s s3  6s2  11s  38
1 8
= 0,21 (valore a regime)
Uf1 = lim s  U1(s) = s 
s s3  6s2  11s 38
s0

Consideriamo ora, agente solo il disturbo 1(s) poniamo R(s)= 0
Lo schema è equivalente
Riducendo i due blocchi in cascata ad un solo blocco si ha
Soluzione
W2 
G2
1  G2  G1  H
U2  W2  1
8
8
8(s 3)
(s 1)(s 2)
W2  (s  1)(s 2)
= W2 

32
(s 1)(2)(s  3)  32 (s  1)(s  2)(s  3)
1
(s  1)(s  2)(s  3)
(s 1)(s  2)(s  3)
8(s  3)
=
s3  6s2 11s  38
Avendo in ingresso un disturbo di ampiezza 0,1  1(s)=0,1/s sostituendo si ha :
(uscita complessa dovuta al solo disturbo)
U2 (s)  0,1  8(s 3)
s s3  6s2 11s  38
8(s 3)
Uf 2 = lim s  U2 (s) = lim s  0,1  8(s 3)
= lim
3
2
3
s s  6s  11s 38 s0 s  6s2  11s  38
s0
s0
Uf 2 =
2,4
= 0,063 (valore a regime dovuto al solo disturbo)
38
La risposta complessiva a regime è
Uf  Uf1  Uf 2 = 0 , 21 +0 , 06 3 = 0,273

ESERCIZIO
Esercizio 2 – Disturbo all’ ingresso e sul blocco di andata - Risposta a regime
Determinare la risposta a regime del sistema in figura sollecitato da un segnale a gradino unitario. I disturbi hanno entrambi
ampiezza 0,1 Per determinare l’uscita applichiamo e il principio di sovrapposizione degli effetti: considerando
l’uscita come somma dell’uscita U0(S) dovuta al segnale R(s), U1(s), dovuta al disturbo 1(s) e U2(s) , dovuta al disturbo 2 (s)

Consideriamo agente solo il segnale R(s), poniamo 0(s) =0 e 1(s) =0
10
(s
1)(s
5)
W0 (s) 
=
50
1
(s 1)(s  2)(s  5)
10(s  2)
=
s3  8s2  17s  60
10
10(s  1)(s  5)
(s 1)(s 5)
=
=
(s 1)(s  2)(s  5)  50 (s2  3s  2)(s  5)
(s 1)(s  2)(s  5)
SOLUZIONE
U0 (s)  W1(s)  R(s)
Avendo in ingresso un gradino di ampiezza unitaria
U0 (s) = 1  10(s  2)
s s3  8s2  17s  60
Uf 0
(uscita complessa in assenza dei disturbi)
= lim s  U0 (s) = s  1  10(s  2)
s0
R(s)=1/s, sostituendo si ha:
s s3  8s2  17s 60
= 20
=
0,333
( valore a regime)
60
 Consideriamo ora agente solo il disturbo 1(s) =0, poniamo R(s) e 1(s) =0
W1(s)  W0 (s)  =
10(s 2)
s3  8s2 17s  60
; U1(s)  W1(s) 1(s)
Avendo in ingresso un disturbo di ampiezza 0,1  1(s)=1/s, sostituendo si ha:
(uscita complessa dovuta al disturbo 1 )
U1(s)  0,1 10(s  2)
s s3  8s2  17s  60
0,1 10(s  2)
Uf1 = lim s  U0 (s) = s  
= 20 = 0,033 (valore a regime )
s s3  8s2  17s 60 60
s0
SOLUZIONE

Consideriamo infine agente solo il disturbo 1(s) =0, poniamo R(s) e 0(s) =0

(uscita complessa dovuta al disturbo 1 )
U2 (s)  0,1 (s  2)(s  5)
s s3  8s2 17s  60
0,1 (s  2)(s 5)
= 1 = 0,017 ( valore aregime)
U f 2 = lim s  U0(s) = s  
s s3 8s 2 17s 60
60
s0
Nota
:
L’effetto del disturbo che si introduce nel blocco di andata è minore di quello all’ingresso.
Uf = Uf 0 + Uf1 + Uf 2 = 0,333+0,033+0,017 = 0,383
STABILITA DEI SISTEMI LINEARI
STABILITA DEI SISTEMI LINEARI
CRITERIO DI ROUTH-HURWITZ
RETROAZIONE NEGATIVA E VELOCITà DI RISPOSTA
STABILITA DEI SISTEMI LINEARI
• Introduzione
• Definizione: lo stato di un sistema è rappresentato dalla quantità e distribuzione dell’energia all’interno del sistema,
ed è riassumibile col valore assunto dalle variabili di stato.
• Lo studio del comportamento di un sistema si effettua esaminando l’evoluzione del suo stato.
• Quando il sistema permane in un determinato stato, cioè le sue variabili di stato permangono nei loro valori, lo stato è
definito ‘stato di equilibrio’.
• Lo stato di equilibrio può essere:
• instabile:
Il disturbo temporaneo fa
cambiare stato al sistema.
• stabile: Il disturbo temporaneo provoca variazioni limitate dello
stato (temporanee o permanenti).
STABILITA DEI SISTEMI LINEARI
Stabilità dei sistemi lineari
Nei controlli industriali si pretende però che, col venir meno della perturbazione, lo stato ritorni a quello di partenza, in
quanto diversamente la variabile controllata verrebbe a dipendere oltre che dall’ingresso di controllo, anche dalle
perturbazioni presentatesi in passato.
Nei sistemi la variabile controllata deve dipendere solo dall’ingresso di controllo (ingresso forzante), deve cioè essere
descritta dai soli termini della componente forzata. Solo così il controllore può controllare la variabile d’uscita del sistema.
Ciò equivale a pretendere che il sistema di controllo sia caratterizzato da una risposta libera che tenda ad estinguersi in
seguito alla scomparsa della perturbazione.
Esempio:
Risposta libera
che si estingue
t
Risposta
libera che si
estingue
Esempio:
y(t)
x(t)
Sistema
t
t
Comparsa
del disturbo
Esempio:
Scomparsa
del disturbo
y(t)
x(t)
Sistema
t
Risposta libera
che si estingue
t
STABILITA DEI SISTEMI LINEARI
Nei sistemi lineari la stabilità dell’intero sistema è garantita dalla stabilità di un singolo stato di equilibrio, in
quanto se la risposta libera si estingue a partire da uno stato si estingue a partire da qualsiasi altro stato di
equilibrio.
Ciò non è vero per i sistemi non lineari. Per essi lo studio della stabilità dell’intero sistema richiede lo studio della
stabilità di ogni singolo stato di equilibrio, che, in questi sistemi, dipende dall’ampiezza del disturbo.
Esempio:
STABILITA DEI SISTEMI LINEARI
Metodo di Routh - Hurwitz
a n s n  a n1 s n1  ............  a1 s  a 0  0
Data la seguente equazione caratteristica:
Condizione necessaria, ma non sufficiente, affichè tutte le radici siano a parte reale negativa è che i coefficienti abbiano
tutti lo stesso segno.
Il metodo permette la determinazione del segno delle radici senza risolvere l’equazione caratteristica: si costruisce la
seguente tabella:
n
an
an-2
an-4
…
n-1
an-1
an-3
an-5
…..
n-2
b1
b2
……
…..
…..
c1
…..
…..
….
0
….
b1 
c1 
a n1  a n2  a n  a n3
a n 1
b2 
a n1 a n4  a n a n5
a n1
b1 a n3  a n1  b 2
b1
Regola: ad ogni variazione di segno tra i termini consecutivi della prima colonna presentano corrisponde
una radice con parte reale positiva, ad ogni permanenza una radice con parte reale negativa.
STABILITA DEI SISTEMI LINEARI
ESEMPIO:
+
_
1
A
s  2 s  5 s 1
3
2
1)
Verificare la stabilità per A = 40.
2)
Calcolare il valore limite di A per cui il sistema si mantiene stabile.
0.1
Soluzione: occorre calcolare l’equazione caratteristica del sistema:
1)
3
1
s3  2 s 2  5 s 1 A 0.1  0
5
Non essendoci variazioni di segno nella prima colonna le
2)
2
2
1+4
1
2.5
0
0
5
soluzioni hanno parte reale negativa e quindi il sistema è
stabile.
3
1
5
2
2
1 + A·0.1
1
4.5 - A·0.05
0
0
1 + A·0.1
Per la stabilità non devono esserci variazioni di segno nella prima colonna:
4.5  A  0.05  0

1 A  0.1  0
A  90

A  10
Il guadagno negativo non ha significato pratico, per cui:
A < 90.
STABILITA DEI SISTEMI LINEARI
ESEMPIO:
+
_
1
s 2s  3
A
Calcolare il valore dell’intervallo di A per cui il sistema si mantiene stabile.
0.1
Soluzione: equazione caratteristica del sistema:
2
1
1
1
0
-6 + A·0.1
s 2  s  6  A 0.1  0
-6 + A·0.1
Per la stabilità deve essere:
6  A  0.1  0
Da cui:
A  60
NB: in questo esempio il sistema complessivo è tanto più stabile quanto maggiore è il guadagno. La causa è da ricercarsi nell’instabilità del blocco del
ramo diretto: la retroazione, unita a un alto guadagno, stabilizza il sistema.
Retroazione negativa e velocitò di risposta
La retroazione negativa modifica la larghezza di banda del sistema e quindi la sua velocità di risposta.
Come esempio si consideri il seguente sistema del 1° ordine:
k
s   1
X(s)  X 0
Y(s)  X(s)
k
s   1
Il valore di regime risulta:
YR  X k
0
Se si introduce un ramo di retroazione: h
X(s)  X 0
+
Y(s)  X(s)
k
s   1
_
k
s   1  k  h
Sono evidenti due conseguenze:
• diminuzione della costante di tempo:
h
• diminuzione del valore di regime:
Il calo del valore di regime dell’uscita può essere affrontato
preamplificando il segnale di ingresso:
X(s)  X 0
1 k  h
+
_
k
s   1
h
YR X  01 k h
'

1 k  h
YR X  0
k
1 k  h
k
 X 0 k
1 k  h
Retroazione negativa e velocitò di risposta
Con retroazione e
preamplificazione
Retroazione negativa e velocitò di risposta
QUINTA
RISPOSTA IN FREQUENZA
STABILITÀ DEI SISTEMI DI CONTROLLO
CONTROLLORI
ESERCIZIO: CONTROLLO DI UN MOTORE IN CC
ESERCIZIO: CONTROLLO DI SPESSORE
CONTROLLO DIGITALE
ARCHITETTURA DI UN SISTEMA DI CONTROLLO
Risposta in frequenza
CONTENUTO ARMONICO
RISPOSTA IN REGIME SINUSOIDALE
DIAGRAMMI DI BODE
TRACCIAMENTO DEI DIAGRAMMI DI BODE
GRAFICI DELLE FUNZIONI ELEMENTARI
RETI CORRETTRICI A SELLA, ANTICIPATRICE, RITARDATRICE
SISTEMI DEL 2° ORDINE CON POLI COMPLESSI CONIUGATI
ESEMPI
DIAFRAMMI DI NYSQUITS
ESEMPI
Risposta in frequenza
CONTENUTO ARMONICO
Il concetto di contenuto armonico di una funzione è connesso alla possibilità di rappresentarla come somma di
termini trigonometrici (seno, coseno).
.
Nel 1807 Jean Baptiste Fourier, fisico e matematico francese, pubblicò uno scritto Sulla Propagazione del Calore, in
cui espose la possibilità di rappresentare una funzione come somma di sinusoidi.
Armonica

f (t)  A 0 
A
n1
n
 cosn  0  t   n 
0 
2
T0
La serie di Fourier permette di scomporre una funzione, anche discontinua, purché periodica, in una somma
infinita di termini trigonometrici (continui).
Esempio:
Risposta in frequenza
Esempio:
Segnale periodico: è sempre scomponibile come somma di infinite sinusoidi (Teorema di Fourier)
Risposta in frequenza
Spettro delle ampiezze An
Spettro delle fasi ρn
Distribuzione delle ampiezze lungo l’asse delle pulsazioni
Distribuzione delle ampiezze lungo l’asse delle pulsazioni
A1
0
A2
A0
1
2
NB: spettri discreti
ω
ω
Segnale non periodico: una funzione di area limitata è scomponibile in somma di infinite sinusoidi con pulsazioni
infinitamente vicine
Esempio: impulso unitario
A∙ 1 = 1
A
Spettro delle ampiezze continuo
1
A’∙ 2 =1
A’
1
2
t
2
1
2
2 
1
ω
Risposta in frequenza
RISPOSTA IN REGIME SINUSOIDALE
In regime sinusoidale si utilizza la variabile complessa immaginaria pura s = jw dove con w si
indica la pulsazione del segnale d’ingresso
Modulo e fase della f.d.t in regime sinusoidale
 Il modulo dalla f.d.t.(rapporto fra l’ampiezza della sinusoide d’uscita e l’ampiezza della sinusoide
d’ingresso) se maggiore di uno rappresenta l’amplificazione del sistema, invece se minore di uno
l’attenuazione.
 La fase della f.d.t. rappresenta lo sfasamento della sinusoide d’uscita rispetto alla sinusoide
d’ingresso.
Risposta in regime sinusoidale
Se ad un sistema lineare stabile si applica un segnale sinusoidale, a regime il sistema risponde
ancora con un segnale sinusoidale con la medesima pulsazione w e con ampiezza e fase in
funzione di w
Risposta in frequenza
Esercizio1
Al circuito in figura (R=1K ; C=1microF) è applicato un segnale sinusoidale
vi(t) = 7*sen(1000*t) Determinare il segnale d’uscita calcolando l’ampiezza e lo sfasamento
circuito RC
circuito RC
trasformato
Segnale d’uscita
vi (t) = 7 sen(1000 t)
vo( t)= 4,95 sen( 1000t- 0 , 785)
Risposta in frequenza
RISPOSTA IN FREQUENZA
Per risposta in frequenza si intende: la risposta di un sistema al variare della frequenza f o
pulsazione w quando in ingresso è applicato un segnale sinusoidale.
Per l’analisi della risposta in frequenza di un sistema, vengono utilizzati dei grafici di facile
costruzione:
- i diagrammi cartesiani o di Bode
- i diagrammi polari o di Nyquist.
I diagrammi di Bode sono due e precisamente: un diagramma del modulo e un diagramma della
fase, mentre il diagramma di Nyquist è unico.
Con i diagrammi di Bode è possibile l’analisi in frequenza di un sistema in modo rapido, anche se
approssimato. Ad es. possiamo ricavare facilmente sia l’attenuazione e che lo sfasamento tra il
segnale d’ingresso e quello d’uscita a certe frequenze.
Diagramma del modulo
Il diagramma del modulo è la rappresentazione grafica dell’andamento del modulo della f.d.t.
(attenuazione o amplificazione) di un sistema al variare della pulsazione w
In tale diagramma sull’asse delle ordinate si riporta in scala lineare il modulo della f.d.t. in decibel
G(jω) ()dB = 20 log(G)
mentre sull’asse delle ascisse, in scala logaritmica si riporta la pulsazione w in rad/sec o la
frequenza in Hz
Risposta in frequenza
Vantaggi dell’uso della scala logaritmica

In luogo di moltiplicazioni e divisioni si opera con somme e sottrazioni


Si può approssimare il diagramma, on errori accettabili, con delle semirette di facile tracciamento
È possibile rappresentare ampi campi di variazione di pulsazioni o frequenze
Diagramma della fase
Il diagramma della fase è la rappresentazione grafica dell’andamento dello sfasamento
(argomento) della f.d.t. di un sistema al variare della pulsazione w.
Sull’asse delle ordinate si riporta in scala lineare gli sfasamenti in gradi della f.d.t. mentre sull’asse
delle ascisse, in scala logaritmica, si riporta la pulsazione w in rad/sec o la frequenza in Hz
TRACCIAMENTO DEI DIAGRAMMI DI BODE
I diagrammi di Bode sia per il modulo che per la fase, si possono ottenere sommando i diagrammi
approssimati delle funzioni elementari.
Dimostrazione
Consideriamo un generico sistema la cui f.d.t. in forma normale è:
Risposta in frequenza
Per il modulo
I quattro termini che compaiono della [2] rappresentano le funzioni elementari.
Dalla [2] si evince che il diagramma di Bode relativo al modulo lo si può ottenere tracciando
singolarmente i diagrammi di dette funzioni elementari per poi sommarli.
Per la fase
L’argomento di
G(jω), <(ω∠jG ) la somma degli argomenti dei singoli fattori della [1]
∠jG(jw) = ∠k + ∠ (1+jωτ)+∠ G(jω)^ ∠-( 1 +jωp)+
Anche per l’argomento il diagramma di Bode lo si può ottenere tracciando singolarmente i
diagrammi delle funzioni elementari per poi sommarli.
Risposta in frequenza
GRAFICI DEI DIAGRAMMI DI BODE DELLE FUNZIONI ELEMENTARI
Costante moltiplicativa G(j) = K
Diagramma del modulo
G(jω)db = 20 log K
fig. 1
fig. 2
Diagramma della fase
0
Gj = arctg   
 K
 0
180
per
K 0
per
K 0
Risposta in frequenza
Polo nell’origine G(s) = 1/s
G j 
1
j
Diagramma del modulo
Gjω
1
= 20 log  20log 

dB
Per disegnare il diagramma troviamo dei punti:
Gjω
= -20log 

dB
0,1
+20 dB

0 dB

-20 dB
Si tratta di una retta con pendenza –20 dB/dec
che interseca l’asse delle ascisse nel punto 
fig. 7
fig. 8
Da notare:
Se il polo nell’origine ha molteplicità g
 Il diagramma del modulo sarà ancora una retta, che interseca l’asse delle ascissenel punto    ma con pendenza – 20g
 Il diagramma della fase sarà ancora una retta parallela all’asse delle ascisse ma di valore –90°g
Risposta in frequenza
Zero nell’origine G(s) = s
G j  j
Diagramma del modulo
Gjω
= 20log 
dB
Per disegnare il diagramma troviamo dei punti:
Gjω
= -20log 

dB
0,1
-20 dB

0 dB

+20 dB
Si tratta di una retta con pendenza + 20 dB/decade
che interseca l’asse delle ascisse nel punto 
fig. 9
Diagramma della fase
Gj  j  Gj = arctg   = arctg  = +90°
 0
Da notare:
Se lo zero nell’origine ha molteplicità g
G j   jg
 Il diagramma del modulo sarà ancora una retta, che interseca l’asse delle ascissenel punto  ma con pendenza +20g
 Il diagramma della fase sarà ancora una retta parallela all’asse delle ascisse ma di valore +90°g
Risposta in frequenza
Diagramma del modulo
Zero reale e negativo G(s)=1+s
G(j)=1 + jz
l massimo errore che si commette nella appresentazione asintotica si ha per =z e vale3 dB, infatti:
Risposta in frequenza
Diagramma della fase
Per disegnare il grafico troviamo i punti più significativi:

0
Fase
fase
approssimat
a
Gj
arctg 0 = 0°
0°
0,1 z arctg 0,1 = 0,7°
0°
z
10z arctg 10 = 84,3°
arctg  = 90°

45°
arctg 1 = 45°
90°
90°
Risposta in frequenza
Polo reale e negativo G(s) = 1/1+s
1
Gj
1  j p
Il diagramma può essere tracciato per tratti in modo approssimato (diagramma asintotico), pertanto consideriamo i due casi: << p e  >> p
Risposta in frequenza
il massimo errore che si commette nella rappresentazione asintotica si ha per =p e vale -3 dB, infatti:
f
Diagramma della fase
per disegnare il grafico troviamo i punti più significativi
Risposta in frequenza
Esercizio – Tracciare i diagramma di Bode del circuito in figura (filtro passa alto)
R= 1K
C= 1 mF
Soluzione
 = RC = 1K 1 mF = 10 +3  10 -6 = 0,001 sec
Diagramma del modulo
la f.d.t. presenta uno zero nell’origine e un polo reale ( p=1000 rad/sec)
Contributo dello zero
Contributo del polo
Per costruire il diagramma del modulo basta sommare i diagrammi
elementari relativi ad uno zero nell’origine ed un polo reale ( p=1000 rad/sec)
Nota:
In pratica la somma viene effettuata sommando le pendenze: pendenze
uguali ed opposte si annullano reciprocamente, producendo un
andamento costante.
Risposta in frequenza
Per costruire il diagramma della fase basta sommare i diagrammi elementari relativi ad uno zero nell’origine ed un polo
reale
Elementi per la costruzione del diagramma del polo
Risposta in frequenza
Tracciare i diagramma di Bode di un sistema la cui f.d.t. è la seguente
Diagramma del Modulo
Poli
La f.d.t. presenta due poli non nell’origine, in corrispondenza di ciascun polo la pendenza varia –20dB/dec,

(1+s10 -3 ) = 0  = p1 = - 103
  p1  103 rad /sec

(1+s10 -4 ) = 0  = p2 = - 10 -4
 p2 104
Costante
K=
lim
s 0
10
=10
rad /sec
 KdB =20log10 = 20dB
(2  s 103)(1 s 104 )
Il diagramma asintotico del modulo si costruisce nel seguente modo: si traccia
una semiretta parallela all’asse  di ordinata 20 dB fino a p1 da p1 aw p2 il
diagramma scende con pendenza di – 20 db/dec da p2 il diagramma scende invece
con pendenza –40dB/dec
Risposta in frequenza
Diagramma della fase
Si
tracciano i diagrammi approssimativi dei singoli termini e poi si sommano
Costante
1° Polo
□ 0,1 p1= 10 2 rad/sec ( 0°)
■ 10p1 =104 ( -90°)
2° Polo
 0,1p2=103 rad/sec ( 0°)
 10p2 =105 ( -90°)
0°
Contributo 1° polo
Contributo 2° p olo
Risposta in frequenza
Diagrammi di Bode di una rete ritardatrice
Risposta in frequenza
Diagramma della fase
G(s)=
1 sT
1 s
 G( j) 
1  jT
1 j
Risposta in frequenza
Diagrammi di Bode di una rete anticipatrice
Risposta in frequenza
Risposta in frequenza
Diagrammi di Bode di una rete a sella
Risposta in frequenza
osserva
che
il
circuito
agisce
contemporaneamente
da
ritardatore
e
anticipatore, ma in due Bode di pulsazioni
diverse
Si
Risposta in frequenza
SISTEMI DEL 2° ORDINE
Sistema del 2° ordine senza zeri.
X(s)
k
2
s  2  s  2
n
t
Y(s)
n
t
Poli della funzione di trasferimento:
s1,2  n   n  2 1
NB: s1 e s2 sono soluzioni dell’equazione caratteristica;
possono essere reali o complesse in funzione di .
Risposta in frequenza
IF(j)IdB
Ipotesi:
 1
Le soluzioni sono
s1
s1,2  n  n  1
2
Ipotesi:
  1
Le soluzioni sono
reali coincidenti:
•s
•
reali distinte:
2
log10
IF(j)IdB
s1,2  n
•
s1 = s2
log10
Risposta in frequenza
Ipotesi:
 1
s1, 2   n  jn 1   2
Le soluzioni sono complesse coniugate:
 =0
IF(j)IdB
0 <  < 0.707
 =0
y(t)
 < 0.5
0.5 <  < 0.707
MR
0.707 <  < 1
0.707 <  < 1
= 1
= 1
•
n
log10
t
Risposta al gradino nel dominio del tempo
Risposta in frequenza
7Grafici dei diagrammi di Bode di un sistema del 2° ordine
con poli complessi coniugati (<1)
Diagramma del modulo
Il diagramma del modulo per  < n e  > n è uguale a quello di un sistema del secondo ordine
+40dB/decade)
con polo doppio ( pendenza retta
Risposta in frequenza
Nell’intorno di wn, esso subisce delle modificazioni che dipendono da
L’analisi matematica mette in evidenza l’esistenza di un massimo della curva per
Da notare:
Nel caso in cui  = 0,7 la risposta è quella di un filtro LPF a banda piatta con
pulsazione di taglio n e pendenza di –40dB/dec. (filtro alla Butterworth de 2° ordine)
Risposta in frequenza
Dimostrazione che per  < n e  > n
il diagramma del modulo è quello di un sistema del secondo ordine con polo doppio.
 2 
 2 
 


GjωdB =  20 log 1
  
 n 
n 

2
Per  << n
2
Risposta in frequenza
Esercizi - Diagrammi di Bode di sistemi del 2° ordine con poli complessi e coniugati
Risposta in frequenza
Risposta in frequenza
DIAGRAMMI DI NYQUIST
A differenza dei diagrammi di Bode le informazioni sul modulo e la fase della f.d.t. si ricavano da un
unico diagramma. Il diagramma di Nyquist è la rappresentazione nel piano di Gauss del modulo e
della fase della f.d.t al variare della pulsazione w.
Il diagramma polare1, si ottiene congiungendo i vertici dei vettori della f.d.t. del sistema G(jw) per w
variabile tra 0 e infinito.
Esempi di tracciamento dei diagrammi di Nyquist
Il diagramma di Nyquist può essere tracciato in due modi: per via numerica, quando si ha ha disposizione un
elaboratore o per via qualitativa grafica.
Esempio di tracciamento per via numerica del diagramma di Nyquist di un sistema di tipo 0 con un
solo polo
con Excel
UN grafico di tipo polare è un grafico le cui coordinate sono
un vettore e un angolo
1
Risposta in frequenza
Esempio di tracciamento del diagramma di Nyquist per via qualitativa grafica di un sistema di tipo 0
con un solo polo
G(s)  10
1  s0.01
Gj 
10
1  j0.01
Da notare:
Ogni punto P del diagramma di Nyquist è individuato dalle
coordinate polari (modulo; fase)
P1( = (10; 0°)
P2 ( ) = (0 ; 0°)
P3 ( ) = (7; -45°)
Risposta in frequenza
Esercizio 2 - Sistemi di tipo zero con due poli reali
G(s) 
G(j) 
G(j) 
7
(1  s0.1)(1  s0.01)
7
(1  j0.1)(1 j0.01)
7
  2
  2

1    1 
10 
100 
p1 = - 10 ; p2 = -100
Risposta in frequenza
Esercizio 3 - Sistemi di tipo zero con tre poli
G(s) 
G(j) 
7
(1 s0.2)(1 s0.1)1 0.01s
p1 = - 5 ; p2 = - 10 ; p3 = - 100
7
(1  j0.2)(1 j0.1)1 0.01j
Risposta in frequenza
Esercizio 4 - Sistemi di tipo uno con tre poli
G(s) 
20
s1  0,1 s(1 0,01s)
G(j) 
p1 = 0 ; p2 = -10 ; p3 = -100
1
j1 0,1 j(1 0,01j)
G  jω  =
20
 1  0,12  1  (0,01)2
;
Risposta in frequenza
Esercizio 5 - Sistemi di tipo due con tre poli
20
G(s) 
p1 = 0 ; p2 = 0 ; p3 = -10
s2 1  0,1 s
G(j) 
1
j j 1  0,1 j 
Gjω =
20
2  1  0,12
;
Stabilità dei sistemi di controllo
GENERALITA
CRITERIO GENERALE DI STABILITA
CRITERIO DI BODE
MARGINE DI FASE
CRITERIO GENERALE DI STABILITA
CRITERIO SEMPLIFICATO
RIDUZIONE DEL GUADAGNO AD ANELLO
SPECIFICHE DEI SISTEMI RETROAZIONATI
CRITERIO DI NYSQUITS
MARGINE DI AMPIEZZA E DI FASE
CRITERIO DI STABILITA DI NYSQUITS
RETI CORRETRICE
TECNICHE DI STABILIZZAZIONE
RETI RITARDATRICE, ANTICIPATRICE A SELLA
Stabilità dei sistemi di controllo
GENERALITÀ
La stabilità di un sistema non dipende dal segnale d’ingresso, ma dipende solo dalla f.d.t. del
sistema
f.d.t. =
U(s)
E(s)
 Un sistema lineare tempo invariante si dice stabile semplicemente se risponde ad un ingresso
limitato con una uscita limitata, invece se risponde con una uscita che tende a zero il sistema
dicesi stabile asintoticamente.
Esempio di risposta:
Stabilità dei sistemi di controllo
 Un sistema lineare tempo invariante si dice instabile se risponde ad un ingresso limitato con una
uscita non limitata (divergente)
Esempio di risposta:
CRITERIO GENERALE DI STABILITÀ
Il criterio generale di stabilità permette di determinare la stabilità di un sistema di controllo quando
si conoscono i poli della f.d.t. ad anello chiuso.
W(s) = f.d.t. ad anello chiuso
G(s) H(s) = f.d.t. ad anello aperto.
Stabilità dei sistemi di controllo
Un sistema lineare è stabile se e solo se la f.d.t. del sistema ha tutti i poli a parte reale non positiva
e gli eventuali poli a parte reale nulla siano semplici.
Un sistema lineare è asintoticamente stabile se è solo se ha tutti i poli a parte reale negativa.
Esercizio 1
Uno stabilimento utilizza, per la cottura di merendine, un sistema di controllo di temperatura a
catena chiusa. Sapendo che le funzioni di trasferimento del
regolatore, del circuito di
comando, del forno e del circuito di reazione (termocoppia e circuito di condizionamento)
sono rispettivamente:
Stabilità dei sistemi di controllo
Determinare la f.d.t. complessiva del sistema
Soluzione
Stabilità dei sistemi di controllo
Il criterio di stabilità di Bode
La funzione d'anello
Per verificare la stabilità di un sistema ad anello chiuso bisogna studiare il comportamento
della funzione d'anello
G(S) · H(S)
al variare della frequenza.
Infatti la funzione di anello, funzione della variabile complessa S, è una grandezza complessa e
quindi ha una parte reale ed una parte immaginaria. Come tutte le grandezze complesse è
pertanto caratterizzata da un modulo e da una fase.
Stabilità dei sistemi di controllo
Il segnale di ingresso “x” viene quindi amplificato (oppure attenuato) e sfasato, dalla
funzione di anello. Tale segnale, così modificato, viene riportato al nodo sommatore e da
questo cambiato di segno, con un ulteriore sfasamento di 180° (introdotto dal nodo
sommatore stesso). Pertanto, il segnale rischia di essere riportato in ingresso al blocco di
andata in fase con il segnale originario (sfasamento complessivo pari a 360°) e amplificato
con modulo del
guadagno maggiore o uguale a 1. In tal caso, eventuali oscillazioni
introdotte dal segnale originario “x”, anche in sua assenza, si autoalimenterebbero, dando
luogo ad instabilità del sistema
Il criterio di Bode
Per garantire la stabilità di un sistema a catena chiusa, bisogna studiare i diagrammi di
bode del modulo e della fase della funzione di anello. Il sistema è stabile solo se non
esistono frequenze a cui, ad uno sfasamento di 180° corrisponde un guadagno di anello
maggiore o uguale a 1.
Il diagramma della fase
Il diagramma
di BODE della
fase
viene
ricavato dal diagramma
di BODE dell’ampiezza
tenendo presente i seguenti criteri:
Ad una pendenza di n · 20 dB/decade corrisponde una fase di n · 90° , per i valori di frequenza lontani almeno
una decade dai punti critici (poli o zeri) più vicini.
Nei campi di frequenze in prossimità dei punti critici, i tratti di curva vengono raccordati linearmente.
Stabilità dei sistemi di controllo
Un esempio: la funzione d'anello
Consideriamo ad esempio il caso in cui G(S) e H(S) siano entrambe f.d.t. del primo ordine, del
tipo:
G(S) = Gst / [1 + τ1 · S]
H(S) = Hst / [1 + τ2 · S]
La funzione d'anello è data allora da:
G(S) · H(S) = Gst · Hst / [(1 + τ1 · S) (1 + τ2 · S)]
I diagrammi di Bode
Si tratta di una f.d.t. del secondo ordine, con due poli reali e distinti.
Supponiamo che i poli si abbiano in corrispondenza delle pulsazioni wp1 = 103 s-1, wp2 = 106 s-
1
e
che il guadagno statico complessivo sia pari a Gst · Hst = 1000.
Qui sotto sono riportati i diagrammi di Bode del modulo e della fase corrispondenti alle condizioni
ipotizzate.
Stabilità dei sistemi di controllo
Dall'analisi dei diagrammi si osserva che esistono delle frequenze in cui viene effettivamente
raggiunto uno sfasamento di 180° (per valori di w superiori a 107 s-1). Questo però avviene
quando il guadagno risulta comunque di valore ben
inferiore a 1 (al di sotto dell'asse
corrispondente a 0 dB). Non esistono quindi apparentemente rischi di instabilità.
Stabilità dei sistemi di controllo
Il margine di fase
In realtà, la modellizzazione del comportamento di un sistema tramite i diagrammi di Bode è una modalità di
rappresentazione abbastanza approssimata (come del resto sono tutti i modelli). Quelle tracciate sono infatti curve
ideali: quelle reali dovrebbero avere un andamento più "smussato". Inoltre non è sempre facile conoscere con molta
precisione i valori dei poli, degli zeri e del guadagno statico dei "sistemi reali".
Per tali motivi si preferisce utilizzare il Criterio di Bode con un certo margine di sicurezza. A tale scopo si prende in
considerazione il valore di frequenza in cui il guadagno risulta pari a 1 (0 dB) e si individua il valore di fase
corrispondente (nel nostro esempio questo si verifica in corrispondenza della pulsazione di valore pari a 106 s-1). Viene
detto allora margine di fase la differenza fra tale valore di fase ed il valore critico di 180°. Nel nostro caso il margine di
fase, evidenziato nel diagramma con un segmento orientato di colore rosso, risulta esattamente pari a 45°.
Proprio questo viene in genere indicato come valore minimo del margine di fase, necessario per garantire la sicura
stabilità del sistema. Risulta infatti evidente che, per frequenze più vicine a quelle che determinano lo sfasamento
critico di 180°, il guadagno scende rapidamente, al di sotto del valore unitario, scongiurando il rischio di instabilità.
Il Criterio di Stabilità di Bode Semplificato
Cosa succede al variare del guadagno statico
Dall'analisi dell'esempio precedente, risulta che un sistema con due poli, di cui il secondo in corrispondenza
dell'asse 0 dB, ha il margine di fase minimo (45°) sufficiente per dichiarare il sistema "sicuramente stabile".
Stabilità dei sistemi di controllo
Aumentando il valore del guadagno statico oltre i 60 dB il secondo polo si sposterebbe al di sopra
dell'asse 0 dB e la curva del guadagno taglierebbe l'asse con pendenza pari a -40 dB/decade. La
frequenza corrispondente al guadagno unitario aumenterebbe di valore. In tal caso il margine di
fase diventerebbe insufficiente e non si potrebbe dichiarare il sistema "sicuramente stabile". Al
contrario, diminuendo il valore del guadagno statico sotto i 60 dB, il secondo polo si sposterebbe
al di sotto dell'asse 0 dB e la curva del guadagno taglierebbe l'asse con pendenza pari a -20
dB/decade. La frequenza corrispondente al guadagno unitario diminuirebbe di valore. In questo
caso il margine di fase aumenterebbe garantendo con sicurezza ancora maggiore la stabilità del
sistema.
Il criterio di stabilità semplificato
Dalle considerazioni precedenti si deduce il seguente criterio di stabilità semplificato, che si
applica utilizzando esclusivamente il diagramma di Bode del modulo della funzione d'anello. Un
sistema è "sicuramente stabile" solo se la funzione d'anello non presenta pendenze di valore
uguale o superiore, in valore assoluto, a 40 dB/decade al disopra dell'asse 0 dB.
Conflitti
Un basso valore di guadagno statico della funzione d'anello è garanzia di stabilità del sistema.
Pero, come vedremo nelle lezioni successive, ci possono essere motivi validi per cercare di
elevare il guadagno statico quanto più sia possibile. Infatti, un guadagno statico elevato assicura
una migliore precisione ed una maggiore immunità ai disturbi del sistema. Un guadagno statico
elevato migliora inoltre il comportamento alle frequenze elevate, aumentando la velocità di
risposta del sistema.
Stabilità dei sistemi di controllo
C'è pertanto conflitto tra la stabilità e le altre prestazioni che caratterizzano la qualità di un
sistema di controllo ad anello chiuso. Caso per caso, sarà compito del progettista del sistema di
controllo trovare il compromesso migliore tra le opposte esigenze ed adottare particolari
strategie che
permettono talvolta di conciliarle, senza sacrificare troppo le prestazioni
desiderate
CRITERIO GENERALE DI STABILITÀ DI BODE
Consideriamo un sistema ad anello chiuso
Il criterio di stabilità di Bode permette di determinare la stabilità quando è nota la funzione f.d.t.
ad anello aperto cioè la L(s) = G(s)*H(s).
Un sistema a catena chiusa è stabile: se lo sfasamento della f.d.t. ad anello aperto calcolato in
corrispondenza della pulsazione critica è inferiore in valore assoluto a 180°
Esempio: consideriamo un sistema ad anello chiuso i cui diagrammi di Bode della f.d.t. ad anello
aperto siano i seguenti
Stabilità dei sistemi di controllo
Stabilità dei sistemi di controllo
CRITERIO SEMPLIFICATO DI STABILITÀ DI BODE
Un sistema ad anello chiuso è stabile se il diagramma del modulo del guadagno ad anello aperto
interseca l’asse delle ascisse con una pendenza di – 40dB/dec. Se la pendenza è maggiore o uguale
a –60dB/dec il sistema è sicuramente instabile; con una pendenza di –40dB/dec il sistema potrebbe
essere instabile e si deve ricorrere al criterio generale di stabilità
ESERCIZI - CRITERIO SEMPLIFICATO DI STABILITÀ DI BODE
L’attraversamento dell’asse delle ascisse avviene con una pendenza di – 20dB/dec, pertanto il sistema è stabile
Stabilità dei sistemi di controllo
L’attraversamento dell’asse delle ascisse avviene con una pendenza di – 60dB/dec, pertanto il sistema
è instabile
Stabilità dei sistemi di controllo
Esercizio 3
Verificare la stabilità del sistema ad anello chiuso
L’attraversamento dell’asse delle ascisse avviene con una pendenza di – 40dB/dec, il criterio
semplificato di Bode non ci permette di valutare la stabilità.
Stabilità dei sistemi di controllo
STABILIZZAZIONE PER RIDUZIONE DEL GUADAGNO DI ANELLO
Esercizio 1
Analizzare la stabilità del sistema dell’esercizio N.3, ma con guadagno K minore di 35dB
La curva del modulo ha lo stesso andamento della figura dell’esercizio N.3, ma parte non più da
50dB, ma da 20dB. L’attraversamento dell’asse delle ascisse avviene ora prima del secondo polo
con una pendenza di – 20dB/dec, per il criterio semplificato di Bode il sistema è stabile.
Stabilità dei sistemi di controllo
Esercizio 2
Stabilizzare il sistema dell’esercizio N.2 riducendo il guadagno d’anello
E’ sufficiente fare in modo che quando
arriva il secondo polo la curva attraversi
l’asse delle ascisse. Quindi bisogna
imporre che alla pulsazione di
100
rad/sec il guadagno
L’attraversamento dell’asse delle ascisse ora avviene con una
pendenza di – 20dB/dec, per il criterio semplificato di Bode il
sistema è stabile.
Nota:
Da questi esempi si evince:
 che la stabilità oltre al guadagno d’ anello dipende dal
numero dei poli della L(s), in quanto ogni polo
 incrementa ulteriore la pendenza di 20dB/dec
 che con la riduzione del guadagno di anello K, si migliora
la stabilità del sistema.
Questo metodo di stabilizzazione in genere non è seguito, perché il sistema di controllo diviene più
lento, meno preciso e più sensibile ai disturbi.
.
Stabilità dei sistemi di controllo
ESERCIZI: CRITERIO GENERALE DI STABILITÀ DI BODE
Osservazioni
Rispetto al criterio di Nyquist, il criterio di Bode ha il vantaggio di servirsi dei diagrammi di Bode
più agevoli da tracciare.
La pulsazione critica può essere ricavata con buona approssimazione dal diagramma di Bode
asintotico del modulo, a condizione che non vi siano cambiamenti di pendenza nelle vicinanze
della pulsazione critica
La fase critica invece conviene calcolarla analiticamente.
Esercizio 1
Discutere la stabilità con il criterio di Bode.
Stabilità dei sistemi di controllo
- La fase critica può essere calcolata analiticamente Φc
=)L(jcω∠= -2⋅arctg 3 = 144°
Nota:. Φc ricavato dal diagramma asintotico ha un valore
minore.
Poiché lo sfasamento in corrispondenza della pulsazione
critica è 144° < 180° il sistema ad anello chiuso per il
criterio di Bode è stabile
Esercizio 2
Discutere la stabilità con il criterio di Bode.
Stabilità dei sistemi di controllo
Stabilità dei sistemi di controllo
Esercizio 3
Uno stabilimento utilizza, per la cottura di merendine, un sistema di controllo di temperatura a
catena chiusa. Sapendo che le funzioni di trasferimento del regolatore, del sistema di comando, del
forno e del blocco di reazione (termocoppia e circuito di condizionamento) sono rispettivamente:
Soluzione
Analizzare la stabilità del sistema
Stabilità dei sistemi di controllo
La f.d.t. ad anello aperto è stabile in quanto i poli della f.d.t. sono reali e negativi ( p1= -1/500;
p2= -1/50), pertanto per determinare la stabilità del sistema ad anello chiuso si può applicare
il criterio di Bode.
Stabilità dei sistemi di controllo
SPECIFICHE DEI SISTEMI REAZIONATI NEL DOMINIO DELLA FREQUENZA
Nota:
Per determinare la stabilità si poteva in alternativa applicare il criterio semplificato di Bode.
Dal grafico si nota che l’attraversamento dell’asse delle ascisse avviene con una pendenza di –
20dB/dec, pertanto per il criterio semplificato di Bode il sistema è stabile
Per la progettazione dei sistemi ad anello chiuso si tengono conto nel dominio della frequenza delle
seguenti specifiche
 Larghezza di banda
La larghezza di banda è l’intervallo delle frequenze tale che il modulo della f.d.t. ad anello chiuso
W(s), non è mai minore di 3dB del valore che esso assume quando omega =0
Per il calcolo della larghezza di banda per sistemi ad anello chiuso si utilizza la f.d.t. ad anello
aperto.
L(s) = G(s)*H(s)
La larghezza di banda (B) di un sistema ad anello chiuso è approssimativamente uguale alla
pulsazione critica B = wca
Picco di risonanza e Pulsazione di risonanza
Per i sistemi ad anello chiuso del 2°ordine con poli complessi e coniugati ζ <= 0.7
Stabilità dei sistemi di controllo
Pulsazione critica wC = pulsazione alla quale il modulo della funzione di trasferimento ad anello aperto vale 0dB
Stabilità dei sistemi di controllo
IL CRITERIO DI NYQUIST
• Il criterio di Nyquist consente di stabilire se un sistema, del quale si conosce la risposta armonica ad
anello aperto, sia stabile o meno una volta chiuso in retroazione:
• Per la sua natura sostanzialmente grafica, esso risulta di notevole ausilio per il progettista perchè,
oltre a fornire indicazione sulla stabilità del sistema in retroazione costituisce anche un’utile guida
per giudicare dell’efficacia di possibili interventi che migliorino il comportamento dinamico del
sistema in retroazione.
• Criterio di Nyquist: sistemi stabili ad anello aperto. Nell’ipotesi che la funzione guadagno di
anello F(s) abbia tutti i poli a parte reale negativa, eccezion fatta per un eventuale polo nullo
semplice o doppio, condizione necessaria e sufficiente perche il sistema in retroazione sia
asintoticamente stabile `e che il diagramma polare completo della funzione F (jω) non circondi n´e
tocchi il punto critico −1+j0.
Stabilità dei sistemi di controllo
• Il criterio di Nyquist fa riferimento ai diagrammi polari “completi, cio`e tracciati per ω variabile da −∞
a +∞. Essendo
F (−jω) = F ∗(jω)
il diagramma per pulsazioni negative si ottiene per ribaltamento intorno all’asse delle ascisse di
quello tracciato per pulsazioni positive.
Nel caso di un sistema di tipo 0, il diagramma polare competo `euna curva chiusa;
• Nei casi di sistemi di tipo 1 o di tipo 2 (che presentano rami all’infinito) si conviene di completare i
diagrammi, rispettivamente, con una semicir- conferenza e con una circonferenza all’infinito percorsa
in senso orario che parte da ω = 0− ed arriva ad ω = 0+
Stabilità dei sistemi di controllo
• Il precedente enunciato del criterio di Nyquist `equello che copre la maggior parte dei casi di interesse. Si puo
dare tuttavia il seguente enunciato piu` generale, che si applica anche al caso in cui il sistema in esame sia
instabile ad anello aperto.
• Criterio di Nyquist: sistemi instabili ad anello aperto, con un eventuale polo nell’origine semplice o
doppio. Nell’ipotesi che la funzione guadagno di anello F (s) non presenti poli immaginari,
eccezion fatta per un eventuale polo nullo semplice o doppio, condizione necessaria e sufficiente
perch´e il sistema in retroazione sia asintoticamente stabile `e che il diagramma polare completo della
funzione F (jω) circondi il punto critico −1+j0 tante volte in senso antiorario quanti sono i poli di
F(s) con parte reale positiva.
Ogni giro in meno in senso antiorario o ogni giro in piu in senso orario corrisponde alla presenza,
nel sistema in retroazione, di un polo con parte reale positiva.
• Esempio Si consideri un sistema in retroazione:
Stabilità dei sistemi di controllo
Se il punto critico viene circondato (due volte in senso antiorario), il che avviene per valori elevati
della costante K, il sistema in retroazione e` stabile, dato che il guadagno di anello presenta due poli
con parte reale positiva. Se invece il punto critico non viene circondato, il che avviene per valori
relativamente bassi della costante K, il sistema in retroazione e` instabile.
Stabilità dei sistemi di controllo
MARGINI
DI AMPIEZZA E
DI
FASE
Quando il diagramma di Nyquist di un sistema in retroazione ha un andamento regolare, con ampiezza funzione
monotona decrescente della pulsazione si può dedurre da esso informazione non solo sulla stabilità del sistema, ma
anche sulla sua maggiore o minore criticità o tendenza all’instabilità.
• `E infatti evidente che, quanto pi`u il diagramma di Nyquist di un sistema tabile ad anello aperto si svolge lontano
dal punto critico, tanto piu lontano dall’instabilità `e il sistema: la vicinanza del diagramma di Nyquistal punto critico
`e normalmente associata ad un comportamento dinamico
non soddisfacente.
• Per quantificare la “distanza di G(jw) dal punto critico −1, si utilizzano due parametri, detti margini di stabilità,
che misurano la cosiddetta“stabilita relativa” dei sistemi in retroazione:
Stabilità dei sistemi di controllo
- Margine di ampiezza MA: `e l’inverso del modulo del guadagno di anello alla pulsazione corrispondente
alla fase − 3.14
– Margine di fase MF : `e l’angolo che occorre sottrarre alla fase (normalmente negativa) del guadagno di
anello alla pulsazione corrispondente al valore unitario del modulo (detta pulsazione di intersezioneo di
incrocio) per ottenere il valore − 3.14.
Margini di ampiezza e fase nei diagrammi di Bode
Stabilità dei sistemi di controllo
CRITERIO DI STABILITÀ DI NYQUIST
Il criterio di stabilità di Nyquist permette di determinare la
stabilità del sistema ad anello chiuso.
Esso si basa sul tracciamento del diagramma di Nyquist della
funzione f.d.t. ad anello aperto cioè L(s) = G(s)⋅H(s). per
ωvariabile da – ∞ a + ∞ 1
Enunciato del criterio di stabilità di Nyquist
Il criterio afferma che un sistema ad anello chiuso è stabile se e solo se il numero di giri (N) in
senso antiorario compiuti dal diagramma di Nyquist della f.d.t. ad anello aperto intorno al punto –
1 è uguale al numero dei poli (P) a parte reale positiva (cioè non presenta poli nel semipiano
destro)
Riassumendo
P = N ⇒ sistema stabile
P ≠ N ⇒ sistema instabile
Nota
Se P=0, cioè la f.d.t. ad anello aperto non presenta poli a parte reale positiva. Il sistema ad anello
chiuso è stabile, se il diagramma di Nyquist non compie nessun giro intorno al punto –1 (N=0)
Stabilità dei sistemi di controllo
ESERCIZI - CRITERIO DI STABILITÀ DI NYQUIST
Stabilità dei sistemi di controllo
modulo parte da 10 e decresce, la fase parte da 0 e decresce fino a 180°
Il diagramma di Nyquist non compie nessun giro intorno al punto –1, pertanto il sistema ad anello
chiuso è stabile.
Stabilità dei sistemi di controllo
Stabilità dei sistemi di controllo
Stabilità dei sistemi di controllo
MARGINE DI FASE E MARGINE DI GUADAGNO
Il margine di fase e il margine di guadagno permettono di valutare il grado di stabilità di un sistema
ad anello chiuso.
Margine di fase
dove:
fc (sfasamento critico) è lo sfasamento della f.d.t. ad anello aperto in corrispondenza della pulsazione
alla quale il modulo della funzione di trasferimento ad anello aperto vale 1.
Stabilità dei sistemi di controllo
dove:
OQ è il modulo della fdt ad anello aperto in corrispondenza di uno sfasamento della f.d.t. ad anello
aperto di 180°
Stabilità dei sistemi di controllo
RETI CORRETTRICI
Si sono visti in precedenza alcuni criteri, tramite i quali si può valutare la stabilità di un sistema a
spira chiusa; qui in particolare ci riferiamo al criterio di Bode che considera la funzione di
trasferimento ad anello aperto .
Si studia il diagramma del modulo di questa funzione e si cerca di individuare la pulsazione
di taglio( pulsazione di attraversamento dell'asse a 0dB ).
Questo metodo, afferma che il sistema è stabile se la fase della funzione Gloop calcolato
corrispondenza della pulsazione di taglio è inferiore a 180°; è instabile se superiore a 180°.
in
Si è inoltre fatto notare, che se l'attraversamento avviene con una pendenza maggiore ai
20dB/dec il sistema è fortemente indiziato di instabilità. E' stato, inoltre introdotto un parametro:
il margine di fase
nel quale appare φt=fase della Gloop alla pulsasione di taglio.
Per avere un buon grado di stabilità, il sistema deve presentare margine di fase positivo non
inferiore a 40°, quindi γ≥40°.
Stabilità dei sistemi di controllo
Con questi pochi elementi da ricordare, cerchiamo di considerare alcuni sistemi instabili
vedere se c'è un modo di ripristinarne la stabilità.
per
TECNICHE DI STABILIZZAZIONE
Il modo più semplice e immediato di rendere stabile un sistema è quello di ridurre
opportunamente il guadagno statico di anello.
L'effetto che in tal modo si ottiene risulta immediato se si osserva il diagramma polare del
sistema in esame.
Infatti se si ha ad esempio un sistema la cui funzione di trasferimento ad anello aperto vale:
Stabilità dei sistemi di controllo
dove le tre costanti di tempo T1, T2 e T3 sono positive; ipotizzando di far variare
statico ( il guadagno in continua ) da K a K',
il
guadagno
il diagramma polare subirà la modificazione illustrata a fianco.
Si nota che per K il sistema appare instabile, in quanto il diagramma abbraccia il punto
-1+j0.
Se però riduce il guadagno statico K al valore di K' il diagramma polare si rimpicciolisce e può
risultare come quello disegnato, in cui il punto -1+j0 si trova all'esterno del diagramma polare
(sistema formalmente stabile).
Stabilità dei sistemi di controllo
La stessa variazione rappresentata sul piano cartesiano viene qui illustrata.
si ottiene un diagramma simile al precedente ma traslato verso il basso Il nuovo diagramma
risulta aver un valore minore ω't<ωt della pulsazione di taglio e quindi anche del
corrispondente sfasamento φt.
Questa opzione è poco consigliabile, perchè si peggiorano le caratteristiche statiche del sistema e
si riduce anche la rapidità di risposta;si ottiene cioè un sistema più lento e meno preciso.
Si preferisce seguire altre strade, che consistono nell'alterare la configurazione poli-zeri del
sistema.
Stabilità dei sistemi di controllo
Sul diagramma di Bode, si effettua lo spostamento delle costanti di tempo T al
denominatore della funzione di trasferimento del sistema. Considerando la funzione di
prima:
L'alterazione avviene introducendo nella funzione di trasferimento una coppia polo- zero,cioè
inserendo in cascata sulla linea di andata un elemento che abbia funzione di trasferimento:
ottenendo una funzione corretta
di fatto, si ha lo spostamento della costante di tempo T1.
Stabilità dei sistemi di controllo
Si ha un diagramma delle attenuazioni che ha ancora, una pulsazione di taglio ω't e uno sfasamento
φ't poco maggiore del precedente ,con un guadagno statico del sistema ancora pari a K.
Stabilità dei sistemi di controllo
Cioè la stabilizzazione avviene solo a spese delle prestazioni dinamiche del sistema,senza alterare
quelle statiche. Si è cioè ottenuto, una funzione di trasferimento
del tutto simile alla
precedente,ma con costante di tempo T al posto di T1.
Un altro modo per migliorare la stabilità del sistema è quello di spostare una o più delle costanti
di tempo minori, ( pulsazioni angolari più elevate e distanti dall'origine ) in modo da renderle più
piccole riducendo così il loro contributo allo sfasamento in corrispondenza di ωt .
Questa operazione può essere eseguita ponendo ancora in cascata sulla linea di andata
elemento con funzione di trasferimento del tipo visto con T < T3 .
un
Si ottiene un sistema del tutto simile al precedente,ma con la costante di tempo più piccola
diminuita ( e costante d'angolo corrispondente aumentata). Si può naturalmente ottenere sia
l'aumento della costante di tempo maggiore,sia la diminuzione delle costanti di tempo più
piccole.
Se queste ultime sono ridotte in modo tale che le corrispondenti pulsazioni d'angolo siano
almeno 3÷4 volte maggiori della pulsazione di taglio ωt si ottiene un diagramma di Bode che
scende con una pendenza di -20dB/decade fino a valori di ω molto maggiori di ωt e il sistema
risulta sicuramente stabile con un conveniente grado di stabilità (margine di fase di 50° 60°).
Stabilità dei sistemi di controllo
Per ottenere questo risultato in un sistema a reazione, bisogna inserire nella linea di andata e
più precisamente fra i vari stadi amplificatori del segnale differenza,delle reti elettriche che
abbiano funzione di trasferimento con le caratteristiche indicate .
R ETE R I T A R DA T R I C E
Una rete ritardatrice è un circuito RC secondo lo schema riportato qui a fianco.
La sua funzione di trasferimento si può ottenere con la regola del partitore
in pratica
risulta
e il diagramma di Bode delle attenuazioni appare come in figura seguente (ad es.)
Stabilità dei sistemi di controllo
Stabilità dei sistemi di controllo
Come si può notare il diagramma coincide con l'asse a zero dB per ω<ωt= 1/T, essendo la
costante numerica K=1,
poi scende con pendenza -20dB/dec fino a valori di ω=ω2=1/τ oltre
il quale diventa una retta parallela all'asse delle ascisse.
Lo sfasamento φ risulta negativo entro un certo intervallo di frequenza al di fuori del quale è
nullo,da cui il nome rete ritardatrice o lag in quanto dà luogo a uno sfasamento sempre in ritardo.
Per quanto detto basta far coincidere la costante τ con una costante di tempo del sistema,per
provocare una compensazione polo-zero descritta in precedenza.
RETE ANTICIPATRICE
Una rete anticipatrice è un circuito RC secondo lo schema riportato qui a fianco.
Anche la sua funzione di trasferimento si può ottenere con la regola del partitore
Stabilità dei sistemi di controllo
con una funzione di trasferimento:
Con risulta
il diagramma di Bode delle attenuazioni e degli sfasamenti sono (ad es.):
Stabilità dei sistemi di controllo
Stabilità dei sistemi di controllo
Come si può notare il diagramma delle attenuazioni coincide con l'asse zero dB per ω>ω2 mentre
per ω<ω1 il diagramma è una retta parallela all'asse delle ascisse di ordinata a < 1
perciò la
rete anticipatrice determina una riduzione del guadagno statico del sistema.
Per ovviare all'inconveniente si può porre in cascata alla rete suddetta un amplificatore di guadagno:
ottenendo un diagramma del modulo così modificato
Stabilità dei sistemi di controllo
In tal caso il complesso amplificatore-rete anticipatrice risulta avere funzione di trasferimento:
Lo sfasamento introdotto dalla rete,come si può notare dai diagrammi è sempre in anticipo da
cui il nome rete anticipatrice o lead.
Facendo coincidere la costante τ con una delle costanti di tempo minori del sistema si ottiene la
riduzione di questa costante di tempo che verrà sostituita da T < τ.
RETE A SELLA
Spesso accade che per rendere sufficientemente stabile un sistema occorre eseguire ambedue le
operazioni precedentemente descritte,cioè aumento della costante di
tempo maggiore della
funzione di trasferimento A(s)B(s) del sistema e diminuzione di una delle costanti di tempo
minori. In tal caso è opportuno disporre in cascata ad un amplificatore della linea di andata una
rete a sella avente funzione di trasferimento:
con:
e
Stabilità dei sistemi di controllo
Una rete che realizza questo tipo di funzione di trasferimento è quella disegnata qui a fianco.
E' una combinazione della rete ritardatrice con quella anticipatrice. La sua funzione di trasferimento
vale:
da cui risulta:
e se è
è anche:
Stabilità dei sistemi di controllo
Il diagramma di Bode relativo alla funzione di trasferimento della rete a sella è il seguente:
Se ora si fa coincidere τ1 con la costante di tempo di A(s)B(s) che si vuole aumentare τ2 con quella che
si vuole ridurre,la funzione di trasferimento complessiva presenterà al posto delle due costanti di
tempo in questione la T' e la T'' rispettivamente. Così si avrà una funzione di trasferimento corretta:
Stabilità dei sistemi di controllo
se si pone:
si ha:
Occorre considerare che:
1.Nella determinazione delle reti stabilizzatrici i rapporti fra le costanti di tempo T' τ1 τ2 e T" in tutti i
tipi di reti viste, non devono essere scelti di valore molto elevato per
realizzabilità.
questioni di pratica
E' difficile realizzare reti stabilizzatrici con circuiti RC in cui i rapporti suddetti superino il valore di
10÷15. Nel caso che fossero richiesti per una buona stabilizzazione rapporti maggiori è consigliabile
usare due reti in cascata separate da una amplificatore disaccoppiando i circuiti RC.
E' in pratica impossibile che ci possa essere una compensazione perfetta fra le costanti di tempo
numeratore della rete stabilizzatrice e quella a denominatore della funzione di trasferimento del
sistema dato,che si intende aumentare o ridurre.
In pratica risulterà sempre una differenza fra esse e questo fatto darà luogo ad un diagramma di
Bode leggermente deformato.
3. Le reti in cascata possono essere inserite solo a monte di amplificatori ad elevate
d'ingresso, perchè non venga alterata la loro funzione di trasferimento.
impedenza
Controllori
CONTROLLO ON/OFF
PID
PID PROPORZIONALE
PID INTEGRATIVO
PID DERIVATIVO
PID TOTALE
PWM
RISPOSTA IN FREQUENZA
REGOLATORE PI
TEORIA DEL CONTROLLO
Controllori
Generalita
I controllori, in base alle informazioni ricevute dall'organo di riferimento (o dal
regolatore
dell'anello immediatamente più esterno) e dall'organo di misura «segnale retroazionato»,
forniscono dei segnali utili a correggere qualsiasi allontanamento, causato da variazioni funzionali
del sistema o da variazioni delle variabile di processo dal loro valore di riferimento.
Il loro scopo è infatti fare in modo cioè che la variabile di processo segua più strettamente
possibile il
valore di
riferimento indipendentemente dalla presenza
o meno di disturbi.
garantendo in questo modo la stabilità
I controllori standard largamente utilizzati in campo industriale sono caratterizzati da una rete di
retroazione che ha una struttura fissa (di tipo P, I, PI, PD, PID) e da parametri che, dimensionati
per una certa condizione di lavoro, restano fissi durante il funzionamento
La regolazione è dunque relativa ad una determinata condizione di funzionamento; pertanto se ci si
allontana sensibilmente da tale condizione si possono verificare smorzamenti non più soddisfacenti
e anche instabilità.
In questi casi può essere opportuno ricorrere a controllori adattativi, in cui o i parametri o la
struttura della rete di retroazione sono variabili in relazione alle condizioni di funzionamento del
sistema controllato, in modo che il circuito di regolazione risulti sempre stabilizzato in maniera
ottimale
Controllori
E’ chiamato anche controllo a
tutto o niente.
CONTROLLO ON / OFF
CARATTERISTICA del controllore ON/OFF
Si tratta di un controllore:
• con uscita a due posizioni
• con isteresi.
I controllori ON/OFF presentano i seguenti parametri
regolabili:
• Set Point
• Ampiezza del ciclo di isteresi
Set Point
Imposta il valore desiderato della variabile controllata.
Ampiezza del ciclo (differenziale)
Non è possibile fissare la variabile controllata al valore stabilito
mediante il SP. Bisogna stabilire quindi una fascia, intorno al SP, di valori
tollerabili.
Ciò che si imposta è il valore del differenziale .
Controllori
Azioni di controllo: ON/OFF
OSSERVAZIONI
• PRECISIONE
Alla variabile controllata è consentita una
escursione entro la banda impostata attraverso
il differenziale. Ciò fa si che la precisione risulti
tanto maggiore quanto minore è il differenziale.
• E’ dunque possibile aumentare la precisione
riducendo il differenziale.
Tuttavia la riduzione del differenziale comporta un più frequente
intervento degli organi di commutazione e degli attuatori con
conseguente maggiore usura e riduzione della vita media.
Controllori
Azioni di controllo: ON/OFF
• COSTANTI DI TEMPO
Sistemi con costanti di tempo piccole comportano
un più
frequente intervento degli organi di
commutazione e degli attuatori.
La conseguenza è una maggiore
usura e una
riduzione della vita media dei componenti il sistema
di controllo, se di tipo meccanico.
Controllori
Azioni di controllo: ON/OFF
• INERZIA
Nei sistemi in cui è presente una
notevole inerzia si può verificare una
fuoriuscita della variabile controllata
dalla fascia consentita.
La conseguenza è una precisione
minore di quella impostata con il
differenziale.
CONCLUSIONI
• Si tratta di un controllo semplice ed economico
• Ma poco preciso
Controllori
Azioni di controllo: PID
GENERALITA’
Generalmente la ricerca di buone prestazioni a regime comporta la realizzazione di sistemi che presentano un cattivo
comportamento in transitorio. Succede infatti che l’alto valore del guadagno d’anello necessario per le buone
prestazioni a regime sia spesso anche la causa di notevoli e prolungati pendolamenti della variabile controllata
durante il transitorio.
I regolatori sono composti fondamentalmente da tre parti:
• un generatore del segnale di riferimento
• un nodo di confronto
.• una rete di elaborazione ed amplificazione
8
Controllori
Azioni di controllo: PID
AZIONI DI CONTROLLO
Le azioni di controllo nei controllori PID sono tre:
• AZIONE PROPORZIONALE
L’azione di controllo risulta proporzionale
al segnale errore:
y(t)  K P e(t)
• AZIONE INTEGRALE
L’azione di controllo risulta proporzionale all’integrale del segnale errore:
y(t)  K I e(t) dt
• AZIONE DERIVATIVA
L’azione di controllo risulta proporzionale alla derivata del segnale errore:
y(t)  K D
de(t)
dt
Controllori
Azioni di controllo: PID - Proporzionale
e
AZIONE PROPORZIONALE
Circuiti di
elaborazione ed
amplificazione
Il circuito di elaborazione ed amplificazione produce una uscita proporzionale all’ingresso:
I parametri caratteristici sono:
• Campo proporzionale
• Banda di azione
• Banda proporzionale
y
y(t)  K P e(t)
Controllori
Azioni di controllo: PID - Proporzionale
La Banda proporzionale è definita dal rapporto:
B% 
e
100
y
Essa rappresenta il valore % dell’ingresso che produce un incremento unitario sull’uscita.
Esempio: Un controllore con B = 25% sviluppa un incremento unitario dell’uscita in
corrispondenza di un incremento di 0.25 dell’ingresso.
OSSERVAZIONI
• Un controllore con B piccola risulta avere
• maggiore sensibilità
• maggiore rapidità di risposta
• rischio pendolamento uscita
• Nel caso di riferimento costante e sistema Tipo 0 il controllo proporzionale risulta soddisfacente se il
sistema controllato è caratterizzato da:
• variazioni di carico piccole
• variazioni di carico poco frequenti.
Controllori
Azioni di controllo: PID - Proporzionale
Esempio:
Nei sistemi Tipo 0 occorre intervenire con un riassetto manuale del riferimento per annullare l’errore a regime. Ma in
presenza di una successiva variazione permanente del carico permane un errore (offset) sulla grandezza controllata.
NB: L’inconveniente dell’offset è tanto più sopportabile quanto minore e poco frequente è la variazione di carico permanente.
Controllori
Configurazione standard deL Controllore P (proporzionale).
f.d.t(s) =Vout/Vrif-Vmis = - R1/Rr = k
- Retroazione negativa
- Sommatore con Rm e Rr uguali
Questo controllore fornisce una risposta rapida e
permette un controllo fine della variabile di processo
poiché la sua uscita varia proporzionalmente allo
scarto di ingresso. Esso però non è in grado di
mantenere nullo il segnale di errore (può solo ridurlo
aumentando il guadagno), in quanto quando lo scarto
di ingresso si annulla la sua uscita si azzera e ciò
causa l'allontanamento della variabile di processo dal
riferimento desiderato
Quindi il sistema non si stabilizza mai, ma fluttua attorno al riferimento. Un aumento del guadagno
proporzionale comporta una diminuzione del
tempo di salita, ma anche più elevate sovra
elongazioni.
Controllori
Azioni di controllo: PID - Integrale
e
AZIONE INTEGRALE
Il circuito di elaborazione ed amplificazione produce una
uscita proporzionale all’integrale dell’ingresso:
Circuiti di
elaborazione ed
amplificazione
y
y(t)  K I e(t) dt
INTEGRALE
E’ un operatore matematico con cui si calcolano delle aree.
L’uscita y(t)
risulta dalla somma algebrica dell’area
delimitata dalla variabile e(t) con l’asse dei tempi.
L’uscita di controllo y(t) è costante solo quando il segnale
errore e(t) è nullo.
L’azione integrale consente quindi un flusso di potenza
verso il sistema controllato anche in presenza di errore
nullo.
La costante KI rappresenta la costante di integrazione. Attraverso essa è possibile rafforzare o indebolire l’azione di
controllo integrale quale risulta dal solo integrale dell’errore.
Controllori
Azioni di controllo: PID - Integrale
Il circuito di elaborazione ed amplificazione nel dominio di Laplace è descrivibile con la seguente funzione di
trasferimento:
OSSERVAZIONI
• L’operatore integrale introduce nel sistema un polo nullo, alzando di uno il tipo del sistema. Ciò comporta
le seguenti conseguenze:
•Miglioramento della sensibilità del sistema (il contributo degli errori piccoli è sommato nel tempo e l’uscita
y(t) finisce col raggiungere valori che possono influire sull’azione di controllo).
•Miglioramento delle prestazioni a regime (Esempio: nei sistemi Tipo 0 si annulla l’errore a regime rispetto ad
un ingresso a gradino).
• Aumento del rischio di pendolamento della variabile controllata.
• Poiché l’azione di controllo dipende dal valore dell’integrale (area), negli istanti iniziali essa è di debole
intensità in quanto occorre del tempo per la formazione di tale area.
Ciò comporta un aumento dei tempi di risposta del sistema.
Controllori
Azioni di controllo: PID - Integrale
ESEMPIO:
NB: Il degrado delle prestazioni dinamiche è tale da sconsigliare l’uso dell’azione integrale da sola. Occorre sempre
abbinarla all’azione proporzionale.
Controllori
Configurazione standard deL Controllore I (integrativo): ILl circuito di retroazione é costituito da un
condensatore C1 ; pertanto dalla configurazione generale che segue si deduce la seguente f.d.t.:
f.d.t(s) = - 1/(sRrC1) = 1/s*τi
Questo controllore ha il compito di ridurre l'errore statico a regime e di mantenerlo nullo in
presenza di disturbi costanti sulla variabile d'uscita, in quanto, essendo la rapidità di variazione
del segnale di uscita proporzionale al segnale di ingresso, quando l'ingresso si annulla l'uscita
mantiene il valore che aveva all'istante di annullamento del segnale di ingresso (tiene conto cioè
della ''storia passata'' del sistema).
dSu/dt = K Si
----Si = 0
----
Su non varia
Controllori
Dal punto di vista dinamico l'azione integrale porta ad un peggioramento dei margini di stabilità
in quanto per w  0 il modulo della f.d.t tende all’infinito rendendo il regolatore fortemente
instabile (lavora in saturazione)
E raramente usato da solo a causa della sua scadente velocità di risposta, è molto usato in
unione con un controllore P.
Controllori
AZIONE PROPORZIONALE – INTEGRALE ( CONTROLLORE PI )
Il controllore PI sviluppa contemporaneamente sia l’azione proporzionale che quella integrale:
E’ possibile scrivere la funzione di trasferimento anche nei seguenti termini:
Controllori
Azioni di controllo: PID - Proporzionale-Integrale
Il peso delle due azioni di controllo si modifica nel corso dell’esercizio del controllo.
Il significato di TI si può desumere dai grafici Ia lato:
nell’ipotesi di errore costante, T
rappresenta il
tempo impiegato dall’azione integrale per uguagliare
(ripetere) l’azione proporzionale.
Il reciproco 1/TI rappresenta il numero di volte che l’azione
integrale ripete quella proporzionale in un secondo.
Nella fase iniziale prevale l’azione proporzionale, ma col
trascorrere del tempo questa si mantiene costante mentre
si rafforza quella integrale.
Con l’abbinamento delle due azioni si:
• Migliora il comportamento a regime, grazie all’azione integrale che alza di uno il Tipo di sistema.
• Migliora la prontezza di risposta, grazie all’azione proporzionale.
OSSERVAZIONE:
L’azione integrale aggrava il fenomeno della sovracorrezione per cui, nei sistemi con spontanea
tendenza al pendolamento della risposta, può risultare destabilizzante.
Controllori
Configurazione standard deL Controllore PI (proporzionale integrativo)
In questo controllore, in cui si completano le caratteristiche di risposta rapida del controllore P e di
errore nullo a regime del controllore I, il circuito di retroazione è costituito da un condensatore C1 in serie
ad una resistenza R1 , si ha pertanto
Z1(s) = R1+1/Sc1
e quindi
f.d.t.(s) = Vu/Vr = [(1+sR1C1)/sRrC1] = (1+s*τn)/s*τi
Per il dimensionamento del regolatore PI
- si determinano i valori delle costanti di tempo Tn e Ti , che devono essere tali da
assicurare che il circuito di regolazione sia stabile e ben smorzato;
- si scelgono poi i valori di R e Rr (10-100 kohm), tenendo conto del carico
di misura
- dalle costanti di tempo si ricavano i valori di R1 e C1
ammissibile per gli organi
Controllori
Azioni di controllo: PID - Derivativa
AZIONE DERIVATIVA
e
Circuiti di
elaborazione ed
amplificazione
y
Il circuito di elaborazione ed amplificazione produce una uscita proporzionale alla derivata dell’ingresso:
y(t)  K D
de(t)
dt
DERIVATA
E’ un operatore matematico con cui si calcolano le tangenti.
L’uscita y(t) risulta proporzionale alla tangente all’errore in
quell’istante.
Con errore costante l’azione derivativa è nulla. L’azione derivativa
è quindi nulla a regime.
Il controllo mediante l’azione derivativa lavora di anticipo
sull’evoluzione dell’errore. Nel tratto iniziale l’azione si indebolisce
ben prima che cominci a ridursi l’errore, esercitando così una
azione frenante sull’evoluzione futura dell’errore.
La costante KD rappresenta la costante di derivazione. Attraverso essa è possibile rafforzare o indebolire l’azione di
controllo derivativa quale risulta dalla sola derivata dell’errore.
Controllori
Azioni di controllo: PID - Derivativa
Il circuito di elaborazione ed amplificazione nel dominio di Laplace è descrivibile con la seguente funzione di trasferimento:
Y(s)
 K D s
E(s)
E(s)
KD = costante di derivazione
K D s
Y(s)
OSSERVAZIONI
• L’operatore derivata lavora di anticipo sull’evoluzione dell’errore (riducendo la potenza quando l’errore sta ancora
salendo e aumentandola quando sta ancora diminuendo). Ciò comporta:
• Aumento della velocità di risposta del sistema, che abbinato all’anticipo consente un
• forte contrasto alle sovracorrezioni che il sistema spontaneamente tenderebbe a
produrre, con conseguenti
• migliori prestazioni dinamiche, cioè forte riduzione del pendolamento della risposta (l’azione correttrice
è tanto più energica quanto più velocemente varia l’errore)
• Complessivamente si ottiene un effetto stabilizzante sull’intero sistema.
• Poiché a regime l’errore è costante, la derivata è nulla. Ne consegue che a regime l’azione derivativa è del tutto assente.
Controllori
Configurazione standard del Controllore derivativo (D).
Nei casi in cui il sistema, in relazione alla sua inerzia, risponda lentamente, il controllore deve
sviluppare un segnale correttivo elevato, che se rimane elevato sovracompensa l'errore e porta
il sistema in oscillazione.
Serve quindi nei confronti dei bruschi disturbi un'azione correttiva inizialmente elevata che
diminuisce nel tempo, ottenibile con un controllore derivativo, la cui uscita è proporzionale alla
velocità di variazione del suo ingresso.
L'azione derivativa migliora i margini di stabilità in quanto introduce un anticipo
3.14/2 e fornisce una correzione che anticipa l'andamento dell'errore nel tempo.
L’inconveniente è che risponde solo a variazioni del
segnale errore, per cui se il sistema presenta un
errore a regime non interviene. Inoltre l'aumento
della banda passante porta ad amplificare i segnali
con contenuto armonico a frequenze elevate (come il
rumore sovrapposto al segnale utile).
di fase pari a
Controllori
Per tali motivi negli azionamenti elettrici, il controllore
utilizzano quasi esclusivamente regolatori di tipo PI.
derivativo non viene impiegato e si
Controllori
AZIONE PROPORZIONALE – DERIVATIVA ( CONTROLLORE PD )
Il controllore PD sviluppa contemporaneamente sia l’azione proporzionale che quella derivativa:
Nel dominio di Laplace:
Y(s)
 K P  K D s
E(s)
E(s)
KP  K D s
Y(s)
E’ possibile scrivere la funzione di trasferimento anche nei seguenti termini:
Controllori
Azioni di controllo: PID - Proporzionale-Derivativo
Così come è stata scritta la funzione di trasferimento non corrisponde ad alcun componente fisicamente realizzabile.
Occorre immaginare la presenza di almeno un polo. Si può immaginare un polo la cui costante di tempo sia molto più
piccola di TD, in modo da rappresentare un transitorio molto più veloce e quindi ininfluente:



Y(s)
TDs 


 K P  1
T
E(s)
 1 D s 
N 

Costante di tempo N volte più piccola di TD, il
valore di N è normalmente compreso tra 10 e 100.
Il peso delle due azioni di controllo si modifica nel corso dell’esercizio del controllo.
Il significato di TD si può desumere dai grafici a lato:
nell’ipotesi di un aumento lineare dell’errore, TD rappresenta
il tempo impiegato dall’azione proporzionale per uguagliare
(ripetere) l’azione derivativa.
Nella fase iniziale prevale l’azione derivativa, ma col trascorrere
del tempo questa si mantiene costante mentre si rafforza quella
proporzionale.
Controllori
ESEMPIO:
Con Controllore KP = 3
Azioni di controllo: PID - Proporzionale-Derivativo
KD = 0.4
NB: all’avviamento l’azione derivativa è molto brusca e potrebbe imprimere al sistema accelerazioni dannose.
Controllori
Con l’abbinamento delle due azioni:
Azioni di controllo: PID - Proporzionale-Derivativo
• Migliora il comportamento in transitorio, grazie all’azione derivativa che interviene di anticipo e riduce il
pendolamento
• L’effetto stabilizzante consente di diminuire la banda proporzionale dell’azione proporzionale, con
conseguente riduzione dell’errore a regime.
OSSERVAZIONI:
• Come ingresso all’azione derivativa viene spesso applicato il segnale di retroazione. Il
segnale errore presenta infatti delle discontinuità (a causa di discontinuità sul segnale di riferimento) che
farebbero impennare il valore della derivata, facendo saturare gli amplificatori e provocando di fatto la perdita
del controllo.
• Ulteriori miglioramenti del comportamento a regime richiedono l’aggiunta dell’azione integrale.
• Nei processi in cui sono presenti disturbi casuali e di breve durata, l’azione derivativa può causare dannosi
pendolamenti e se ne sconsiglia pertanto l’uso.
Controllori
Controllore proporzionale - derivativo (PD).
Nelle applicazioni industriali più diffuse, anche l’azione derivativa viene associata all’azione proporzionale così
da creare i cosiddetti controllori PD i quali possono essere utilizzati nei sistemi in cui si hanno improvvise
variazioni di carico.
Alcune tipologie di tali impianti possono essere sistemi di controllo per servomotori, oppure sistemi che non
presentano problemi di stabilità e di prestazioni statiche ma che, invece, richiedono una buona velocità di
risposta o un allargamento della banda passante
Con questo regolatore l’azione con cui è modificata la variabile manipolata è proporzionale alla velocità di
cambiamento dell’errore.
Controllori
AZIONE PROPORZIONALE – INTEGRALE - DERIVATIVA ( CONTROLLORE PID )
E(s)
Circuiti di
elaborazione ed
amplificazione
Y(s)
Il controllore PID sviluppa contemporaneamente le tre azioni di controllo:
La legge di controllo è quindi composta da:
• un’azione proporzionale all’errore;
• un’azione Integrale sull’errore;
• un’azione Derivativa sull’errore
Nel dominio di Laplace:


Y(s)
K
1
 K P  I  K D s  K P  1
 TD s 
E(s)
s
 TI s

Il controllore PID permette l’adattamento del controllo al sistema da controllare. Impostando i parametri KP, TI, TD
(oppure KP, KI, KD) è possibile far si che siano soddisfatte sia le specifiche a regime che quelle in transitorio.
Controllori
Tra le ragioni del vastissimo utilizzo dei regolatori PID nella pratica dell’automazione industriale (i
PID sono anche detti regolatori industriali), ricordiamo:
• semplicità di realizzazione in diverse tecnologie (elettronica, idraulica, pneumatica);
• efficacia per la regolazione di un’ampia gamma di processi industriali;
• standardizzazione con i relativi vantaggi in termini di affidabilità e economicità;
- semplicità di taratura dei parametri;
• possibilità di taratura automatica dei parametri, per mezzo di semplici esperimenti
ESEMPIO:
Azioni di controllo: PID - Proporzionale-Integrale-Derivativo
351.2
0.5s2  0.8s 1
Sistema
controllato
G(s) 
Ramo di
retroazione
H(s)  0.1
Controllori
Azioni di controllo: PID - Proporzionale-Integrale-Derivativo
Il controllore PID può essere messo a punto empiricamente
variando uno o più valori dei guadagni e osservando come
si modifica la risposta del sistema.
Si pongono uguali a zero i guadagni integrale e derivativo e
si aumenta il guadagno proporzionale fino a che il sistema
risponde bene a variazioni del punto di regolazione senza
eccessive sovraelongazioni.
Scelto un ragionevole valore del guadagno proporzionale si
aumenta quindi
lentamente il guadagno integrale per
forzare a zero l'errore del sistema.
Nella maggior parte dei casi è richiesto un piccolo valore del
guadagno integrale, in quanto se abbastanza grande, può
sopraffare l'azione del termine proporzionale, rallentare la
risposta globale e far oscillare il sistema attorno al punto
di regolazione.
In tale caso il problema si risolve
usualmente
riducendo
il guadagno
integrale
ed
aumentando il guadagno proporzionale.
Nel controllo dei motori normalmente il guadagno derivativo del controllore PID è mantenuto nullo
(il termine derivativo viene infatti implementato solo nel caso di carichi con inerzia molto elevata).
Schema di un controllore PID REALE
Controllori
il componente attivo è l’amplificatore operazionale IC1 connesso nella
configurazione invertente. La rete composta da R4, R5, R6 e P1
costituisce una resistenza equivalente Req che varia tra 11MΩ e
231MΩ. Questa rete è stata adottata per poter avere valori così grande
di resistenza usando resistenze di valore normalmente reperibili in
commercio.
L’azione proporzionale svolta dal controllore è realizzata tramite le
resistenze R1 e Req: variando il valore di P1, si aumenta il guadagno e
di conseguenza diminuisce l’errore. Però se un guadagno maggiore
migliora le prestazioni di precisione e di velocità, comporta anche un
minore margine di stabilità.
La parte integrale del controllore viene svolta dalle resistenze R1 e R7
e dai condensatori C4, C5 e C6.
I tre condensatori possono essere inseriti singolarmente o in combinazione tra loro permettendo
ampi margini di regolazione: infatti variando la capacità varia la costante di tempo del regolatore
integrale. Integrando il segnale di ingresso (errore) varia la propria uscita fino a quando il segnale di
errore non è nullo. La parte derivativa del controllore è formata dalle resistenze R2 e Req e dai
condensatori C1, C2 e C3.
Anche in questo caso i condensatori possono essere utilizzati singolarmente o in combinazione tra
loro consentendo ampi margini di regolazione. L’azione derivativa ha il grosso problema di dare
uscita nulla in presenza di errore costante e diverso da zero: per questo motivo non viene mai usata
da sola ma sempre affiancata dal controllo integrale o da quello proporzionale o da una loro
combinazione.
Controllori
Viene però usata perché il suo effetto è positivo per il margine di stabilità: infatti può rendere
stabile un sistema divenuto instabile a causa dell’adozione di guadagni troppo elevati o azioni
integratrici troppo grandi Controllori adattativi.
Le caratteristiche funzionali dei controllori standard sono determinate dalla struttura del loro
circuito di retroazione e dai valori assunti delle relative resistenze e capacità.
Nel caso di sensibili variazioni delle condizioni di funzionamento ipotizzate nella fase di
progettazione del controllore dell'azionamento e qualora si richiedono al sistema controllato
prestazioni elevate, é necessario fare ricorso a controllori adattativi
Questi sono essenzialmente di due tipi:
- a struttura fissa e parametri variabili;
- a parametri fissi e struttura variabile.
I controllori adattativi a
struttura fissa e parametri variabili si ottengono inserendo
nel loro circuito di retroazione uno o più moltiplicatori mentre quelli a parametri fissi e
struttura variabile consentono di passare da una struttura proporzionale-integrativa ad una
struttura proporzionale grazie all’inserimento di elementi attivi (mosfet, diodi)
Controllori
Considerazioni sulla scelta e sul dimensionamento del controllore.
Negli azionamenti elettrici il sistema elettromeccanico da regolare, anche se ordine elevato,
presenta un comportamento dinamico simile a quello di un sistema del secondo ordine;.
Esso possiede infatti normalmente: due costanti di tempo dominanti
(meccanica τm e elettrica τa),
che rallentano la dinamica del sistema, e una serie
di piccole costanti di tempo τpk (e/o di piccoli
ritardi) prodotti da organi
di comando, filtri
e circuiti ausiliari di regolazione, il cui
effetto si estingue rapidamente La loro f.d.t é quindi del tipo:
f.d.t= K / (1+s*τm) (1+s*τa) *(1+s*τp) )
con K guadagno statico
τp= piccola costante di tempo equivalente a tutti i ritardi del sistema
E' pertanto necessario utilizzare uno o più controllori in cascata, al fine di compensare le costanti
di tempo dominanti del sistema da regolare e inserire un polo nell'origine, la cui assenza
comporta un errore a regime nella risposta a gradino.
Con
scelte adeguate delle costanti di tempo del controllore il sistema si rende stabile e la rapidità
di regolazione non dipende piú dalle caratteristiche del motore o della macchina azionata ma solo
dalla piccola costante di tempo equivalente τp
Controllori
PWM
Amplificazione PWM
PRINCIPIO DI FUNZIONAMENTO
La amplificazione presenta le seguenti caratteristiche:
• una uscita istantanea a due posizioni
• un periodo degli impulsi costante
• un duty cycle proporzionale all’ingresso:
• un valore medio nel periodo funzione di TON:
Per la dipendenza del valore medio dell’uscita dal segnale di ingresso, la amplificazione PWM è detta anche a tempo proporzionale
Controllori
Amplificazione PWM
La alta frequenza di commutazione fa si che il carico veda (risulti sensibile) solo il valore medio.
Il controllo PWM realizza quindi un più efficiente controllo proporzionale, ma conserva il limite intrinseco dell’azione
proporzionale: un errore di offset in caso di variazione permanente del carico o comparsa di disturbi permanenti.
Con una frequenza di commutazione degli IGBT di ~ 18 - 20 kHz, si ha un periodo di 55.6 - 20 ms, per cui la risposta
dell’amplificatore può essere considerata istantanea, ossia la sua funzione di trasferimento come una costante (cioè non
contenente termini con la variabile s).
Controllori
RISPOSTA IN FREQUENZA
Regolatore PI
Il controllore PI è caratterizzato dalla seguente funzione di trasferimento:
F(s) 
s k p  k i
s
In
cui sono presenti:
• uno zero: s = - ki/kp
• un polo: s = 0
Dai diagrammi di Bode si possono trarre le seguenti osservazioni:
• il modulo presenta un andamento tipo passa basso e, nel caso kp < 1, introduce una attenuazione verso le
pulsazioni maggiori
• il controllore introduce un ritardo di fase, maggiore verso le basse pulsazioni
• un aumento del peso dell’azione integrale (ki) comporta (a parità di kp) uno spostamento a destra dello zero, con
conseguentemente ampliamento dell’intervallo di pulsazioni dove maggiore è il ritardo di fase.
Controllori
REGOLATORE PI
L’azione proporzionale, associata all’azione integrale, ha un parziale effetto stabilizzante. Se si riporta la risposta in
frequenza al variare di kp, si può osservare come all’aumentare del peso dell’azione proporzionale si riduce l’intervallo
di pulsazioni con forti ritardi, ma tende ad aumentare la banda passante del complesso degli apparati in cascata.
L’introduzione di un controllore PI in un controllo con retroazione ha delle conseguenze che dipendono dalle
caratteristiche del sistema, tenuto conto che si introduce comunque un ritardo di fase.
6
Controllori
Controllore PI introdotto in un sistema molto stabile
APPLICAZIONE
Sistema senza controllore PI
+
200
s 2  6 s  5
+ _
0.04
Sistema con controllore PI
Ipotesi:
kP  2
k I  1.6
+
+ _
s  kP  kI
s
200
s 2  6 s  5
0.04
Controllori
Controllore PI introdotto in un sistema molto stabile
Osservazioni:
risultano evidenti:
• il forte aumento del guadagno d’anello alle basse frequenze
• l’estensione della banda passante (kp è > 1)
Controllori
Controllore PI introdotto in un sistema molto stabile
Il sistema senza controllore è caratterizzato da un MG infinito e da un MF pari a 117°.
Dopo l’introduzione del controllore PI il MG resta infinito, mentre il MF si riduce a 65°, un valore ancora rilevante e
soddisfacente.
NB: al di là del posizionamento dello zero del controllore, quest’ultimo introduce comunque un ritardo di fase che riduce
il MF, ed ha, quindi, comunque un effetto destabilizzante.
Controllori
Controllore PI introdotto in un sistema molto stabile
NB
: L’azione proporzionale pesa il 25% in più rispetto all’azione integrale.
Controllori
Controllore PI introdotto in un sistema poco stabile
Il sistema senza controllore è caratterizzato da un MG pari a 23.2 dB e da un MF pari a 31.3°.
Con l’introduzione del controllore PI i margini divengono entrambi negativi e denotano un anello chiuso instabile.
Valori diversi di kp e ki mantengono il sistema stabile, ma i margini sono così ridotti da rendere del tutto inaccettabile
il transitorio (es: kp = 3, ki = 0.4, cioè kp 6.5 volte ki, risultano MG = 8.71 dB e MF = 6.7°).
NB: si ricordi che un aumento di kp ha effetto stabilizzante, ma al prezzo di un aumento dell’ampiezza delle
sovraelongazioni.
RIEPILOGO
Controllori
Un sistema di controllo ad anello chiuso deve soddisfare le specifiche assegnate nel dominio della
frequenza e quelle assegnate nel do-minio del tempo. Queste ultime si suddividono in specifiche del
comportamento a regime (errore a regime, sensibilità ai disturbi additivi e para-metrici) e in
specifiche del comportamento in regime transitorio ( tempo di salita, sovraelongazione, tempo di
assestamento, velocità della rispo-sta).
Le specifiche definite nel dominio della frequenza sono la banda passante, la stabilità, il margine di
fase e il margine di guadagno. In particolare se il sistema non è stabile, o se il suo margine di fase e il
suo margine di guadagno non corrispondono a quelli richiesti, è necessario intervenire sul sistema,
modificarlo in modo che risponda ai requisiti richiesti senza alterare, nei limiti del possibile, le altre
caratteristiche quali la velocità della risposta e la precisione.
La stabilizzazione, ad esempio, di un sistema instabile mediante la riduzione del guadagno di anello è
consigliabile solo in casi particolarmente semplici perché tale tecnica provoca, come si è visto,
l'aumento dell'errore a regime.
Nei casi più
complessi, quando cioè il progettista deve soddisfare le specifiche assegnate, è
necessario modificare la configurazione del sistema introducendo, in punti opportuni della catena, reti
elettriche di tipo passivo o di tipo attivo al fine di migliorare le prestazioni statiche e dinamiche del
sistema.
Se si desidera stabilizzare il sistema senza diminuire il guadagno del sistema e allora possibile usare
una rete ritardatrice.
Controllori
La rete ritardo-anticipo, infatti, permette di sfruttare i pregi di entrambe le reti correttrici,
consente di stabilizzare sistemi assolutamente instabili (ovvero sistemiche, se chiusi in
retroazione
con un semplice regolatore proporzionale, sono instabili in anello chiuso per
qualsiasi valore del guadagno), senza un eccessivo aumento della larghezza di banda.
Inoltre, poiche la rete ritardo-anticipo ha guadagno statico unitario, non varia la precisione a
regime.
Elementi del circuito di controllo.
Negli azionamenti elettrici il tipo di controllo del moto di gran lunga più diffuso è quello in cascata
o gerarchico, che è caratterizzato dalla presenza di più anelli sovrapposti, in ognuno dei quali la
variabile di stato ha una dinamica molto più rapida di quella relativa alla variabile di stato
dell'anello immediatamente più esterno.
Regolatore di posizione: non presente
Controllori
Regolatore di corrente: dipende dal tipo di motore
Regolatore di velocità: dipende dal tipo di carico
Regolatore di posizione: dipende dal tipo si carico
e si posiziona nell’anello esterno
Le caratteristiche salienti del controllo in cascata sono:
- relativa semplicità nella scelta e nel dimensionamento dei vari controllori (uno per ogni
variabile controllata); il transitorio della variabile di un anello inizia solo dopo che è terminato
quello della variabile relativa all'anello sovrastante per cui si può prendere in esame una sola
parte del sistema per volta. Nel caso dell'azionamento di figura si dimensiona il controllore
dell'anello di corrente, quindi quello di velocità e infine quello di posizione
- notevole flessibilità, in quanto é possibile, partendo da un dato azionamento,
ottenere
facilmente il controllo di ulteriori variabili aggiungendo altri anelli;
- elevata protezione del sistema, in quanto ogni variabile intermedia può essere controllata
limitando il relativo valore di riferimento.
In un circuito di controllo si possono distinguere:
Controllori
a. organi di riferimento
Forniscono una grandezza di riferimento regolabile espressa per mezzo
di una tensione
continua (di valore massimo pari a 10-15V). L'elemento più
semplice e più usato é il
potenziometro
b. organi di controllo
La funzione dell'organo di controllo è quella
fornire, in base ai valori della tensione di
comando (Vcm) fornita dal regolatore
di corrente e delle
tensioni di riferimento ricavate
dalla rete di alimentazione(Vr) le sequenze degli impulsi di gate per gli SCR controllando gli
istanti di innesco e quindi il valore medio della tensione ai suoi morsetti in uscita
c. Organi di misura
I sensori sono insiemi di uno o più trasduttori con relativa circuiteria per l'elaborazione del
segnale, la cui funzione è convertire una generica grandezza fisica in ingresso in un segnale
elettrico (generalmente in una tensione continua) in uscita interfacciabile con il sistema di
controllo.
I sensori si dividono in assoluti o incrementali, in analogici e digitali, in intelligenti (se
interagiscono con un computer di controllo per la manipolazione dei dati) e non intelligenti (se
forniscono al computer dei semplici dati).
Controllo del motore in continua a magnete permanente
Dal punto di vista elettrico, il motore può essere assimilato al seguente circuito
Definendo con:
Ke costante di velocita,
R resistenza di armatura,
L induttanza di armatura
E = Ke*w(t)
va= R*i+ L*(di(t)/dt)+ E
Trasformando nel dominio di Laplace e ipotizzando I(0)=0 si ottiene
V(s) = Ke*wm(s) + (R +L*s)*i(s)
per un motore in corrente continua possiamo scrivere
C = coppia del motore = Kt *i(t)
Kt costante di coppia del motore Es = Ke*w
Per la parte meccanica, supponendo che la trasmissione del moto venga effettuata mediante un albero
ed un giunto di tipo rigido, in modo che la velocità dell'asse lato-motore e lato-carico sia la stessa, la
coppia generata Cm dal motore dovrà essere uguale alla somma della coppia resistente Cr applicata
all'albero del motore e della coppia inerziale (inerzia dovuta alla parte meccanica e al carico, trascurando
la coppia di attrito)
Cm –Cr = Cj = J*(dw/dt)
w = (1/Js)*(Cm – Cr)
d θ(t)/dt =w(t)
θ = (1/s)*w
Schema a blocchi del
senza carico )
motore comprensivo del
controllo del moto
controllo di posizione
carico (che coincide, nel caso in esame, con quello
Funzione di trasferimento. Per lo studio della funzione di trasferimento, si deve tenere presente che
la coppia resistente Cr, che la coppia motoria Cm deve vincere, è somma di più termini:
Detto J il momento di inerzia complessivo del motore e del carico, At il coefficientedi attrito viscoso
complessivo del motore e del carico, e Cu la coppia resistente del carico, si può quindi scrivere:
In questo schema a blocchi sono considerate come entrate la tensione di armatura e la coppia resistente del carico, e
come uscita la velocità angolare: si tratta di un sistema a retroazione negativa, pertanto il motore tende ad
autocompensarsi, ovvero a mantenerecostante la sua velocità (con Va costante).
Se si suppone che siano trascurabili gli attriti, la funzione di trasferimento del motore,valutata rispetto alla tensione di
alimentazione, risulta:
Si tratta di una funzione di trasferimento con due poli; questo motore è
quindi un sistema del secondo ordine. I poli si ricavano dalle radici del
denominatore:
poli possono risultare reali negativi (distinti o coincidenti), o complessi coniugati a parte reale
negativa.
In ogni caso, quindi, il sistema è asintoticamente stabile; in presenza di una sollecitazione a gradino
della tensione di ingresso, se i poli sono reali la velocità del motore raggiunge il valore a regime in
modo aperiodico, mentre con poli complessila raggiunge tramite un’oscillazione smorzata.
Due parametri caratteristici del motore sono la costante di tempo elettrica e e la costante di tempo
meccanica m
Si potrebbe facilmente dimostrare che, qualora risulti Tm >= 4Te, i poli risultano reali (risposta aperiodica); in
particolare qualora risulti Tm >= 10T e i due poli coincidono, a meno del segno, con l’inverso delle due costanti
di tempo e, ovviamente, esiste un polo dominante determinato da Tm
Da queste premesse può proseguire lo studio calcolando
la f.d.t equivalente al
comportamento desiderato della macchina e del sistema (a vuoto, oppure quando viene
impressa una variazione brusca della coppia resistente).
Si studiano successivamente le risposte ai vari segnali d’ingresso, determinandone le
condizioni di stabilità tenendo presente che Il motore in continua è caratterizzato da due
parametri particolarmente importanti,
la costante di tempo elettrica
τe= La/Ra
la costante meccanica τm = Ra*J /KeKt,
dove j è il momemto di inerzia complessivo del motore collegato al carico.
Se, come normalmente succede,
τm>>τe la funzione di trasferimento del motore F (s) =
w (s)/Va(s), che lega la velocità di rotazione alla tensione di armatura, espresse mediante la
trasformata di Laplace, viene a presentare due poli distinti, in valore assoluto sostanzialmente
coincidenti con l'inverso delle costanti di tempo.
La frequenza di taglio del sistema viene pertanto ad essere determinata dal polo corrispondente
alla costante meccanica del motore
Si potrebbe facilmente dimostrare che, qualora risulti Tm >= 4Te, i poli risultano reali (risposta aperiodica); in particolare
qualora risulti Tm >= 10T e i due poli coincidono, a meno del segno, con l’inverso delle due costanti di tempo e,
ovviamente, esiste un polo dominante determinato da Tm
Dinamo tachimetrica
I motori in corrente continua sono delle macchine dal funzionamento reversibile, ovvero, ponendo in rotazione la
macchina, è possibile prelevare una tensione di armatura. La macchina, in questo modo, si comporta da
generatore in continua e viene detta dinamo. In particolare, per la la forza elettromotrice di armatura risulta
direttamente proporzionale alla velocità: se tra i terminali dell’avvolgimento non viene applicato un carico
significativo, ovvero la tensione Va viene prelevata praticamente a vuoto, risultando trascurabile la c.d.t. su Ra,
per cui si può considerare
Va =E
Una macchina di questo tipo, strutturalmente equivalente a un piccolo motore in DC a magnete permanente,
viene detta dinamo tachimetrica e viene usata come trasduttore di velocità angolare, calettandola su un asse di
rotazione di cui si vuole va-lutare la velocità di rotazione. Le dinamo tachimetriche devono presentare come
caratteristiche peculiari una limitata inerzia e poche perdite meccaniche, in modo da non alterare le
caratteristiche del carico meccanico applicato all’asse di rotazione. Mediamente, queste dinamo presentano una
sensibilità di 0,1÷1 V per 100 giri/min. Vediamo alcuni limiti di questi trasduttori:
la tensione di uscita presenta una certa ondulazione residua: La presenza del collettore permette poi di prelevare
un segnale raddrizzato a onda intera. Per ridurre l’ondulazione, si deve aumentare il numero dei settori del
collettore (fig. 3);
◗
la linearità è abbastanza limitata (difficilmente l’errore di linearità è inferiore al 10%);
◗
l’inerzia meccanica e l’attrito non sono sempre totalmente trascurabili;
◗
presentano una limitata velocità massima, a causa delle vibrazioni delle spazzole;
◗
le spazzole sono soggette a usura.
Motori a eccitazione indipendente :
caratteristica meccanica
E = K*
Φ *Ω
(1)
Cm = K * Φ *I
Caratteristica meccanica del motore
con
U = E +Ri*Ii
(2)
I = U – E /Ri = (U – K*Φ*Ω)/Ri
(3)
eccitazione indipendente e flusso costante
la velocità è:
- direttamente proporzionale alla tensione alle spazzole,
- inversamente proporzionale al flusso risultante in cui sono immersi
conduttori d’indotto
La variazione di velocità può quindi ottenersi con la variazione della
tensione, con la variazione del flusso o con entrambe le variazioni
Lo schema a blocchi coincide con quello a magneti permanenti
Operando a flusso costante, per variare la velocità si agisce sulla tensione di armatura e si opera,
come d’altronde nei motori a magnete permanente, a coppia motrice costante. Infatti, per la , o per la ,
al variare di Va varia anche E e, quindi, la differenza rimane costante e tale risulta anche la Ia e, per la o
la , la Cm.
Al variare della velocità, a flusso costante, essendo Ia costante, la potenza assorbita dall’armatura
cresce linearmente con la Va.
Facendo ancora riferimento alla figura , quando la velocità del motore supera il valore nominale, se
non si vuole sovraccaricare lo stesso in modo eccessivo, non è più possibile aumentare la velocità
agendo sulla tensione di armatura. Mantenendo costante la tensione di armatura, si può variare la
velocità agendo sul flusso. In questo modo, però, per aumentare la velocità si deve ridurre il flusso;
infatti per la , se si suppone E  Va, si vede che la velocità è inversamente proporzionale al flusso.
Riducendo il flusso, si vede che, per la , diminuisce la coppia motrice; in conseguenza deve ridursi
anche la coppia resistente e tende a risultare costante la Pa.
Per lo studio della funzione di trasferimento, se si opera a flusso costante, rimane valido quanto
esposto per i motori a magnete permanente.
Si osservi, infine, che in questo tipo di motore, per invertire il verso di rotazione, è possibile agire sia
sul verso della tensione di armatura che su quella di eccitazione
ESERCIZIO: CONTROLLO DI SPESSORE
SCHEMA DI PRINCIPIO
SCHEMA A BLOCCHI
Alimentazione di potenza
Circuiti di retroazione
Il ritardo finito viene inserito nel ramo diretto in quanto il ramo di retroazione comincia con la lettura
della variabile d’uscita da parte del sensore.
CONVERTITORE
DI POTENZA

Svolge la funzione della amplificazione della potenza ed è caratterizzato da un guadagno A0:
Ao = Va/e
La velocità di risposta dipende dalla tecnologia con cui sono realizzati.

Se introduce un ritardo la sua funzione di trasferimento è dipendente dalla variabile di Laplace ‘s’.

Ipotesi:
risposta istantanea
Funzione di trasferimento
A(s) = A0
SERVOMOTORE ELETTRICO

Svolge la funzione di attuatore: converte la potenza elettrica in potenza meccanica.

La sua funzione di trasferimento dipende dalla tecnologia con cui è realizzato.
Ipotesi: Motore a collettore in corrente continua a magneti permanenti
Funzione di trasferimento: costituisce un sistema del 2° ordine
VITE A RICIRCOLO DI SFERE

Svolge la funzione di attuatore (insieme al servomotore): converte il movimento rotatorio in traslatorio.

Il suo parametro fondamentale è il passo:

Dal passo si ricava il Rapporto di trasformazione:
traslazione della chiocciola per un giro della vite
In questo esempio la Funzione di trasferimento non corrisponde al Rapporto di trasformazione, in quanto:
RITARDO FINITO (1/3)

E’ un ritardo dovuto alla collocazione fisica del sensore che misura lo spessore della lamiera: è posto alla distanza
d dagli assi dei cilindri

Lo si calcola attraverso la relazione:

Nel dominio di Laplace si rappresenta con il termine
NB: si tratta di una funzione di trasferimento di tipo trascendente, occorre trovare una funzione razionale che ne
rappresenti una buona approssimazione.
RITARDO FINITO (2/3)
Una funzione esponenziale può essere approssimata con diverse funzioni. Per piccoli valori dell’esponente le
diverse rappresentazioni sono equivalenti.
RITARDO FINITO (3/3)
In questo sistema:
Approssimante di Padé (1° ordine):
Approssimante di Padé (2° ordine):
CIRCUITI DI RETROAZIONE
• Il ramo di retroazione è costituito da:
-Sensore, per la misura della variabile controllata
-Circuiti di elaborazione, per il condizionamento del segnale elettrico fornito dal sensore
• Il dimensionamento del guadagno è determinato da:
-valore desiderato della variabile controllata (xd)
-valore del segnale di retroazione Vret uguale all’ingresso di riferimento (Vrif)
Più in generale:
ESEMPIO NUMERICO (1/6)
CONVERTITORE DI POTENZA
Il guadagno risulta posto pari a:
SERVOMOTORE
VITE A CIRCOLAZIONE DI SFERE
Esempio numerico (2/6)
RITARDO FINITO
Il sensore è collocato alla distanza d = 10 cm
La lamiera avanza con la velocità di vl = 0.2 m/s
Funzione di trasferimento: Approssimante di
Padé del 1° ordine:
CIRCUITI DI RETROAZIONE
La lamiera deve essere laminata allo spessore di
Il segnale di riferimento è posto a Vrif = 5 V
x = 12 mm
Ipotesi: i circuiti forniscono una risposta istantanea, ciò consente di scrivere la funzione di trasferimento come
una costante pura
Esempio numerico (3/6)
VERIFICA DELLA STABILITA’
Metodo di Routh
Calcolo della funzione di trasferimento del ramo diretto:
G(s)  AM (s) Rv(s) RF (s) 
Esempio numerico (4/6)
I coefficienti dell’equazione soddisfano la condizione necessaria.
Si costruisce la tabella:
I coefficienti
della prima colonna non presentano variazioni di segno per cui il sistema risulta
stabile: 4 soluzioni reali negative e/o complesse coniugate con parte reale negativa.
Le soluzioni dell’equazione caratteristica risultano infatti:
s1 = - 3.90
s2 = - 2.99
s3 = - 0.057 + j 0.25
s4 = - 0.057 - j 0.25
Esempio numerico (5/6)
NUOVA IPOTESI
un problema sul controllo della velocità della lamiera provoca un rallentamento del nastro facendo salire
il ritardo t0 a 5 s
Se il problema di controllo si prolunga nel tempo potrebbero presentarsi fenomeni di instabilità.
E in questo caso, ricalcolando il segno delle soluzioni dell’equazione caratteristica, si scopre che il
sistema è divenuto instabile.
Equazione caratteristica:
soluzioni:
10 s4  34 s3 17 s2  0.023s  0.79  0
s1 = - 2.79
s2 = - 0.69
s3 = 0.037 + j 0.20
s4 = 0.037 - j 0.20
Esempio numerico (6/6)
controlli digitali
MOTORE PASSO PASSO
MOTORE A RILUTTANZA VARIABILE
TECNICHE DI PILOTAGGIO
CARATTERISTICA MECCANICA
INTEGRATO L298
controlli digitali
MOTORE PASSO PASSO
Proprietà
E’ un motore alimentato con forme d’onda impulsive: ad ogni impulso corrisponde una rotazione del motore di un
angolo fisso (passo, step).
Vantaggi:
•
adatti per controllo di posizione e/o velocità in sistemi con catena aperta (senza retroazione)
•
•
affidabili e robusti (non necessitano di manutenzione periodica)
facile controllo via computer (forme d’onda impulsive) Svantaggi:
• bassa potenza specifica
• basso rendimento energetico
• necessità di scheda di alimentazione elettronica
• funzionamento irregolare a basso regime
• bassa velocità massima
controlli digitali
TECNOLOGIA di realizzazione del rotore
• Magneti permanenti (MP)
• Riluttanza variabile (RV)
• Ibridi
NUMERO DI FASI presenti sullo statore
• Bifase
• Polifase
SENSO DI CIRCOLAZIONE della corrente negli avvolgimenti di ciascuna fase statoriche
• unipolare: un solo senso di percorrenza della corrente nell’avvolgimento
• bipolare: è possibile invertire il verso della corrente nell’avvolgimento
Un parametro molto importante è quello della RISOLUZIONE, esprimibile come:
• angolo (passo, step) di cui ruota il rotore per ogni impulso
Risoluzione =360
Numero di passi
• numero di passi per giro
NB: la risoluzione deriva dalle caratteristiche costruttive del motore, ma può essere modificata
attraverso la scheda elettronica di pilotaggio.
controlli digitali
Motore step a Magnete Permanente
Motore step ibrido
controlli digitali
Motore a Magneti Permanenti, Bifase, Bipolare
Magneti Permanenti: il rotore è formato da magneti permanenti (magnetizzazione radiale).
Nell’esempio è presente una sola coppia polare.
Bifase: si hanno due fasi A-C e B-D
Bipolare: l’assenza di una presa centrale nelle fasi lascia intendere che deve essere possibile
l’inversione della corrente nelle fasi.
Funzionamento:
Alimentando il motore dal terminale A, si genera un flusso magnetico che ha un nord in 1 e
un sud in 3 (fig. a). Considerando la situazione di partenza del rotore, il nuovo flusso lo fa
girare di 90° in senso orario (fig. b). Una successiva alimentazione dal terminale B (nord in 2
e sud in 4) induce una ulteriore rotazione di 90° (fig. c).Alimentando ulteriormente da C e poi
da D si fa completare al rotore un giro.
controlli digitali
Il rotore compie un giro completo
in
4 T (T = durata di un
impulso). Spesso la cadenza dei
passi viene indicata con la
frequenza:
f
Se il moto è continuo, è possibile
calcolare una velocità media di
rotazione

2
4T
1
T
rad 
 s 
Dove 2  / 4 rappresenta l’angolo per passo.
NB:
questa modalità di alimentazione (tecnica di
pilotaggio) è chiamata One Phase-On (oppure
Wave Drive Mode)
controlli digitali
Motore a Magneti Permanenti, Bifase, Unipolare
Unipolare: la presenza della presa centrale nelle fasi
lascia intendere che la corrente nelle fasi può avere
un solo senso.
Funzionamento:
La corrente entra da un terminale ed esce dalla
presa centrale.
Alimentando in sequenza i terminali A – B - C – D
si fa fare un giro completo al motore.
NB: i motori unipolari sono pilotati con le stesse tecniche dei motori bipolari.
controlli digitali
Confronto Bipolari - Unipolari
• I motori unipolari richiedono una scheda di controllo più semplice poiché non richiedono
l’inversione del verso della corrente nelle fasi
• I motori bipolari forniscono una coppia maggiore a parità di volume esterno in quanto
l’intero avvolgimento è percorso da corrente, quando la fase è eccitata (negli unipolari
invece solo metà avvolgimento per volta può essere percorso da corrente)
controlli digitali
Motore a Riluttanza Variabile
Funzionamento: il rotore non è magnetizzato; la coppia motrice si forma per l’anisotropia del rotore:
•Alimentando la bobina 2 si crea un polo magnetico in 2,
•che induce un polo opposto in y’,
•i due poli si attraggono e nasce la coppia motrice.
NB: se il rotore fosse un cilindro (isotropo) il punto y’ si troverebbe sull’asse 2 – 2’ e non
nascerebbe alcuna coppia.
Il fenomeno può essere descritto anche in termini di riluttanza: la coppia motrice nasce in
quanto il circuito magnetico nel tratto 2 – 2’ presenta riluttanza minima su un percorso che
non è quello diretto, più breve, tra i denti di statore. Le forze di attrazione tra i poli magnetici
indotti non giacciono sulla stessa linea d’azione e formano quindi una coppia.
Essendo il rotore non magnetizzato, l’inversione del senso di
rotazione non può avvenire invertendo le polarità magnetiche
sullo statore (come in quelli a MP).
Occorre modificare la sequenza di alimentazione degli
avvolgimenti.
Per questo motivo gli avvolgimenti hanno una presa centrale.
Statore e rotore devono avere numero di denti diverso per evitare
un loro allineamento.
CONFRONTO
controlli digitali
MP - RV
MOTORI a MP:
• Grazie al rotore magnetizzato, presentano una coppia residua, in assenza di alimentazione.
• Sono costruibili solo a bassa risoluzione, in quanto, per ragioni meccaniche, non si può
aumentare più di tanto il numero di poli magnetici del rotore.
• Per via dell’alta inerzia del MP del rotore la frequenza di alimentazione deve essere piuttosto
bassa.
Il profilo b corrisponde a un maggior momento
d’inerzia, che frena la
accelerazione e ritarda il raggiungimento della posizione finale da parte del
rotore.
Il profilo a consente di dimezzare la durata degli impulsi (raddoppia la
frequenza), impossibile per il motore dal profilo b.
Motori a RV
• Non manifestano alcuna coppia residua.
• Realizzano risoluzioni molto alte.
• Raggiungono velocità maggiori
• Presentano fenomeni di risonanza che generano oscillazioni
dell’asse intorno alla posizione diequilibrio.
controlli digitali
Motore Ibrido
Il rotore è formato da due corone dentate poste agli estremi di un cilindro
che contiene un magnete permanente (magnetizzazione assiale).
I denti delle due corone sono sfasati di 1/2 passo polare (passo polare =
distanza angolare tra due denti).
Sullo statore sono presenti espansioni polari con denti dello stesso passo
di quelli di rotore.
Quando i denti di rotore sono allineati con quelli di una espansione
polare,
essi risultano sfasati di 1/4 di passo da quelli dell’altra
espansione polare.
La tecnologia ibrida è complessa e costosa, ma consente di raggiungere
alte risoluzioni (480 passi per giro).
I motori ibridi esaltano i vantaggi delle altre due tecnologie:
• disponibilità di una coppia residua (grazie al magnete permanente)
• alta risoluzione (grazie sagomatura del rotore per generare percorsi
a riluttanza diversa).
controlli digitali
TECNICHE DI PILOTAGGIO
• Le seguenti tecniche si applicano a tutti i tipi di motori:
• FULL STEP (Passo intero)
• Wave Drive Mode (One Phase-On): alimentazione di una fase per volta
• Normal Drive Mode (Two Phase-ON): alimentazione di due fasi per volta
• HALF STEP (Mezzo passo), mediante alternanza One Phase-On e Two Phase-On
• MICROSTEPPING (micropassi), mediante modulazione della corrente.
controlli digitali
ESEMPIO: Two Phase-On
Osservazioni: Rispetto alla tecnica One Phase-On
• si modifica la posizione di equilibrio del rotore, ma non
cambia la risoluzione (90° per passo)
• la coppia motrice aumenta di 1.41 volte:
BT
BAC = BDC = B
BAC
BT = 1.41B
BBD
controlli digitali
ESEMPIO:
Half Step
A
B
C
D
t
A
AB
B
BC
C
Osservazioni:
• si raddoppia risoluzione (45° per passo)
• la coppia motrice non è costante: quando sono alimentate due fasi
aumenta di 1.41 volte. Si supera il problema aumentando la
corrente quando si alimenta un solo avvolgimento.
controlli digitali
ESEMPIO:
Microstepping
Consiste nell’alimentare due fasi per volta,
ma regolando la corrente nelle diverse fasi.
Se si dimezza la corrente nella fase B-D:
Consiste nell’alimentare due fasi per volta,
ma regolando la corrente nelle diverse fasi.
controlli digitali
Esempi di collegamenti
Si tratta di motori a 2 fasi, ma con diverse bobine e
collegamenti esterni.
cavi per i
Non esiste uno standard nella designazione dei colori dei cavi.
controlli digitali
Circuiti di alimentazione
2 bobine ( 4 cavi ) : Bipolare
4 bobine ( 8 cavi ) : Unipolare
Motore con 5 fasi
controlli digitali
Principali grandezze nominali
DATI DI TARGA
Angolo di passo
[°]
Angolo di cui ruota il rotore ad ogni passo
Tensione di fase
[V]
Tensione di alimentazione delle fasi
Corrente di fase
[A]
Corrente assorbita da una fase quanto alimentata alla tensione di fase
Resistenza di fase [ Ω ]
Induttanza di fase [ L ]
Resistenza elettrica di una fase
Induttanza di una fase
Coppia di mantenimento (Holding Torque) [ Nm ] Coppia sviluppata dal motore quando
alimentato e fermo
Coppia residua (Detent Torque) [ Nm ] Coppia sviluppata dal motore quando non alimentato e fermo
Momento d’inerzia [ kg m2 ]
Momento d’inerzia del rotore
NB: nel caso dal motore fuoriescano un numero di conduttori tale da consentire funzionamenti sia
come unipolare che bipolare e il costruttore fornisca i dati di targa senza specificare a quale
configurazione si riferiscano, essi sono normalmente da attribuirsi alla configurazione bipolare.
controlli digitali
NB:
CH = Coppia di mantenimento (coppia di stallo) (Holding Torque): il motore è alimentato ed è
fermo. In questa circostanza assorbe la corrente massima (di fase).
A bassa velocità (frequenza) il motore ha normalmente un funzionamento instabile, per cui si evita
di tracciare la caratteristica.
All’aumentare della velocità la coppia generata diminuisce (con la corrente assorbita). Oltre un
limite massimo di velocità (frequenza) il motore perde il passo e si blocca.
controlli digitali
Normalmente il motore parte da fermo e viene alimentato immediatamente con impulsi alla frequenza
desiderata.
Durante l’avviamento la coppia motrice deve vincere oltre alla coppia resistente del carico anche la
coppia d’inerzia, che si manifesta in conseguenza della accelerazione:
La coppia d’inerzia (Ci) si oppone alla accelerazione, per cui non tutta la coppia di pull-out (Cpo) è
disponibile per il carico.
Si definisce coppia di pull-in (Cpi) la coppia di carico che il motore riesce ad avviare senza perdere
passi. Essa dipende quindi dal
• carico (per via dell’inerzia) e dalla frequenza
(per via della coppia motrice CPO)
controlli digitali
Motore Passo Passo Caratteristica meccanica
Start-Stop Range: per coppie di carico interne a quest’area il motore è in grado di
avviare, fermare e invertire il movimento del carico senza perdere passi.
Slew Range: per coppie di carico interne a quest’area il motore riesce ad avviare o arrestare
il carico, senza perdere passi, solo se la frequenza di alimentazione varia lentamente.
controlli digitali
Formule
TP = intervallo di tempo tra due passi (nella modalità One phase-On: durata dell’impulso) [ s ]
f = frequenza dei passi, passi per secondo
[ Hz ] ω = velocità
angolare [ rad/s ]
α = angolo corrispondente ad un passo [ rad ]
Il motore deve raggiungere la velocità (ω) corrispondente alla frequenza di alimentazione nel
tempo TP di un passo.
controlli digitali
Esercizio
Verificare se è possibile avviare con frequenza di 500 Hz, un carico caratterizzato da un JC = 22 gcm2 e
una CC = 6 Ncm, col seguente motore:
α = 3.6 ° = 0.06283
rad
IN = 0.80 A
R = 4.5 Ω L
= 5.7 H
CH = 11.4 Ncm
CD = 1.55 Ncm
JM = 15 gcm2
SOLUZIONE
Bisognerebbe verificare se la CC, alla frequenza di 500 Hz, si trovi all’interno della curva di pull-in. Ma non si
dispone della curva di pull-in. Si deve allora calcolare la coppia d’inerzia e verificare che sottraendola alla coppia
di pull-out non dia origine a una coppia inferiore a quella del carico.
Da Curva di pull-out, a 500 Hz: CPO = 10 Ncm
JT = JM + JC = 15 + 22 = 37 gcm2 = 37·10-3·10-4 kgm2

t
   f 2  0.06283 5002  15708
C i  J T
rad/s 2

 3.7 106 15708  0.0581 Nm  5.81 Ncm
t
= 3.7·10-6 kgm2
C pi  C po  C i  10  5.81  4.19 Ncm
NB: Cpi < CC, quindi il motore non
può avviare a 500 Hz questo carico.
controlli digitali
Esercizio
Con i dati dell’esercizio precedente, calcolare la curva di pull-in.
NB: calcolare la coppia di pull-in per le seguenti frequenze (Hz): 100, 300, 600, 1000, 2000, 4000
α = 3.6 ° = 0.06283
rad
IN = 0.80 A
Curva di
pull-out
R = 4.5 Ω L
= 5.7 H
•
•
CH = 11.4 Ncm
CD = 1.55 Ncm
JM = 15 gcm2
•
SOLUZIONE
f
[ Hz ]
CPO
[ Ncm ]
Δω/Δt
[ rad/s2
]
Ci
[ Ncm ]
Cpi
[ Ncm ]
100
10
628.3
0.23
9.77
300
10
5 655
2.1
7.9
600
9.8
22 619
8.4
1.4
1000
9.5
62 830
23.2
- 13.7
2000
8.2
251 320
4000
5.7
1 005 280
NB: tra 600 Hz e un 1 kHz la coppia
di pull-in si annulla.
controlli digitali
Esercizio
Un carico, con CC = 4 Ncm e JC incognito, è azionato da un motore passo passo. Determinare il JC massimo che il motore
riesce ad avviare alla frequenza di 500 Hz.
Dati motore:
α = 1.8 ° = 0.0314 rad IN
= 0.30 A
R = 24 Ω L
= 30 mH
CH = 13.8 Ncm
CD = 1.75 Ncm
C po  Cc 0.07

 0.00000892 kgm 2 

7850
t
 89.2 gcm 2
JT 
JM = 17 gcm2
SOLUZIONE
Occorre cercare la max coppia d’inerzia, da cui ricavare il max JC. Il
vincolo è imposto dalla relazione: Cpi ≥ CC da cui:
Ci ≤ CPO – CC = 11 – 4 = 7 Ncm = 0.07 Nm
Δω/Δt = 0.0314·5002 = 7850 rad/s2
controlli digitali
Esercizio
Con i dati dell’esercizio precedente e, considerando un JC = 40 gcm2, calcolare la massima velocità con cui è
possibile avviare il carico.
SOLUZIONE
Il calcolo si riduce alla ricerca della frequenza max di alimentazione.
Occorre:
• costruire la curva di pull-in, fino al primo valore negativo
• tracciare una linea orizzontale al livello CC
• leggere in corrispondenza dell’intersezione la frequenza
JT = 17 + 40 = 57 gcm2 = 5.7·10-6 kgm2
f
[ Hz ]
CPO
[ Ncm ]
Δω/Δt
[ rad/s2 ]
Ci
[ Ncm ]
Cpi
[ Ncm ]
100
10
314
0.18
9.82
200
11
1 256
0.72
10.28
500
11
7 850
4.5
6.5
800
10.6
20 096
11
- 0.4
1000
10
31 400
18
-8
controlli digitali
integrato l298
controlli digitali
MOTORE PASSO PASSO CON UN PONTE H L298
si dovrà scaricare la libreri accedendo al link https://github.com/yohendry/arduino_L298N.
Una volta scaricata la libreria in formato zip si dovrà andare al menu Sketch -> #Include Libreria > Aggiungi libreria da file .ZIP e aggiungere la libreria appena scaricata
/*Programma per testare il comando di un motore stepper tramite un L298N Dual H-Bridge Motor Controller
Vengono utilizzati i seguenti pin
Pin +5V -> Pin laterale del potenziometro
Pin GND
-> Pin GND modulo e pin laterale potenz.
Pin Digital 2
-> Collegato al pin IN1
Pin Digital 3
-> Collegato al pin IN2
Pin Digital 4
-> Collegato al pin IN3
Pin Digital 5
-> Collegato al pin IN4
Pin Analog A0
-> Collagato al centrale del potenziometro
*/
#include <Stepper.h>
const int stepsPerRevolution = 200;
/*cambiare questo per adattare il numero di passi per giro; per il vostro motore da calcolare dividendo
360° con il numero di gradi per passo, Inizializzare la libreria passo-passo su pin da 2 a 5*/
Stepper myStepper(stepsPerRevolution, 2,3,4,5);
int stepCount = 0; // numero di passi del motore
void setup() {
// niente da fare all'interno della configurazione
}
void loop() {
// Legge il valore della tensione fornito dal potenziometro:
int sensorReading = analogRead(A0);
// mappa il valore nel range da 0 a 100:
int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
// Imposta la velocità del motore:
if (motorSpeed > 0) {
myStepper.setSpeed(motorSpeed);
// step 1/100 of a revolution:
myStepper.step(stepsPerRevolution/100);
}
}
I
diodi in contro fase servono per proteggere le uscite
dell’integrato L298N da eventuali sovratensioni generate
durante l’alimentazione delle bobine.
void setup()
{
//i pin 2-3-4-5 sono
//configurati come uscite
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
//forza le uscite a livello
logico basso
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
void loop()
{
//FASE 1
//Alimenta solo la prima
bobina
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
delay(10);
//FASE 2
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
delay(10);
//FASE 3
//Alimenta solo
bobina
digitalWrite(2,
digitalWrite(3,
digitalWrite(4,
digitalWrite(5,
delay(10);
//fase 4
//Alimento solo
bobina
digitalWrite(2,
digitalWrite(3,
digitalWrite(4,
digitalWrite(5,
delay(10);
}
la terza
LOW);
HIGH);
LOW);
LOW);
la quarta
LOW);
LOW);
LOW);
HIGH);
controlli digitali
2Un altro modo per pilotare il motore è quello di utilizzare la libreria Stepper.h
#include <Stepper.h> //include la libreria dedicata ai motori
passo passo
#define STEPS 100 // variabile che individua gli step del
motore utilizzato
int val = 0; //setta una variabile per la lettura dell’ingresso
analogico
int previous = 0; //variabile per la lettura precedente
dall'ingresso analogico
Stepper stepper(STEPS, 2, 3, 4, 5); //crea un'instanza della
classe specificando i pin di uscita
void setup()
{
stepper.setSpeed(30); //imposta la velocità del motore a 30
giri al minuto
}
void loop()
{
val = analogRead(0); //legge il valore del potenziometro
stepper.step(val - previous); //sposta il motore di un numero
di passi uguale al cambiamento letto da A0
previous = val; //registra il valore precedente letto dal
sensore
}
#include <Stepper.h>
const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution,
9,10,11,12); // initialize the stepper
library on pins 9 through 12:
void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(60);
// initialize the serial port:
Serial.begin(9600);
}
void loop() {
// step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// step one revolution in the other
direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500); }
SCHEMA DEI COLLEGAMENTI
ESEMPIO: Programma che gestisce i comandi di base di un motore passo passo
Nel programma è presente codice che va ripetuto più volte. Per una scrittura più efficiente è meglio scrivere questa
parte di codice in dei sottoprogrammi (funzioni) da richiamare all’occorrenza. E’ stato quindi creato un nuovo file.c,
denominato LibreriaMPP.c, con all’interno i sottoprogrammi : intestazioneMPP(), opzioni_iniz(); controllo().
Il programma principale (denominato K8055_MotorePP.c), alla luce della scelta precedente, contiene il seguente
codice:
Il file LibreriaMPP.c risulta:
Contenuto della cartella:
5
ARCHITETTURA DEI SISTEMI DI CONTROLLO
GENERALITA
A ANELLO APERTO
A ANELLO CHIUSO
ESEMPIO
SISTEMA DI CONTROLLO
SISTEMA DI CONTROLLOA MICROPROCESSORE
CLASSIFICAZIONE DEI SISTEMI DI CONTROLLO
F.D.T. NEI SISTEMI DI CONTROLLO
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Per sistema di controllo si intende un qualsiasi sistema in grado di fare assumere alla grandezza
d’uscita un prefissato andamento in funzione della grandezza di
ingresso, anche in presenza di
disturbi (dovuti a fattori esterni al sistema) e parametrici (dovuti al deterioramento parziale dei
componenti del sistema).
I sistemi di controllo possono essere distinti in due categorie: sistemi ad anello aperto e sistemi ad
anello chiuso:
AD ANELLO APERTO
Nei sistemi ad anello aperto l’azione di controllo è indipendente dall’uscita; non si opera nessuna
misura della grandezza d’uscita
Pregi: semplice, stabile
Difetti:
• precisione affidata alla accuratezza del modello matematico dei componenti
• vulnerabile ai fenomeni di usura e invecchiamento dei componenti in quanto non più
fedelmente descritti dai modelli matematici memorizzati
.
• vulnerabile in caso di infiltrazione di disturbi.
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Esempio
Consideriamo un sistema di controllo di temperatura ad esempio di un forno a gas
In questo sistema la temperatura, grandezza da controllare, viene
scelta mediante il
posizionamento di una manopola che regola l’erogazione del gas al bruciatore
In questo sistema non si opera nessun controllo sulla grandezza d’uscita.
Il controllo ad anello aperto presenta lo svantaggio che un’eventuale variazione dell’uscita rispetto
al valore desiderato, dovuta ad es. ai disturbi, non viene percepita in ingresso.
Una più efficacia regolazione della temperatura può essere ottenuta misurando continuamente la
temperatura del forno ed intervenendo di conseguenza sulla manopola, aumentando l’afflusso del
gas se la temperatura è al disotto del valore desiderato oppure diminuendolo in caso contrario
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Compensazione in avanti (feed - forward)
In catena aperta è possibile compensare i disturbi a condizione che siano prevedibili e misurabili, è cioè possibile
annullare gli effetti sull’uscita controllata.
In assenza di disturbo e compensazione:
y  A x
In presenza di disturbo, senza compensazione:
y  A x  d
In presenza di disturbo, con compensazione:
y  A  x
ARCHITETTURA DEI SISTEMI DI CONTROLLO
AD ANELLO CHIUSO
Se sostituiamo completamento l’intervento dell’uomo con dispositivi appropriati, il sistema
diventa “sistema di controllo automatico di temperatura ad anello chiuso”
Nei sistemi ad anello chiuso detti anche sistemi a retroazione (feedback) l’azione di controllo dipende
dall’uscita.
L’uscita, viene continuamente <<saggiata>> ed il suo valore è confrontato con una grandezza di
riferimento (Vi), in modo da produrre, ogni qualvolta ci sia una diversità fra l’uscita reale e
quella voluta, un azione correttiva che riporti l’uscita al valore desiderato.
Un sistema di controllo ad anello chiuso può essere schematizzato nel seguente modo:
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Blocco di reazione
E’ costituito da un trasduttore che effettua la conversione della grandezza fisica da controllare (temperatura,
velocità, ecc. ) in un segnale elettrico proporzionale e da un blocco di condizionamento che adatta il segnale
generato dal trasduttore per essere confrontato con il segnale di riferimento Nodo sottrattore
Il nodo sottrattore ha il compito di elaborare il segnale di riferimento e quello di reazione e quindi di generare
il segnale errore Ve che opera l’opportuna azione correttrice.
Nei sistemi continui il dispositivo che effettua il confronto (nodo sottrattore) è realizzato con un amplificatone
in connessione differenziale, nei sistemi di controllo On-Off invece con un comparatore.
Controllore
Il controllore ha lo scopo di manipolare il segnale errore, è presente se occorre migliorare il comportamento
dell’intero sistema in termini di velocità, precisione e stabilità, può essere una rete correttrice oppure un
regolatore industriale.
Blocco di comando attuatore
Il segnale proveniente dal nodo sottrattore opportunamente trattato, comanda l’attuatore (riscaldatore,
motore, ecc) per produrre il segnale d’uscita desiderato. Il blocco di comando attuatore in genere è composto
da un preamplificatore e da un amplificatore di potenza.
Nota: per lo studio dei sistemi di controllo a catena chiusa si fa uno dello schema semplificato.
ARCHITETTURA
ARCHITETTURA DEI
DEI SISTEMI
SISTEMI DI
DI CONTROLLO
CONTROLLO
Difetti:
la modalità con cui si decide l’azione di controllo può dare origine a un sistema instabile per via
dei ritardi con cui i segnali si propagano tra i vari blocchi:
1)il blocco di misura impiega del tempo nell’eseguire la misura della variabile
controllata, il cui valore giunge quindi in ritardo sul nodo di confronto
2)l’azione di controllo, che è decisa sulla base di una situazione che è già vecchia,
impiega del tempo per giungere sul sistema controllato e produrre i suoi effetti.
Questi ritardi, sia nel ramo di retroazione che in quello diretto, sono responsabili della
generazione di azioni di controllo eccessive, cioè di sovracorrezioni che provocano il
pendolamento dell’uscita controllata e, nei casi peggiori, l’instabilità del sistema.
I ritardi possono essere:
•
di trasporto: per trasporto di materia, trasmissione meccanica, pneumatica
•
inerziali: dovuti all’accumulo e rilascio di energia (termica, meccanica, elettrica) negli
accumulatori.
ARCHITETTURA DEI SISTEMI DI CONTROLLO
ESEMPIO DI UN SISTEMA DI CONTROLLO AUTOMATICO DI VELOCITÀ DI UN MOTORE IN CORRENTE CONTINUA
Descrizione dei blocchi:
Il sistema di reazione trasduce la velocità di rotazione in tensione (Vr) Il potenziometro fornisce la
tensione di riferimento (Vi)
Il nodo sottrattore confronta la tensione di riferimento (Vi) con quella
trasduzione e produce il segnale errore. ( Ve = Vi-Vr )
proveniente da sistema di
Il controllore ha lo scopo di manipolare il segnale errore; è presente se occorre migliorare il comportamento
dell’intero sistema in termini di velocità, precisione e stabilità, può essere una rete correttrice oppure un
regolatore industriale(PID)
Il blocco di comando (amplificatore), fornisce al motore il valore opportuno di tensione per mantenere
costante la velocità . (Esso rappresenta l’elemento di regolazione)
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Principio di funzionamento.
Fissato tramite il potenziometro il valore della tensione di riferimento Vi (quindi la velocità di
rotazione del motore), se il motore tende a rallentare, diminuirà la tensione proveniente dal blocco
di reazione (Vr), aumenterà l’errore (Ve) e la tensione ai capi del motore, di conseguenza
aumenterà anche la velocità del motore, compensando così la diminuzione di velocità.
ESEMPIO DI UN SISTEMA DI CONTROLLO AUTOMATICO DI TEMPERATURA DI UN FORNO
Descrizione dei blocchi:
Il blocco di reazione trasduce la temperatura in tensione (Vr). È costituito dall’insieme del
trasduttore (ad es. termocoppia) e dal blocco di condizionamento. Il blocco di condizionamento ha
la funzione di adattare i valori di tensione generati dalla termocoppia per il confronto con la
tensione di riferimento.
Il potenziometro fornisce la tensione di riferimento (Vi) ; rappresenta il valore della
temperatura “ideale” che si vuole mantenere nel forno;
Il nodo sottrattore1 confronta la tensione di riferimento (Vi) con quella proveniente da
sistema di trasduzione e produce il segnale errore. ( Ve = Vi- Vr );
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Il controllore ha lo scopo di manipolare il segnale errore; è presente se
occorre
migliorare
il
comportamento dell’intero sistema in termini di velocità, precisione e stabilità, può essere una rete
correttrice oppure un regolatore industriale (PID)
Il blocco di comando è costituito, ad es. da una elettrovalvola proporzionale, in grado cioè di
modulare l’apertura in funzione della tensione di pilotaggio; in uscita si avrà quindi una portata di
combustibile proporzionale alla tensione stessa.
Il forno” è l’impianto da controllare è costituito dall’insieme del bruciatore e del forno vero e
proprio.
Principio di funzionamento.
Fissato tramite il potenziometro il valore della tensione di riferimento Vi (quindi la temperatura del
forno), se la temperatura del forno diminuisce , diminuirà la tensione proveniente dal blocco di
reazione (Vr), aumenterà l’errore (Ve) e quindi la tensione ai capi dell’elettrovalvola , di conseguenza
aumenterà la quantità di combustibile e quindi aumenterà la temperatura del forno, compensando
così la diminuzione di temperatura.Il nodo sottrattore in genere è realizzato con un amplificatore
operazionale.
ARCHITETTURA DEI SISTEMI DI CONTROLLO
SISTEMA DI CONTROLLO
Il sistema di controllo ON/OFF, (a funzionamento intermittente nel tempo), viene usato quando non
si richiede una marcata precisione; esso è economico e semplice da realizzare.
La struttura base è la seguente:
E’ cosi chiamato perché il dispositivo che effettua il confronto (comparatore) tra la grandezza
d’uscita convertita in tensione (Vr), tramite il blocco di reazione e quella di ingresso (Vi), ha
solamente due stati possibili alto (h) o basso (l).
Caratteristica del comparatore:
se Vr <Vi se Ve = “h”
Ve = “l”
Vr > Vi
-
-
Principio di funzionamento del sistema:
Se l’uscita è minore di quella desiderata (impostata tramite Vi), il comparatore venendosi a trovare
allo stato alto, attiva l’attuatore (ad es. riscaldatore, motore, ecc) per mezzo del blocco di comando.
Non appena l’uscita raggiunge il valore desiderato il comparatore commuta allo stato basso,
disattivando così l’attuatore.
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Possibile andamento dell’uscita
di un sistema di controllo on/off
PROGETTAZIONE DI UN SISTEMA DI CONTROLLO AUTOMATICO DI TEMPERATURA ON/OFF , FACENDO USO
DEL TRASDUTTORE AD590
Specifiche: temperatura di set-point 40°C
Questo sistema consente di controllare la temperatura di un
ambiente, mediante l’attivazione di un riscaldatore quando la
temperatura scende al disotto di una soglia prefissata (40°C).
La temperatura di soglia (40°C) viene scelta impostando Vi tramite
il trimmer R2’’.
Calcolo della tensione Vr per una temperatura di soglia di 40°C.
Il trasduttore AD590 trasduce la temperatura
in corrente,
eroga una corrente 1 A per ogni °K. Di temperatura
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Dimensionamento del generatore di tensione di riferimento
Scegliendo:
R1= 4.7K, R2=1.5K
R2 =1k (trimmer multigiri di regolazione)
Regolando il trimmer multigiri R2
si ottiene Vi = 3,13V
ARCHITETTURA DEI SISTEMI DI CONTROLLO
Dimensionamento del blocco di comando
Il relè per essere eccitato necessita di una corrente Il = 12/300 = 40mA che l’operazionale non è in grado di
fornire.
dati relè:
Va=12V ; R=300
dati BjT 2N2222A: h FE( min) = 75; V CE ( s a t ) =0,3V ; V BE ( s a t ) =0,8V
È pertanto necessario ricorrere ad un BJT in funzionamento ON/OFF.
Calcolo della Ib di saturazione
Per portare in saturazione il BJT è necessaria una Ib>Ic/ h FE( min) ,
sostituendo si ha: Ib > 40 / 75 = 0 , 53 m A. Si può scegliere Ib = 2mA
Dimensionamento della Re
Da notare:
Il diodo inserito in parallelo alla bobina del relè, serve per evitare sovratensioni pericolose sul
collettore del BjT nella commutazione in OFF.
Il diodo inserito sul BJT, serve per proteggere la giunzione BE, quando l’uscita del comparatore è a
livello basso (Ve -12V).
ARCHITETTURA DEI SISTEMI DI CONTROLLO
SISTEMA DI CONTROLLO A MICROPROCESSORE
Il sistema di controllo a microprocessore fa uso di un elaboratore o di un sistema
dedicato; ha un funzionamento che dipende dal programma di gestione.
a microP
Vantaggi:
Il vantaggio più evidente è quello della versatilità, infatti se si vuole variale il valore della
grandezza da controllare, basta modificare il programma di gestione senza
intervenire
sull’hardware .
Il blocco di reazione acquisisce la grandezza da controllare e la converte in formato digitale
L’elaboratore legge il dato digitale, lo confronta con il valore di riferimento precedentemente
impostato e invia il risultato dell’elaborazione al convertitore D/A..
Il convertitore D/A lo converte in segnale analogico. e lo invia al blocco di commando
Il blocco di comando fornisce all’attuatore il segnale opportuno dicontrollo.
Note:
Se la grandezza da controllare varia velocemente prima del convertitore A/D, bisogna inserire il
blocco Sample-Hold, per mantenere stabile il segnale durante il processo di conversione.
Nei sistemi di controllo on/off a microprocessore manca il convertitore D/A.
ARCHITETTURA DEI SISTEMI DI CONTROLLO
CLASSIFICAZIONE DEI SISTEMI DI CONTROLLO
I sistemi di controllo a catena chiusa si distinguono in:
regolatori: quando il valore della grandezza controllata deve essere mantenuta costante;
esempi:
- sistema di controllo di velocità di un motore in c.c. (deve essere mantenuta costante la velocità);
- sistema di controllo della temperatura di un forno (deve essere mantenuta costante la temperatura);
servomeccanismi : quando la grandezza controllata di tipo meccanico (posizione, velocità, ecc.) deve
seguire nel tempo le variazioni della grandezza di riferimento;
esempio
- sistema di trasmissione e di ricezione via satellite: l’antenna di ricezione e
trasmissione “insegue
istante per istante il satellite;
a valore programmato: quando la grandezza controllata varia nel tempo secondo un programma
stabilito;
esempio:
- lavatrice automatica: tutte le grandezze di questo sistema (livello e temperatura dell’acqua, verso e
velocità del cestello hanno nel tempo un andamento che è prefissato mediante il programmatore.
- torni a controllo numerico: le azioni compiute dalla macchina sono
controllate da un programma
gestito da un calcolatore o da un sistema amicroP dedicato.
REQUISITI DI UNSISTEMA DI CONTROLLO
Ad un sistema di controllo è richiesto:
- di risentire del minore modo possibile dei disturbi dovuti a cause esterne;
- di rispondere il più prontamente possibile alle sollecitazioni;
- di fornire una risposta la più precisa possibile
ARCHITETTURA
ARCHITETTURA DEI
DEI SISTEMI
SISTEMI DI
DI CONTROLLO
CONTROLLO
LA FUNZIONE DI TRASFERIMENTO DEI SISTEMI DI CONTROLLO REAZIONATI
In molti casi per agevolare lo studio dei sistemi di
controllo reazionati è preferibile utilizzare lo
schema equivalente con retroazione unitaria.