Salta al contenuto
Note per Studenti Esercizio 20 · regolatore PI in C per il controllo PWM di un motore, valore del duty-cycle e risoluzione (tema d'esame gennaio 2023)

Esercizio 20regolatore PI in C per il controllo PWM di un motore, valore del duty-cycle e risoluzione (tema d'esame gennaio 2023)

Esame
In questa pagina 7

Testo (tema d'esame gennaio 2023, problema P7). È dato il seguente segmento di codice C che realizza un regolatore di tipo PI per il controllo tramite PWM di un motore elettrico a corrente continua:

c
/* ---- Variable x1 ---- */
error1 = x1_ref - x1;                 /* error on x1 */
/* ---- PI regulator ---- */
yp1    = (kp1 * error1) >> 12;        /* proportional correction */
yint1 += ((ki1 * error1) >> 16);      /* integral correction */
DutyCycle = yp1 + yint1;

Sapendo che all'inizio del segmento i valori di x1_ref, x1 e yint1 sono 0x2000\texttt{0x2000}, 0x0900\texttt{0x0900} e 0x0005FF00\texttt{0x0005FF00}, e che i guadagni del regolatore sono rispettivamente kp1=150010kp1=1500_{10} e ki1=3800010ki1=38000_{10} (valori in base 10), determinare: (a) il valore, in formato esadecimale, della variabile uint16_t DutyCycle alla fine del segmento; (b) il valore effettivo del duty-cycle, sapendo che il periodo di conteggio del modulatore è pari a 384001038400_{10} cicli di clock; (c) il numero effettivo di bit che corrisponde alla risoluzione del duty-cycle; Sapendo inoltre che la frequenza di clock del timer è fissata a 2,3042{,}304 GHz: (d) la frequenza di modulazione del sistema; (e) il valore della frequenza di modulazione che porterebbe a 12 bit effettivi la risoluzione del duty-cycle.


Teoria usata: Regolatori PI e PID digitaliIl PI digitale è $y(k)=k_p,e(k)+y_I(k)$ con $y_I(k)=k_I',e(k)+y_I(k-1)$ e $k_I'=k_iT_c$ (con una MAC bastano 3 cicli). Nel PID la derivata si calcola come $\frac{k_d}{T_c}[e(k)-e(k-1)]$ ed è sensibile al rumore: si usa la versione filtrata $y_d(k)=\frac{k_d}{T_c+\tau_L}[e(k)-e(k-1)]+\frac{\tau_L}{T_c+\tau_L}y_d(k-1)$ o una media su più campioni. Con la saturazione dell'attuatore serve l'anti-wind-up: $|y_I|\le L(k)=Y_{max}-|k_pe(k)|$. Il controllo dead-beatcontrollo che porta l'errore a zero in un numero finito di passi (predittivo) azzera l'errore in un numero finito di passi ma è poco usato in industria.Regolatori PI e PID digitali →, Modulazione PWM - duty-cycle, risoluzione e demodulazioneLa PWM trasferisce un segnale modulante $V^$ nella larghezza degli impulsi di un'onda quadra a frequenza fissa: con duty-cycle $d=t_1/T$ e livelli $\pm\frac E2$ la media è $V_{med}=(d-\frac12)E=E,\frac{V^}{V_p}$. L'informazione sta nel valor medio; il resto dello spettro (armoniche della portante) si elimina con un passa-basso (demodulazione). Il modulatore digitale è un timer: contatore + comparatore, $N=f_{clk}/f_{PWM}$ conteggi per periodo, risoluzione $n=\log_2N$ bit (massima frequenza per $n$ bit: $f_{clk}/2^n$), registro di compare = duty-cycle. Servono almeno 8 bit per evitare cicli limite.Modulazione PWM - duty-cycle, risoluzione e demodulazione →, Realizzare un filtro o un regolatore a virgola fissaRealizzare in C un filtro a virgola fissa vuol dire scegliere per ogni dato il formato (coefficienti $<1$ in 0.16 U, coefficienti $>1$ in 1.15, 4.12, 5.11 S...), moltiplicare con aritmetica a 32 bit ($16\times16\to32$) e riportare il prodotto al formato di arrivo con uno shift a destrascorrimento dei bit verso destra: equivale a dividere per una potenza di 2; per sommare due prodotti con scale diverse si fa lo shift prima di sommare. Con $a+b=2^{16}$ il filtro $y=\big(a,y_{k-1}+b,(u\ll4)\big)\gg16$ non va in overflow in un uint32_t. Nel codice il formato di ogni variabile va dichiarato in un commento; la funzione $\sin x\approx x-\frac{x^3}6+\frac{x^5}{120}$ mostra come si approssima una funzione con polinomi a coefficienti in virgola fissa.Realizzare un filtro o un regolatore a virgola fissa →.

Lettura del codice

È un PI discreto (Regolatori PI e PID digitaliIl PI digitale è $y(k)=k_p,e(k)+y_I(k)$ con $y_I(k)=k_I',e(k)+y_I(k-1)$ e $k_I'=k_iT_c$ (con una MAC bastano 3 cicli). Nel PID la derivata si calcola come $\frac{k_d}{T_c}[e(k)-e(k-1)]$ ed è sensibile al rumore: si usa la versione filtrata $y_d(k)=\frac{k_d}{T_c+\tau_L}[e(k)-e(k-1)]+\frac{\tau_L}{T_c+\tau_L}y_d(k-1)$ o una media su più campioni. Con la saturazione dell'attuatore serve l'anti-wind-up: $|y_I|\le L(k)=Y_{max}-|k_pe(k)|$. Il controllo dead-beatcontrollo che porta l'errore a zero in un numero finito di passi (predittivo) azzera l'errore in un numero finito di passi ma è poco usato in industria.Regolatori PI e PID digitali →): y=kp e+yIy=k_p\,e+y_I con yI←yI+kI′ ey_I\leftarrow y_I+k_I'\,e. I guadagni sono scalati in virgola fissa: kp1kp1 con fattore 2122^{12} (shift ≫12\gg12: kp=15004096=0,366k_p=\frac{1500}{4096}=0{,}366) e ki1ki1 con fattore 2162^{16} (shift ≫16\gg16: kI′=3800065536=0,58k_I'=\frac{38000}{65536}=0{,}58). Le variabili intermedie (error1, yp1, yint1) sono int32_t; la somma finale è assegnata a una uint16_t, quindi si tiene la parte bassa a 16 bit.

(a) Calcolo

  1. Errore: error1=0x2000−0x0900=8192−2304=5888=0x1700\texttt{error1}=\texttt{0x2000}-\texttt{0x0900}=8192-2304=5888=\texttt{0x1700}.
  2. Proporzionale: kp1⋅error1=1500⋅5888=8 832 000kp1\cdot error1=1500\cdot5888=8\,832\,000; ≫12\gg12 (divisione per 4096, troncamento): 8832000/4096=2156,25→yp1=2156=0x086C8832000/4096=2156{,}25\to\texttt{yp1}=2156=\texttt{0x086C}.
  3. Integrale: ki1⋅error1=38000⋅5888=223 744 000ki1\cdot error1=38000\cdot5888=223\,744\,000; ≫16\gg16: 223744000/65536=3414,06→3414=0x0D56223744000/65536=3414{,}06\to3414=\texttt{0x0D56}. Quindi yint1=0x0005FF00+0x0D56=392 960+3414=396 374=0x00060C56\texttt{yint1}=\texttt{0x0005FF00}+\texttt{0x0D56}=392\,960+3414=396\,374=\texttt{0x00060C56}.
  4. Duty-cycle: yp1+yint1=2156+396 374=398 530=6⋅65536+5314\texttt{yp1}+\texttt{yint1}=2156+396\,374=398\,530=6\cdot65536+5314 (infatti 6⋅65536=393 2166\cdot65536=393\,216 e 398 530−393 216=5314398\,530-393\,216=5314). Assegnato a una uint16_t si tiene il resto modulo 6553665536: DutyCycle =5314=0x14C2=5314=\texttt{0x14C2}.

(Nota: il termine yint1=0x00060C56\texttt{yint1}=\texttt{0x00060C56} è più grande di 16 bit perché la variabile integrale è a 32 bit; l'assegnazione a 16 bit ne scarta il byte alto. Il testo chiede il valore della variabile a 16 bit: qui si segue questa interpretazione; il dato del testo non precisa se yint1 sia scalato diversamente.)

(b) Duty-cycle effettivo

D=531438400=0,138D=\dfrac{5314}{38400}=\mathbf{0{,}138}, cioè 13,8% (il registro di compare vale 53145314 conteggi su 38400).

(c) Risoluzione

I conteggi per periodo sono N=38400N=38400: bit effettivi log⁡2(38400)=15,23\log_2(38400)=\mathbf{15{,}23} bit. Il passo del duty-cycle è 138400=2,6⋅10−5\frac1{38400}=2{,}6\cdot10^{-5} (0,0026%).

(d) Frequenza di modulazione

fPWM=fclkN=2,304 GHz38400=60 kHzf_{PWM}=\dfrac{f_{clk}}{N}=\dfrac{2{,}304\ \text{GHz}}{38400}=\mathbf{60\ kHz}.

(e) Frequenza per 12 bit effettivi

N=212=4096N=2^{12}=4096: fPWM=2,304 GHz4096=562,5 kHzf_{PWM}=\dfrac{2{,}304\ \text{GHz}}{4096}=\mathbf{562{,}5\ kHz} (con un timer ordinario a 100 MHz gli stessi 12 bit darebbero solo 100 MHz/4096=24,4100\text{ MHz}/4096=24{,}4 kHz: è il clock di qualche GHz dei timer ad alta risoluzione a permettere una portante di oltre 500 kHz con 12 bit).

Errori comuni

  • Fare lo shift prima della moltiplicazione (si perde tutta la precisione di kp1kp1).
  • Dimenticare che l'assegnazione a uint16_t tronca ai 16 bit bassi.
  • Calcolare la frequenza di modulazione con il clock del processore invece che con quello del timer (2,3042{,}304 GHz).
  • Usare i bit effettivi log⁡2N\log_2 N arrotondati: la risoluzione "effettiva" è 15,2315{,}23 bit.

Versione ripasso

Testo. PI in C: error1=x1_ref-x1; yp1=(kp1*error1)>>12; yint1+=(ki1*error1)>>16; DutyCycle=yp1+yint1; con x1_ref=0x2000, x1=0x0900, yint1=0x0005FF00, kp1=1500kp1=1500, ki1=38000ki1=38000; periodo 38400, clock 2,304 GHz (gennaio 2023).

Teoria collegata