UPS: guida pratica alla realizzazione.

Tutti noi conosciamo l'indubbia efficacia ed utilità di un UPS. Poter contare sul fatto che i nostri dispositivi vengano alimentati con continuità anche quando la tensione di rete diventa discontinua oppure ha delle pericolose fluttuazioni è semplicemente fondamentale. Ecco, dunque, una guida pratica per realizzarne uno con PIC17C43.

Non è la prima volta che su queste pagine ci occupiamo di UPS; in passato, grazie all'ausilio di un utile video, abbiamo visto come progettare un gruppo di continuità ad onsa sinusoidale.

Questa Reference Design si propone di fornire al lettore una soluzione per realizzare un UPS (al secolo Uninterruptible Power Supply) pronta all'uso gode di tutti i benefici della flessibilità del micro controllore PIC17C43; esso offre una soluzione a basso costo che però non prende le prestazioni meno interessanti, anzi le caratterizza come concorrenziali rispetto a quanto accade con altri microcontrollori.

Il PIC17C43 si dimostra particolarmente adatto a questo tipo di applicazione. Questo perché controlla un inverter la cui uscita, se filtrata, è proprio una forma d'onda sinusoidale AC.

Diversi sono i tipi di intervento che si richiede che un UPS sia in grado di compiere, a seconda, ovviamente, del tipo di problema che la rete elettrica dimostra in quel momento. Infatti, quello che viene definito “fault” può essere rilevato sia internamente sia esternamente dal micro controllore a seconda proprio del tipo di problema. Tensione e corrente di uscita vengono monitorate al fine di effettuare controlli “in tempo reale” per correggere la componente di offset DC e la variazione sul carico.

Ovviamente, la dicitura in tempo reale ha la necessità di essere messa tra virgolette proprio perché sappiamo che è assolutamente impossibile effettuare operazioni di questo tipo realmente in maniera istantanea, dato che quanto meno la forma d'onda presente deve essere comparata o misurata per poter abilitare l'erogazione di potenza proveniente dalla batteria. I tempi tipici di queste commutazioni si attestano intorno ai 10 ms ma, com'è ovvio, possono variare a seconda del tipo di configurazione, del tipo di carico nonché della specifica anomalia sull'alimentazione presente.

Il PIC17C43 utilizza moduli interni per generare segnali di sincronismo alla tensione/fase tra ingresso e uscita.

Caratteristiche

