Ecco una proposta di soluzione per la prova ordinaria del 2016 dell'esame di Sistemi Automatici.
Da questo link si può scaricare l'esercitazione.
Soluzione della Prima Parte.
Da una attenta analisi della prima parte e dalla lettura della seconda parte alla domanda relativa ai quesiti numero 1 e numero 2 collegata alla prima parte si fanno le seguenti ipotesi aggiuntive preliminari:
- Il parcheggio è costituito da un Piano Terra PT costituito da due ingressi INGR1 e INGR2 con semaforo SEM01 e SEM02, fotocellula FC1 e FC2 per ciascun ingresso e due sbarre SB1 e SB3. Sempre nel piano terra ci sono due uscite USC1 e USC2 con fotocellula FC3 e FC4 e relativa sbarra SB2 e SB4. In corrispondenza dei due ingressi ci sono due pannelli replicanti la stessa informazione del tipo: "Posti liberi piano terra: XX; Posti liberi piano sotterraneo: XX". Nello schema vengono indicati con appositi simboli.
- Il parcheggio è costituito inoltre da un piano sotterraneo P-1, che ha 90 posti auto così come il piano terra.
Dovendo "Contare quante automobili sono presenti in ciascun piano" sono presenti altre due fotocellule FC5 e FC6 per contare i cambi di piano.
Si ipotizzano le fotocellule come dei sistemi optoelettronici con uscita digitale compatibile con il microcontrollore scelto. Dal punto di vista del microcontrollore MCU sono ingressi digitali e non sarà per le sei fotocellule necessaria alcuna conversione Analogico Digitale.
Si ipotizza il segnale condizionato dalle fotocellule come un segnale sempre pari a "1" logico che scende allo "0" logico in presenza di automobile e risale ad "1" quando l'automobile è completamente passata. In un sistema automatizzato più realistico il segnale della fotocellula va considerato insieme al peso, per evitare che vengano considerati anche i pedoni.
E' un sistema di acquisizione e distribuzione dati con sei ingressi digitali, le fotocellule:
- FC1: l'automobile entra nel parcheggio da INGR1
- FC2: l'automobile entra nel parcheggio da INGR2
- FC3: l'automobile esce dal parcheggio da USC1
- FC4: l'automobile esce dal parcheggio da USC2
- FC5: l'automobile scende al piano P-1
- FC6: l'automobile sale dal piano P-1
Nella seconda parte della prova d'esame si parla anche della necessità di misurare la forza peso delle automobili all'ingresso con una cella di carico. Occorreranno due celle di carico ai due ingressi. Essendo tale quesito nella seconda parte non verrà dunque considerato nella prima parte. Si consideri solo la necessità di due ingressi analogici che saranno le tensioni fornite dalle due celle di carico opportunamente condizionate. Non verrà ulteriormente considerato ciò nella prima parte. E' ovvio che in un sistema funzionante reale ciò condizionerà l'algoritmo.
Il sistema inoltre ha le seguenti uscite:
- SB1: sbarra presso INGR1
- SB2: sbarra presso USC1
- SB3: sbarra presso INGR2
- SB4 sbarra presso USC2
le varie sbarre possono funzionare "contemporaneamente", ossia per gli essere umani non ci si deve accorgere che una sbarra si sta abbassando per attendere l'apertura di un'altra sbarra.
Per quello che riguarda i due semafori ci saranno tre uscite per ciascun semaforo
SEM01.Rosso | SEM02.Rosso |
SEM01.Giallo | SEM02.Giallo |
SEM01.Verde | SEM02.Verde |
Invece i due display visualizzeranno le stesse informazioni. Una attenta ricerca di mercato porterà alla ricerca e alla soluzione di display indicatori a basso consumo di potenza, elevata visibilità e con pochi fili di comando da e per il microcontrollore. Si suggerisce di approfondire lo standard I2C oppure SPi.
In conclusione si ipotizzano 6 ingressi digitali (le fotocellule optoelettroniche ad infrarosso condizionate), due ingressi analogici, quattro uscite digitali per le sbarre, sei uscite per il semaforo ed almeno quattro uscite digitali per la comunicazione bidirezionali con il display a seconda del display scelto.
E' chiaro che il microcontrollore svolgerà solo la parte di comando. Poi ci saranno contattori, teleruttori, relays che attiveranno la parte di "potenza" per l'accensione dei led dei semafori e dei motori trifase come richiesto nel quesito 2 della seconda parte.
Poi una più attenta valutazione del testo permette di comprendere che saranno necessari anche due sensori di finecorsa per ciascuna sbarra. Tale valutazione la si lascia al lettore e non verrà ulteriormente sviluppata.
Nel seguente disegno si riassume quanto detto finora:
Veniamo ora alla scelta del microcontrollore. Si sceglie di usare il microcontrollore PIC16F887. E' un microcontrollore dotato di un numero adeguato di porte sia analogiche che digitali. Si ritiene a priori la memoria sufficiente. Qualora non lo sia si potranno utilizzare MCU più potenti, mantenendo lo stesso approccio.
Si sceglie di programmarlo in linguaggio C con compilatore XC8 ed ambiente di sviluppo MPLAB X, quello ufficiale di Microchip.
Per le funzioni richieste si effettua il seguente commento:
Contare quante automobili sono presenti in ciascun piano ed inviare queste informazioni ai due pannelli indicatori posti in corrispondenza degli ingressi.
E' possibile conservare tale informazioni in due variabili di tipo intero che chiameremo numeroauto_pt e numeroautopmeno1.
Se la somma numeroauto_pt + numeroautopmeno1 uguaglia in ogni istante 180 le due sbarre di ingresso saranno abbassate e i due semafori di ingresso rossi. Il display indicherà il raggiungimento della capacità con scritte del tipo "Parcheggio Completo"
Allo scopo di "Fornire una statistica relativa alla occupazione media giornaliera dei posti disponibili" è utile disporre di un integrato che faccia da Real Time Clock RTC collegato al microcontrollore. Per esempio si può usare l'integrato DS1307 collegato con protocollo I2C al microcontrollore PIC16F887.
Nell'immagine del produttore si vede che la CPU sarà nel nostro caso il PIC MCU.
In tal modo ogni ora verranno rilevate le medie occupazionali di ciascuno dei 60 minuti che compongono l'ora appena passata. Ogni ora si fa la media dei 60 minuti eppoi si fa alla mezzanotte la media delle 24 ore appena calcolate.
Sono sufficienti due variabili ad array di char[60] per la media ora precedente e char[24] per la media delle medie oraria. Non ha senso conservare questi dati come float come verrà spiegato meglio in seguito.
Il microcontrollore ha una memoria limitata. Usare array di float o di int non permetterebbe neanche la compilazione con MCU scelto.
Ad ogni mezzanotte il microcontrollore calcola la media delle medie giornaliera e lo indicherà per tutta la giornata sui pannelli indicatori.
Risposta alle domande della prima parte:
1. Disegni uno schema a blocchi del sistema di controllo dell’intera apparecchiatura.
Si lascia al lettore il disegno dell'intero schema a blocchi. Si tenga conto delle figure precedenti e del seguente subsistema elettrico:
Nello schema elettrico soprastante al posto del DS1307 si usa X1205.
2. Codifichi l’algoritmo di gestione dei sensori di ingresso, degli attuatori (sbarre mobili e semafori) e dei pannelli indicatori dell’impianto
L'intera codifica del codice necessario non può essere svolta per intero nel poco tempo a disposizione nell'esame. Si riportano qui alcuni passi significativi.
Si consiglia di effettuare una codifica "modulare" e dividere il codice in file separati appartenenti allo stesso Progetto di MPLAB X.
File di Configurazione "config.h":
/*
* File: config.h
* Author: mariani.fausto
*
* Created on 04/22/2017 3:04:02 PM UTC
*/
#ifndef CONFIG_H
#define CONFIG_H
#define _XTAL_FREQ 8000000
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
#include <xc.h>
#endif /* CONFIG_H */
Per la gestione della libreria del pannello indicatore si utilizzeranno le librerie specifiche del pannello indicatore utilizzato. Per dovere di cronaca e per fare le prime prove è possibile farle con un display LCD 16x2 che andrà poi sostituito con il pannello visibile da lontano e dalle sue librerie.
Qui si riporta la configurazione "config_lcd_pin.h":
*
* File: config_lcd_pin.h
* Author: mariani.fausto
*
* Created on 04/22/2017 3:19:11 PM UTC
*/
#ifndef CONFIG_LCD_PIN_H
#define CONFIG_LCD_PIN_H
// this define have to be changed according to the Hw connection to LCD display
#define RS PORTDbits.RD4
#define EN PORTDbits.RD5
#define D4 PORTDbits.RD0
#define D5 PORTDbits.RD1
#define D6 PORTDbits.RD2
#define D7 PORTDbits.RD3
#endif /* CONFIG_LCD_PIN_H */
Una volta sviluppato il prototipo e provata la libreria e l'algoritmo il display LCD va rimosso dalla PORTD ed usato un altro protocollo con meno file e collegato ad esempio a PORTB.RB6 e PORTB.RB7 per il protocollo I2C.
La libreria LCD può essere scaricata ed utilizzata da Internet, per esempio qui.
Infine il programma "main.c":
/*
* File: main.c
*
* Author: mariani.fausto
*
* Created on 04/22/2017 3:04:02 PM UTC
* "Created in MPLAB Xpress"
*
* Original Version:
* http://learn.mikroe.com/ebooks/piccprogramming/chapter/example-12/
*
* and
* https://electrosome.com/lcd-pic-mplab-xc8/
* for LCD library
* and https://youtu.be/4QHmRLJgJ74?list=PL3lfkED2i6JcJH-OETxsI43e8M-7eLeL-
*
* and http://www.cuteminds.com/en/conversione-adc-volt-su-lcd
*/
#include "config.h"
#include "config_lcd_pin.h"
#include "lcd.h"
/*
* Global define pin constants
*/
// as input
#define FC1 PORTBbits.RB0
#define FC2 PORTBbits.RB1
#define FC3 PORTBbits.RB2
#define FC4 PORTBbits.RB3
#define FC5 PORTBbits.RB4
#define FC6 PORTBbits.RB5
// as output
#define SB1 PORTDbits.RD0
#define SB2 PORTDbits.RD1
#define SB3 PORTDbits.RD2
#define SB4 PORTDbits.RD3
#define SEM01_Red PORTDbits.RD4
#define SEM01_Yellow PORTDbits.RD5
#define SEM01_Green PORTDbits.RD6
#define SEM02_Red PORTDbits.RD7
#define SEM02_Yellow PORTEbits.RE0
#define SEM02_Green PORTEbits.RE1
/*
* Global variables
*/
unsigned char numeroauto_pt; // to store the numeber of auto at ground level
unsigned char numeroautopmeno1; // to store the number of auto at -1 level
unsigned char total_auto; // to store the total number of auto inside the parking
void interrupt isr()
{
// interrupt handler
if (INTCONbits.INTF == 1){
if (!FC1) {
numeroauto_pt = numeroauto_pt + 1;
}
else if (!FC2) {
numeroauto_pt = numeroauto_pt + 1;
}
else if(!FC3) {
numeroauto_pt = numeroauto_pt - 1;
}
else if(!FC4) {
numeroauto_pt = numeroauto_pt - 1;
}
else if(!FC5) {
numeroauto_pt = numeroauto_pt - 1;
numeroautopmeno1 = numeroautopmeno1 + 1;
}
else if(!FC6) {
numeroauto_pt = numeroauto_pt + 1;
numeroautopmeno1 = numeroautopmeno1 - 1;
}
}
// this is the routine automatically runs as an Interrupt happen
//reset the interrupt flag
INTCONbits.INTF = 0;
}
void configure_interrupt()
{
INTCONbits.INTF = 0; //reset the external interrupt flag
OPTION_REGbits.INTEDG = 0; //interrupt on the falling edge of RB0/INT bit
INTCONbits.INTE = 1; //enable the external interrupt , enable Interrupt 0 (RB0 as interrupt)
INTCONbits.PEIE = 1; // set the peripheral interrupt enable
// 1 = Enables all unmasked peripheral interrupts
INTCONbits.RBIE = 1; // to enable Interrupt on Port B
IOCBbits.IOCB = 1; // to enable Interrupt-on-change on Port B
// 1 = Enables the PORTB change interrupt
INTCONbits.GIE = 1; //set the Global Interrupt Enable
// 1 = Enables all unmasked interrupts
ei(); // This is like flipping the master switch to enable interrupt
}
// we suppose that Display LCD is connected on PORTD
// we suppose that Temperature sensor like LM35 is connected on RA1/AN1
void main()
{
ANSEL = 0b00000000; //from AN7 to AN0 disabled
ANSELH= 0b00000000; //from AN13 to AN8 disabled
TRISB = 0b11111111; //Configure all PORTB pins as inputs, for photocells
OPTION_REGbits.nRBPU = 0; // to enable Pull-Up resistor on Port B
// - 0 = PORTB pull-ups are enabled by individual PORT latch values
WPUBbits.WPUB = 1; // to enable weak pull-up
TRISD = 0x00; // set PORTD as Output to motor and traffic lights
TRISEbits.TRISE0 = 0; // Configure RE0 as output
TRISEbits.TRISE1 = 0; // Configure RE1 as output
TRISCbits.TRISC3 = 0; // Configure SCL as Input, Setting as input as given in datasheet
TRISCbits.TRISC4 = 0; // Configure SDA as Input, Setting as input as given in datasheet
Lcd_Init(); // This function will initialize the LCD Module
configure_interrupt(); // to configure and enable Interrupt Management
while(1)
{
Lcd_Clear(); // To clear the display.
Lcd_Set_Cursor(1,1); //This function is used to set row and column of the cursor on the LCD screen.
// in this case first row, first column
__delay_ms(1000);
Lcd_Set_Cursor(2,1);
Lcd_Write_String("Stats daily: " );
Lcd_Write_String(average_calculation_on_previous_day());
__delay_ms(1000); // wait one second
}
return;
}
3.Codifichi l’algoritmo che fornisce la statistica relativa alla occupazione media giornaliera dei posti disponibili.
Qui possiamo mettere il file "stats.c" che contiene solo le librerie di funzioni che dovranno essere richiamate da una o più routine di interrupt in accordo con il Real Time Clock RTC.
/* we put here the library for stats calculus*/
/* we suppose that every Minutes the following monodimensional array will be filled
unsigned char Hourly_occupation_by_minute[60]
-------------------------------------------------------------
| 12 | 12 | 15 | 18 | 18 ! ............ | 35 | 32 | 40 | 33 |
-------------------------------------------------------------
MIN |MIN |MIN |MIN |MIN | |MIN |MIN |MIN |MIN |
* 0 * 1 * 2 * 3 * 4 * * 56 * 57 * 58 * 59 *
inside the cell the value is the parking occupation by minute
*
we use another array monodimensiona for the average by hour
*
unsigned char Daily_occupation_by_hour[24]
-------------------------------------------------------------
| 12 | 18 | 14 | ..... | 35 | 34 | 35 | 33 |
-------------------------------------------------------------
Hour | Hour | Hour | Hour | Hour | Hour | Hour |
* 0 * 1 * 2 * 20 * 21 * 22 * 23
* In order to save memory we use int instead of float
* Let's suppose that every Hours from 01:00 AM till 12:00 PM the algorithm will
* determine the mean values of all the cells on the array Hourly_occupation_by_minute
*/
unsigned char Hourly_occupation_by_minute[60];
unsigned char Daily_occupation_by_hour[24];
int average_previous_day;
/* the following function have to be called by an interrupt every minutes*/
int average_calculation_on_previous_hour (int hour)
{
for (int i=0; i<60; i++)
{
Daily_occupation_by_hour[hour] += Hourly_occupation_by_minute[i];
}
Daily_occupation_by_hour[hour] /= 60;
return 1;
}
/* the following function have to be called by an interrupt every hour, at full hour*/
int average_calculation_on_previous_day ()
{
for (int j=0; j<24; j++)
{
average_previous_day += Daily_occupation_by_hour[j];
}
average_previous_day /= 24;
return average_previous_day;
}
L'ultima funzione fornisce la statistica relativa alla occupazione media giornaliera dei posti disponibili. Tale valore è approssimato ad un numero intero anche per risparmiare la preziosa memoria dei MCU. Non ha senso dire agli utenti che nel giorno precedente ci sono state 11,43 automobili. E' molto meglio dire ci sono state in media 11 automobili. Si è usato il tipo unsigned char per ogni cella perché nel MCU scelto non c'era abbastanza memoria per avere dei tipi di dato più "capienti".
4. Descriva una possibile soluzione realizzativa per la visualizzazione del numero di posti liberi di ogni piano.
Questa parte è stata descritta in precedenza. Nella pratica sarà influenzata dalla scelta del pannello indicatore. E dall'esistenza o meno di librerie già pronte o da realizzare ex-novo per visualizzare le scritte sul pannello. Un esempio di Pannello Indicatore si trova qui.
Per la comunicazione in MODBUS RS485 guardare questo http://www.microchip.com/forums/m882533.aspx.
Soluzione della Seconda Parte.
Si devono risolvere solo due quesiti. Per completezza in questo sito riporto la soluzione a tutti e quattro i quesiti, fermo restando che in una prova d'esame, per evitare discussioni e penalizzazioni solo due dei quesiti devono essere risolti dal candidato.
Quesito n°1
Il candidato, con riferimento al tema proposto nella prima parte, descriva il circuito di condizionamento del segnale proveniente da una cella di carico posta in corrispondenza di ogni ingresso al fine di limitare il peso dei veicoli all’interno del parcheggio. Se il peso supera 20 kN, l’accesso deve essere impedito e segnalato.
E' la stessa domanda che era già stata risolta nella soluzione della prova d'esame suppletiva del 2016, nella prima parte e alla terza domanda. Si usa un amplificatore per strumentazione. Questo amplificatore amplifica la tensione differenziale prodotta dalla cella di carico, e quella tensione che corrisponde a quel peso di 20kN viene amplificata e rilevata e segnalata. Occorre fare opportune ipotesi aggiuntive e sulla base di queste scrivere in verifica il progetto del circuito di condizionamento. Chiaramente bisognerà leggere il datasheet della cella di carico e sulla base di questa e del microcontrollore scelto, decidere l'amplificazione del circuito di condizionamento.
Con il suo ingresso analogico si dovrà impedire l'apertura della sbarra agli ingressi e segnalare con il semaforo e con il pannello indicatore che il peso supera il massimo consentito.
Guardare ad esempio il sito: http://it.rs-online.com/web/p/celle-di-carico/8213702/
Ogni singolo candidato ha qui diritto a fare delle ipotesi aggiuntive sulla caratteristica Peso -> Tensione in uscita alla cella di carico, e questa tensione è l'ingresso del circuito di condizionamento.
Quesito n°2
Con riferimento al tema proposto nella prima parte, ipotizzando che il motore elettrico che muove la barriera mobile sia di tipo asincrono trifase, il candidato descriva il tipo di azionamento ritenuto idoneo per questo utilizzo.
Si puo' ipotizzare di indicare qui la parte di potenza di un motore asincrono trifase, azionata con teleruttore contattore comandato a distanza da un PLC oppure da una logica di comando elettromeccanica. Un'ottima descrizione di questo azionamento è il documento del prof. Samuele Mazzolini di Forlì. Come c'è scritto nel suo sito possiamo pensare anche ad un controllo con PLC
La parte di comando (che in caso di PLC può essere costituita dal PLC programmato in linguaggio Ladder) è, ad esempio, in logica elettromeccanica:
Per ulteriori dettagli consultare il sito del prof. Mazzolini e il documento http://www.samuelemazzolini.altervista.org/Teleinversione%20di%20marcia.pdf.
Quesito n°3
Dell’impianto lineare rappresentato in figura, progettare il regolatore industriale di tipo proporzionale Kp in modo che venga garantito un margine di fase di 45° della funzione d’anello. Successivamente, dopo aver individuato il tipo del sistema, calcoli la funzione ad anello chiuso e disegni qualitativamente il diagramma di Bode del modulo.
Dallo schema a blocchi della figura si puo' ricavare la funzione d'anello.
Si calcola la funzione di anello:
$$ W(s) = G(s)H(s) $$
dove
$$ H(s) = H_0 =0,25 $$
e
$$ G(s) = \frac {5000 K_p}{ s (s+380)} $$
pertanto $$ W(s) = G(s)H(s) $$
$$ W(s) = \frac {1250 K_p}{ s (s+380)} $$
Si tratta di un sistema di controllo a sfasamento minimo perché non ci sono né poli né zeri con parte reale positiva. La funzione di anello ha un polo nell'origine p1=0 ed un polo con parte reale negativa p2= - 380.
Di questa funzione si ricava il diagramma di Bode in modulo e fase e si calcola il margine di fase. E' sufficiente il diagramma di Bode "asintotico" e qualitativo.
E' conveniente consultare il sito Wolfram Alpha per vedere il diagramma di Bode. Nel testo si chiede quello asintotico ed approssimato e non quello reale che viene disegnato con Multisim o Wolfram Alpha
Si vede che con Kp minore o uguale a 100 ho ancora un margine di fase $$ m_φ >= 45° $$
Quesito n°4
Il regolatore di un sistema di controllo è di tipo PID. Si illustrino le caratteristiche del regolatore, mettendo in evidenza gli effetti prodotti da una variazione dei coefficienti: Kp, Kd e Ki.
E' un sistema di controllo controreazionato in cui per variare alcune caratteristiche sono stati inseriti dei blocchi proporzionali con coefficiente Kp, dei blocchi derivativi con coefficiente Kd, ed infine del blocchi integrativi con coefficiente Ki.
Tali blocchi modificano la FdT di anello e intervengono soprattutto in alcune pulsazioni, migliorando ad esempio la stabilità complessiva del sistema di controllo, aumentando il margine di fase e di guadagno.
La variazione del segnale di controllo rappresenterebbe la migliore soluzione possibile ma è anche la più difficile da ottenere.
Il regolatore è costituito da tre blocchi collegati in parallelo e i loro contributi si sommano
$$ m(s) = K_P e(s) + \frac {K_i}{ s} e(s) + s K_d e(s) $$
Il regolatore PID con il polo nell'origine dovuto all'azione integrale I modifica il tipo del sistema e migliora l'errore a regime. Contemporaneamente l'introduzione dello zero migliora la stabilità e la rapidità della risposta.
Buono studio!