Vediamo, adesso, alcune delle caratteristiche che ci fanno pensare che il PIC17C43 sia effettivamente la scelta giusta per questo tipo di sistema:

  • filtraggio digitale
  • riduzione del numero di componenti della complessità
  • possibilità di integrare periferiche
  • facilità di interfacciamento
  • onda sinusoidale di alta qualità
  • il sistema può essere realizzato in breve tempo
  • flessibilità (dato che gran parte di ciò che questo sistema potrà fare sarà controllabile da codice e quindi potrà essere riprogrammato all'occorrenza)
  • facilità di test

Si intuisce, quindi, per quale motivo la scelta sia quella giusta, nonostante un paio di obiezioni che devono essere fatte per onor di cronaca e completezza. La prima, riguarda il fatto che il tipo di memoria di questo micro-controllore è OTP, cioè One-Time Programmable. Il vantaggio della non volatilità della memoria viene "attenuato" da questo aspetto talvolta quantomeno "scomodo".

Nella sigla questa particolare feature si può identificare con la lettera "C".

Il secondo aspetto da sottolineare riguarda il fatto che la famiglia di microcontrollori oggetto di questo articolo, ovvero la 17, non ha riscosso un successo ma il reference design può risultare piuttosto utile per implementazioni che prevedano esponenti della nuova generazione FLASH, come i PIC18, quelli a 16-bit (PIC24F, PIC24H) e DSPic (dsPIC33) ed a 32-bit.

Ma entriamo nello specifico e vediamo

Com'è fatto il sistema

L'UPS fornisce potenza sulla base del controllo effettuato sull'ingresso, quando l'unità è collegata, oppure utilizza le batterie. La potenza in ingresso viene filtrata (quando questo è possibile) per eliminare il rumore, o componenti di disturbo, di modo comune; sistemi di correzione compensazione vengono utilizzati per eliminare eventuali spike presenti. Successivamente, come si può notare dal diagramma a blocchi riportato di seguito,

si attraversa il blocco PFC, ovvero Power Factor Correction, il quale forza la corrente in ingresso a “diventare” sinusoidale. In questo modo l'utilizzazione della potenza risulta decisamente più efficiente. Il blocco svolge anche la funzione di rettificare la potenza AC in ingresso al fine di produrre tensione DC regolata che viene utilizzata da tutto il resto dei blocchi funzionali del sistema.

Il sistema risulta altamente personalizzabile, tanto che molti potranno modificarne alcune parti del progetto; una prerogativa della famiglia di microcontrollori PIC16/17 è proprio quella di offrire una grande varietà di opzioni di progetto per un UPS. La scelta del microcontrollore può ricadere su diversi integrati, dal PIC16C72 fino al PIC17C756.

Diamo, adesso, dei dettagli circa l'hardware.

Il PlC17C43 rappresenta il cuore di questa configurazione. L'architettura Harvard si dimostra capace di prestazioni di alto livello e garantisce all'utente un canale necessario per proporre in uscita l'onda sinusoidale di cui ha bisogno. Inoltre, il “single-cycle multiply” implica una programmazione più veloce ed una esecuzione più rapida nella risposta ai cambiamenti di forma d'onda. Solo otto dei 10 bit del PWM (Pulse-width modulator) sono richiesti per produrre in uscita la forma d'onda corretta.

Di seguito riportiamo un'immagine del microcontrollore, appartenente alla famiglia PIC17C4X, con annessa piedinatura.

 

Batteria, caricatore e circuito di boost

Per capire meglio come funziona questo sistema c'è da considerare la teoria che sta dietro alla terna composta dalla batteria del sistema, deputato ad accumulare energia, dal caricatore e dal circuito di boost. La batteria viene caricata grazie all'utilizzo della potenza in ingresso fino a quando l'attenzione sul bus supera i 40 V DC. L'ingresso viene spento quando la tensione risulta inferiore a questo valore. La batteria inizia ad erogare potenza al circuito perché viene disabilitata la sezione che è adibita alla sua carica.
A questo punto si utilizza un circuito di boost il cui scopo è quello di convertire, tramite push-pull, i 48 V di tensione continua al valore di 360 V. Il valore prodotto da questa sezione del circuito è leggermente inferiore rispetto a quello del caricatore della batteria; viene realizzato in questo modo per far sì che, sotto condizioni operative normali, la potenza d'ingresso sia proprio la sorgente.
Viene utilizzato, proprio qui, come accennato in precedenza, un controller PWM UC3825 al fine di integrare, per questa sezione del circuito, un drive di protezione che non incida in maniera considerevole nell'economia globale del progetto. L'UC3825 viene ottimizzato per funzionare ad alta frequenza di switch; particolare attenzione viene data alla minimizzazione dei ritardi di propagazione attraverso i compratori ed i circuiti logici. Come accennato in apertura, la velocità di commutazione tra alimentazione normale ed alimentazione batteria deve essere repentina, pena la manifesta inutilità del sistema stesso. Inoltre la circuiteria logica viene dimensionata per massimizzare la banda e lo slew rate dell'amplificatore.
Il progetto di questa sezione viene fatto per l'utilizzo in sistemi sia in current mode sia in voltage mode.
Il circuito di protezione include un limitatore di corrente che fa la comparazione ad un livello di soglia ad 1 V ed un pin di start il cui scopo è, se serve, aumentare il duty cycle.
La configurazione è fully latched e questo garantisce un'alta robustezza al fenomeno del jitter, oltre a garantire che in uscita non troveremo impulsi “multipli”.

Filtraggio in uscita e protezione dell'hardware

L'ingresso all'inverter, dopo opportuni filtraggi sul bus DC, viene portato al circuito H-Bridge il quale, sotto il diretto controllo del PIC17C43, lavora ad una frequenza di 25 MHz. L'output, differenziale, dell'H-Bridge è costituito da una forma d'onda ad impulsi rettangolari a frequenza costante di 25 kHz ed ha un Duty cycle variabili a seconda del valore assoluto dell'output sinusoidale che desideriamo all'uscita.
Come dicevamo in apertura, il filtraggio sull'uscita produce una forma d'onda sinusoidale più “morbida”.
La protezione dell'hardware viene realizzata tramite IGBT (Insulated Gate Bipolar Transistor); questa scelta viene fatta sulla base della bassa impedenza d'uscita dimostrata dai transistor quando essi sono polarizzati.

 

Nel dettaglio, alcune delle specifiche di nostro interesse sono:

  • Input: AC 120/240 VAC ± 10%, 50/60 Hz ± 3Hz
  • Output: 120/240 VAC ± 10%, 50/60 Hz ± 3Hz (selezionabile dall'utente), sinusoidale
  • Rating: 1400 VA
  • Filtraggio in ingresso: EMI/RFI
  • Metal Oxide Varistor (MOV) per la protezione della Spike/Surge

Una delle prerogative dell'UPS è che la correzione del Power Factor viene effettuata da un circuito che alimenta il Chopper, il quale a sua volta alimenta poi l'Inverter. Se l'ingresso dovesse “andare perso” allora il circuito “perde” il flusso di potenza ed è proprio quello di Boost che entra in funzione in maniera del tutto automatica.

Lo schema riportato qui sotto ne dimostra, in linea di principio, il funzionamento.

Qui si osserva che la coppia di transistor è connessa in parallelo allo scopo di fornire grandi valori di correnti d'uscita. Il trasformatore T2 è connesso in modo tale da sentire entrambe le correnti e ciò ha l'effetto di prevenire la saturazione. Viene utilizzato un relè di controllo che effettui lo switch tra 120 e 240V.

Riportiamo, per completezza, il codice sorgente che permette la programmazione:

/*****************************************************************************
* Filename: MAIN.C
******************************************************************************
*
* Author: Dave Karipides
* Company: APS, Inc.
* Date: 3-3-97
* Compiled Using MPLAB-C Rev 1.21
*
******************************************************************************
*
* Include Files:
*
******************************************************************************
*
* Description: The main routine calls all the functions for generating
* an OPEN_LOOP or FEEDBACK sine wave of either 50 or 60 Hz.
*
******************************************************************************
*
* Revisions:
* 3/3/97 Added FEEDBACK LOOP
*
*
******************************************************************************/
/*****************************************************************************
* main()
*
* Description: The main routine initializes the registers and loops
* forever. All control is handled in the TMR0 INT
* routine.
*
*
* Input Variables: NONE
*
* Output Variables: NONE
*
*
******************************************************************************/
//#define OPEN_LOOP
#define FEEDBACK
//#define 50Hz
#define 60Hz
#pragma option v
#include <17c43.h>
#include 
#include 
#ifdef OPEN_LOOP
// This table yields Full VRMS input
unsigned char const pwmtab[32]={0,25,50,74,98,120,142,162,180,197,212,
225,235,244,250,254,255,254,250,244,235,
225,212,197,180,162,142,120,98,74,50,25};
#endif
#ifdef FEEDBACK
// This table yields slightly less than Full VRMS input
unsigned char const pwmtab[32]={0,20,40,60,79,97,114,131,145,159,171,
181,189,197,202,205,206,205,202,197,189,
181,171,159,145,131,114,97,79,60,40,20};
#endif
long read_ad(unsigned char); // Prototype for A/D converter function
unsigned char index; // Index into the sinewave reference table
unsigned char sign; // Flag used to unfold sinewave reference table
long reference; // Value of the sinewave refrence after unfolding
unsigned char reference_lo @ reference;
// V1.21 of Compiler does not type cast unsigned
// char to long so we will write to low byte separately
long out_volt; // Magnitude of the output voltage;
long y; // Variables used in compensation routine
long yold;
long x;
long xold;
long ad_value; // A/D Converter Value
void main(void)
{
CLRWDT();
PORTC = 0; // Zero out portc latches
DDRC = 0x22; // Set up Data direction register for C
DDRB = 0; // Set up Data direction register for B
PR1 = 0xFF; // Setup PR1 register (24.4Khz @ 25Mhz clk)
PW1DCL = 0; // Set low bits of PWM to 0
PW1DCH = 0; // Init PWM duty cycle to 0
T0STA = 0x20; // Configure Timer0 prescaler
INTSTA.T0IE = 1; // Enable Timer 0 interrupt
TCON1.TMR1CS = 0;
TCON1.T16 = 0;
TCON2.TMR1ON = 1; // Start timer 1 (PWM timer)
TCON2.PWM1ON = 1; // Turn on the PWM
CPUSTA.GLINTD = 0; // Unmask the interrupts
index = 0; // Initialize variables
sign = 0;
y = 0;
yold = 0;
x = 0;
xold = 0;
PORTC.0 = 1; // Enable the Inverter
while(1); // Loop forever, execute in INT Routine
}
#ifdef FEEDBACK
__TMR0() // Timer interrupt
{
T0STA.T0CS = 0; // Stop timer
PORTB.7=1;
#ifdef 60Hz
TMR0L=0xA5;
TMR0H=0xF9; // Make Timer0 interrupt at 3.84KHz for 60Hz output
#endif
#ifdef 50Hz
TMR0L=0x5F; // Make Timer0 interrupt at 3.20KHz for 50Hz output
#endif
T0STA.T0CS = 1; // Start timer
CLRWDT();
reference = 0; // Clear Reference Value
reference_lo = pwmtab[index]; // Lookup the value of the sinewave reference
if (!index) // Toggle Sign Every Cycle Through table
sign = ~sign;
++index; // Increment index
if (index == 32) // If end of table, reset counter
index = 0;
if (sign) // If negative going wave
{
reference = ~reference; // V1.21 of Compiler negate (-ref) doesn’t work for
reference = reference + 1; // ref<=0
}
ad_value = read_ad(0);
out_volt = ad_value - 512; // Read output voltage (512 counts=0 volts out)
// Form the expression y = yold + (0.09261 * (x + xold))
// Where yold, xold is the value of y, x from the previous sample
// x is the , formed by the difference between the output
// of the inverter and the reference signal.
x = out_volt - reference;
y = ((x + xold) * 24);
y = y / 256;
y = y + yold;
if (y >= 0)
{
PORTC.2 = 0; // Set positive going cycle
} else
{
PORTC.2 = 1; // Set negative going cycle
y = ~y;
y = y + 1;
}
if (y > 255)
y = 255; // Limit y
PW1DCH = y; // Update duty cycle
xold = x; // Store previous sample’s state
yold = y;
PORTB.7=0;
}
#endif
#ifdef OPEN_LOOP
// The inverter runs in an open loop mode with OPEN_LOOP defined.
__TMR0() // Timer interrupt
{
T0STA.T0CS = 0; // Stop timer
#ifdef 60Hz
TMR0L=0xA5;
TMR0H=0xF9; //Make Timer0 interrupt at 3.84KHz for 60Hz output
#endif
#ifdef 50Hz
TMR0L=0x5F; //Make Timer0 interrupt at 3.20KHz for 50Hz output
TMR0H=0xF8;
#endif
T0STA.T0CS=1; //Start timer
CLRWDT();
PW1DCH = pwmtab[index];
if (!index)
{
PORTC.0 = 0; // Gate Drive off
PORTC.2 = ~PORTC.2; // Flip Pos/Neg bit
PORTC.0 = 1; // Gate Drive on
}
++index;
if (index == 32)
index = 0;
PORTC.3 = ~PORTC.3; // Toggle bit to test freq.
}
#endif
long read_ad(unsigned char channel)
{
long result;
PORTC.6 = 1; // Write bit high
PORTC.7 = 1; // Read bit high
PORTC.4 = 1; // Chip select high
DDRD = 0; // Make PORTD an output
PORTD = 0x04; // Single ended mode signed 10 bit chan 0 Right justified
PORTC.4 = 0; // Select chip
PORTC.6 = 0; // latch command word int A/D
PORTC.6 = 1; // Start conversion
PORTC.4 = 1; // Deselect chip
while (PORTC.5); // Wait for conversion to complete
DDRD = 0xFF; // Make PORTD an input
PORTC.4 = 0; // Select chip
PORTC.7 = 0; // Read high byte
*( ((unsigned char*)&result) + 1) = PORTD;
PORTC.7 = 1;
PORTC.4 = 1;
PORTC.4 = 0;
PORTC.7 = 0; // Read low byte
*( ((unsigned char*)&result) ) = PORTD;
PORTC.7 = 1;
PORTC.4 = 1; // Reset chip select lines
return (result); // Return data
}

Esiste, infine, la possibilità di mettere le mani su una Demo Unit (se ancora disponibile). Di seguito trovate una sua immagine. Questa unità è stata progettata per dimostrare le potenzialità dell'inverter utilizzando il microcontrollore PIC17C43 ed è comunque assemblata solo parzialmente. Pertanto non trovate alcuna circuiteria di backup ma solo pochi pezzi, quelli che vedete esplicitamente indicati, per avere un'idea di massima di come funziona il circuito finale.

Scarica subito una copia gratis

3 Commenti

  1. Avatar photo Giuseppe80 22 Luglio 2012
  2. Avatar photo Piero Boccadoro 22 Luglio 2012
  3. Avatar photo DarioIII 16 Novembre 2022

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend